陶杰
2024-08-22 ee9032d9baf5f33e376d2d2699136e0a7b26bec7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package com.mzl.flower.service.login;
 
import cn.hutool.core.map.MapUtil;
import com.mzl.flower.config.OAuth2Properties;
import com.mzl.flower.config.exception.ValidationException;
import com.mzl.flower.config.security.AuthUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import java.util.Base64;
import java.util.List;
 
 
@Service
@Transactional
@Slf4j
public class LoginService {
 
    private static final String BASIC_ = "Basic ";
    private static final String DEFAULT_CLIENT_TYPE = "default";
 
    @Autowired
    private AuthorizationServerTokenServices authorizationServerTokenServices;
 
    @Autowired
    private ClientDetailsService clientDetailsService;
 
    @Autowired
    private PasswordEncoder passwordEncoder;
 
    @Autowired
    private OAuth2Properties oAuth2Properties;
 
    private String clientAuthorization(String clientType){
        if(StringUtils.isBlank(clientType)){
            clientType = DEFAULT_CLIENT_TYPE;
        }
        List<OAuth2Properties.ClientConfiguration> clients = oAuth2Properties.getClientConfigurations();
        if(clients==null){
            throw new ValidationException("请求头中无client信息");
        }
        String authorization ="";
        for (OAuth2Properties.ClientConfiguration webClientConfiguration :clients){
            if(clientType.equals(webClientConfiguration.getClientType())){
                String clientId = webClientConfiguration.getClientId();
                String secret = webClientConfiguration.getSecret();
                byte[] bytes = (clientId+":"+secret).getBytes();
                authorization = Base64.getEncoder().encodeToString(bytes);
                break;
            }
        }
        return BASIC_+authorization;
    }
 
    public ClientDetails getClient(String clientType){
        String authorization = clientAuthorization(clientType);
        if (StringUtils.isBlank(authorization) || !authorization.startsWith(BASIC_)) {
            throw new ValidationException( "请求头中无client信息");
        }
        String[] tokens = AuthUtils.extractAndDecodeHeader(authorization);
        if (tokens.length != 2) {
            throw new ValidationException( "请求头错误");
        }
        String clientId = tokens[0];
        String clientSecret = tokens[1];
 
        ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);
        if (!passwordEncoder.matches(clientSecret, clientDetails.getClientSecret())) {
            throw new ValidationException("请求头错误");
        }
        return clientDetails;
    }
 
    public OAuth2AccessToken getAccessToken(Authentication authentication,String clientType){
        ClientDetails clientDetails = getClient(clientType);
        TokenRequest tokenRequest = new TokenRequest(MapUtil.newHashMap(), clientDetails.getClientId(), clientDetails.getScope(), "password");
 
        OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);
        OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);
        OAuth2AccessToken token = authorizationServerTokenServices.createAccessToken(oAuth2Authentication);
        return token;
    }
}