完成 oauth2 code 授权码模式的实现

This commit is contained in:
YunaiV 2022-05-15 00:20:52 +08:00
parent 6ca88277d8
commit 66034d26c0
5 changed files with 57 additions and 13 deletions

View File

@ -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

View File

@ -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() {

View File

@ -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;
}
}

View File

@ -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";
}
}

View File

@ -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"));
}
}