完成 oauth2 code 授权码模式的实现
This commit is contained in:
parent
6ca88277d8
commit
66034d26c0
|
@ -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"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue