mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-04 12:18:42 +08:00 
			
		
		
		
	完成 oauth2 code 授权码模式的实现
This commit is contained in:
		@@ -1,7 +1,15 @@
 | 
			
		||||
### 请求 /system/oauth2/authorize 接口 => 成功
 | 
			
		||||
### 请求 /system/oauth2/authorize + token 接口 => 成功
 | 
			
		||||
POST {{baseUrl}}/system/oauth2/authorize
 | 
			
		||||
Content-Type: application/x-www-form-urlencoded
 | 
			
		||||
Authorization: Bearer {{token}}
 | 
			
		||||
tenant-id: {{adminTenentId}}
 | 
			
		||||
 | 
			
		||||
response_type=token&client_id=default&scope={"user_info": true}&redirect_uri=https://www.iocoder.cn&auto_approve=true
 | 
			
		||||
 | 
			
		||||
### 请求 /system/oauth2/authorize + code 接口 => 成功
 | 
			
		||||
POST {{baseUrl}}/system/oauth2/authorize
 | 
			
		||||
Content-Type: application/x-www-form-urlencoded
 | 
			
		||||
Authorization: Bearer {{token}}
 | 
			
		||||
tenant-id: {{adminTenentId}}
 | 
			
		||||
 | 
			
		||||
response_type=code&client_id=default&scope={"user_info": true}&redirect_uri=https://www.iocoder.cn&auto_approve=true
 | 
			
		||||
 
 | 
			
		||||
@@ -49,7 +49,7 @@ public class OAuth2Controller {
 | 
			
		||||
//    GET  oauth/authorize AuthorizationEndpoint
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private OAuth2GrantService oAuth2GrantService;
 | 
			
		||||
    private OAuth2GrantService oauth2GrantService;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private OAuth2ClientService oauth2ClientService;
 | 
			
		||||
    @Resource
 | 
			
		||||
@@ -121,17 +121,18 @@ public class OAuth2Controller {
 | 
			
		||||
        } else { // 2.2 假设 approved 非 null,说明是场景二
 | 
			
		||||
            // 如果计算后不通过,则跳转一个错误链接
 | 
			
		||||
            if (!oauth2ApproveService.updateAfterApproval(getLoginUserId(), getUserType(), clientId, scopes)) {
 | 
			
		||||
                return success("TODO");
 | 
			
		||||
                return success(OAuth2Utils.buildUnsuccessfulRedirect(redirectUri, responseType, state,
 | 
			
		||||
                        "access_denied", "User denied access"));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 3.1 如果是 code 授权码模式,则发放 code 授权码,并重定向
 | 
			
		||||
        List<String> approveScopes = convertList(scopes.entrySet(), Map.Entry::getKey, Map.Entry::getValue);
 | 
			
		||||
        if (grantTypeEnum == OAuth2GrantTypeEnum.AUTHORIZATION_CODE) {
 | 
			
		||||
            return success(getAuthorizationCodeRedirect());
 | 
			
		||||
            return success(getAuthorizationCodeRedirect(getLoginUserId(), client, approveScopes, redirectUri, state));
 | 
			
		||||
        }
 | 
			
		||||
        // 3.2 如果是 token 则是 implicit 简化模式,则发送 accessToken 访问令牌,并重定向
 | 
			
		||||
        return success(getImplicitGrantRedirect(getLoginUserId(), client, redirectUri, state, approveScopes));
 | 
			
		||||
        return success(getImplicitGrantRedirect(getLoginUserId(), client, approveScopes, redirectUri, state));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static OAuth2GrantTypeEnum getGrantTypeEnum(String responseType) {
 | 
			
		||||
@@ -145,17 +146,23 @@ public class OAuth2Controller {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String getImplicitGrantRedirect(Long userId, OAuth2ClientDO client,
 | 
			
		||||
                                            String redirectUri, String state, List<String> scopes) {
 | 
			
		||||
        OAuth2AccessTokenDO accessTokenDO = oAuth2GrantService.grantImplicit(userId, getUserType(), client.getClientId(), scopes);
 | 
			
		||||
                                            List<String> scopes, String redirectUri, String state) {
 | 
			
		||||
        // 1. 创建 access token 访问令牌
 | 
			
		||||
        OAuth2AccessTokenDO accessTokenDO = oauth2GrantService.grantImplicit(userId, getUserType(), client.getClientId(), scopes);
 | 
			
		||||
        Assert.notNull(accessTokenDO, "访问令牌不能为空"); // 防御性检查
 | 
			
		||||
        // 拼接 URL
 | 
			
		||||
        // 2. 拼接重定向的 URL
 | 
			
		||||
        // noinspection unchecked
 | 
			
		||||
        return OAuth2Utils.buildImplicitRedirectUri(redirectUri, accessTokenDO.getAccessToken(), state, accessTokenDO.getExpiresTime(),
 | 
			
		||||
                scopes, JsonUtils.parseObject(client.getAdditionalInformation(), Map.class));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String getAuthorizationCodeRedirect() {
 | 
			
		||||
        return "";
 | 
			
		||||
    private String getAuthorizationCodeRedirect(Long userId, OAuth2ClientDO client,
 | 
			
		||||
                                                List<String> scopes, String redirectUri, String state) {
 | 
			
		||||
        // 1. 创建 code 授权码
 | 
			
		||||
        String authorizationCode = oauth2GrantService.grantAuthorizationCode(userId,getUserType(), client.getClientId(), scopes,
 | 
			
		||||
                redirectUri, state);
 | 
			
		||||
        // 2. 拼接重定向的 URL
 | 
			
		||||
        return OAuth2Utils.buildAuthorizationCodeRedirectUri(redirectUri, authorizationCode, state);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Integer getUserType() {
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ public class OAuth2ApproveServiceImpl implements OAuth2ApproveService {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean updateAfterApproval(Long userId, Integer userType, String clientId, Map<String, Boolean> scopes) {
 | 
			
		||||
        return true;
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,6 @@ import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -28,7 +27,7 @@ public class OAuth2GrantServiceImpl implements OAuth2GrantService {
 | 
			
		||||
    public String grantAuthorizationCode(Long userId, Integer userType,
 | 
			
		||||
                                         String clientId, List<String> scopes,
 | 
			
		||||
                                         String redirectUri, String state) {
 | 
			
		||||
        return null;
 | 
			
		||||
        return "test";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,25 @@ import java.util.*;
 | 
			
		||||
 */
 | 
			
		||||
public class OAuth2Utils {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 构建授权码模式下,重定向的 URI
 | 
			
		||||
     *
 | 
			
		||||
     * copy from Spring Security OAuth2 的 AuthorizationEndpoint 类的 getSuccessfulRedirect 方法
 | 
			
		||||
     *
 | 
			
		||||
     * @param redirectUri 重定向 URI
 | 
			
		||||
     * @param authorizationCode 授权码
 | 
			
		||||
     * @param state 状态
 | 
			
		||||
     * @return 授权码模式下的重定向 URI
 | 
			
		||||
     */
 | 
			
		||||
    public static String buildAuthorizationCodeRedirectUri(String redirectUri, String authorizationCode, String state) {
 | 
			
		||||
        Map<String, String> query = new LinkedHashMap<>();
 | 
			
		||||
        query.put("code", authorizationCode);
 | 
			
		||||
        if (state != null) {
 | 
			
		||||
            query.put("state", state);
 | 
			
		||||
        }
 | 
			
		||||
        return HttpUtils.append(redirectUri, query, null, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 构建简化模式下,重定向的 URI
 | 
			
		||||
     *
 | 
			
		||||
@@ -53,4 +72,15 @@ public class OAuth2Utils {
 | 
			
		||||
        return HttpUtils.append(redirectUri, vars, keys, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String buildUnsuccessfulRedirect(String redirectUri, String responseType, String state,
 | 
			
		||||
                                                   String error, String description) {
 | 
			
		||||
        Map<String, String> query = new LinkedHashMap<String, String>();
 | 
			
		||||
        query.put("error", error);
 | 
			
		||||
        query.put("error_description", description);
 | 
			
		||||
        if (state != null) {
 | 
			
		||||
            query.put("state", state);
 | 
			
		||||
        }
 | 
			
		||||
        return HttpUtils.append(redirectUri, query, null, !responseType.contains("code"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user