From 66034d26c06cbb7ad37e2e6579299260de9b728e Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 15 May 2022 00:20:52 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=20oauth2=20code=20=E6=8E=88?= =?UTF-8?q?=E6=9D=83=E7=A0=81=E6=A8=A1=E5=BC=8F=E7=9A=84=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/oauth2/OAuth2Controller.http | 10 ++++++- .../admin/oauth2/OAuth2Controller.java | 25 ++++++++++------ .../oauth2/OAuth2ApproveServiceImpl.java | 2 +- .../oauth2/OAuth2GrantServiceImpl.java | 3 +- .../system/util/oauth2/OAuth2Utils.java | 30 +++++++++++++++++++ 5 files changed, 57 insertions(+), 13 deletions(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2Controller.http b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2Controller.http index eece85e5c7..cd4d0f3b25 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2Controller.http +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2Controller.http @@ -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 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2Controller.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2Controller.java index 875ce722c4..e528890a14 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2Controller.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2Controller.java @@ -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 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 scopes) { - OAuth2AccessTokenDO accessTokenDO = oAuth2GrantService.grantImplicit(userId, getUserType(), client.getClientId(), scopes); + List 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 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() { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2ApproveServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2ApproveServiceImpl.java index 76e9af6c3b..18191caac3 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2ApproveServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2ApproveServiceImpl.java @@ -20,7 +20,7 @@ public class OAuth2ApproveServiceImpl implements OAuth2ApproveService { @Override public boolean updateAfterApproval(Long userId, Integer userType, String clientId, Map scopes) { - return true; + return false; } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2GrantServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2GrantServiceImpl.java index 3af885fc90..22dad3c88e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2GrantServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2GrantServiceImpl.java @@ -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 scopes, String redirectUri, String state) { - return null; + return "test"; } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/oauth2/OAuth2Utils.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/oauth2/OAuth2Utils.java index c4321e5360..0cdc88c5f3 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/oauth2/OAuth2Utils.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/oauth2/OAuth2Utils.java @@ -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 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 query = new LinkedHashMap(); + 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")); + } + }