diff --git a/sa-token-demo/sa-token-demo-oauth2-client/src/main/java/com/pj/oauth2/SaOAuthClientController.java b/sa-token-demo/sa-token-demo-oauth2-client/src/main/java/com/pj/oauth2/SaOAuthClientController.java index e0cb545e..aed42c2a 100644 --- a/sa-token-demo/sa-token-demo-oauth2-client/src/main/java/com/pj/oauth2/SaOAuthClientController.java +++ b/sa-token-demo/sa-token-demo-oauth2-client/src/main/java/com/pj/oauth2/SaOAuthClientController.java @@ -94,6 +94,7 @@ public class SaOAuthClientController { String str = OkHttps.sync(serverUrl + "/oauth2/token") .addBodyPara("grant_type", "password") .addBodyPara("client_id", clientId) + .addBodyPara("client_secret", clientSecret) .addBodyPara("username", username) .addBodyPara("password", password) .post() diff --git a/sa-token-demo/sa-token-demo-oauth2-client/src/main/resources/templates/index.html b/sa-token-demo/sa-token-demo-oauth2-client/src/main/resources/templates/index.html index ee520f89..9d5b3121 100644 --- a/sa-token-demo/sa-token-demo-oauth2-client/src/main/resources/templates/index.html +++ b/sa-token-demo/sa-token-demo-oauth2-client/src/main/resources/templates/index.html @@ -76,7 +76,7 @@ 账号: 密码: - http://sa-oauth-server.com:8001/oauth2/token?grant_type=password&client_id={value}&username={value}&password={value} + http://sa-oauth-server.com:8001/oauth2/token?grant_type=password&client_id={value}&client_secret={value}&username={value}&password={value}

模式四:凭证式(Client Credentials)

diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/logic/SaOAuth2Handle.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/logic/SaOAuth2Handle.java index ca323660..97413b8b 100644 --- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/logic/SaOAuth2Handle.java +++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/logic/SaOAuth2Handle.java @@ -255,30 +255,31 @@ public class SaOAuth2Handle { String username = req.getParamNotNull(Param.username); String password = req.getParamNotNull(Param.password); String clientId = req.getParamNotNull(Param.client_id); + String clientSecret = req.getParamNotNull(Param.client_secret); String scope = req.getParam(Param.scope, ""); - // 2、校验 ClientScope - SaOAuth2Util.checkContract(clientId, scope); + // 2、校验 ClientScope 和 scope + SaOAuth2Util.checkClientSecretAndScope(clientId, clientSecret, scope); // 3、防止因前端误传token造成逻辑干扰 - SaHolder.getStorage().set(StpUtil.stpLogic.splicingKeyJustCreatedSave(), "no-token"); + // SaHolder.getStorage().set(StpUtil.stpLogic.splicingKeyJustCreatedSave(), "no-token"); - // 4、调用API 开始登录,如果没能成功登录,则直接退出 + // 3、调用API 开始登录,如果没能成功登录,则直接退出 Object retObj = cfg.getDoLoginHandle().apply(username, password); if(StpUtil.isLogin() == false) { return retObj; } - // 5、构建 ra对象 + // 4、构建 ra对象 RequestAuthModel ra = new RequestAuthModel(); ra.clientId = clientId; ra.loginId = StpUtil.getLoginId(); ra.scope = scope; - // 7、生成 Access-Token + // 5、生成 Access-Token AccessTokenModel at = SaOAuth2Util.generateAccessToken(ra, true); - // 8、返回 Access-Token + // 6、返回 Access-Token return SaResult.data(at.toLineMap()); } diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/logic/SaOAuth2Template.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/logic/SaOAuth2Template.java index 16bdcf83..c602a9c0 100644 --- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/logic/SaOAuth2Template.java +++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/logic/SaOAuth2Template.java @@ -396,6 +396,25 @@ public class SaOAuth2Template { SaOAuth2Exception.throwBy(cm.clientSecret == null || cm.clientSecret.equals(clientSecret) == false, "无效client_secret: " + clientSecret); return cm; } + /** + * 校验:clientId 与 clientSecret 是否正确,并且是否签约了指定 scopes + * @param clientId 应用id + * @param clientSecret 秘钥 + * @param scopes 权限(多个用逗号隔开) + * @return SaClientModel对象 + */ + public SaClientModel checkClientSecretAndScope(String clientId, String clientSecret, String scopes) { + // 先校验 clientSecret + SaClientModel cm = checkClientSecret(clientId, clientSecret); + // 再校验 是否签约 + List clientScopeList = SaFoxUtil.convertStringToList(cm.contractScope); + List scopelist = SaFoxUtil.convertStringToList(scopes); + if(clientScopeList.containsAll(scopelist) == false) { + throw new SaOAuth2Exception("请求的Scope暂未签约"); + } + // 返回数据 + return cm; + } /** * 校验:使用 code 获取 token 时提供的参数校验 * @param code 授权码 diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/logic/SaOAuth2Util.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/logic/SaOAuth2Util.java index 25004650..3c4acad4 100644 --- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/logic/SaOAuth2Util.java +++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/logic/SaOAuth2Util.java @@ -207,6 +207,17 @@ public class SaOAuth2Util { return saOAuth2Template.checkClientSecret(clientId, clientSecret); } + /** + * 校验:clientId 与 clientSecret 是否正确,并且是否签约了指定 scopes + * @param clientId 应用id + * @param clientSecret 秘钥 + * @param scopes 权限(多个用逗号隔开) + * @return SaClientModel对象 + */ + public static SaClientModel checkClientSecretAndScope(String clientId, String clientSecret, String scopes) { + return saOAuth2Template.checkClientSecretAndScope(clientId, clientSecret, scopes); + } + /** * 校验:使用 code 获取 token 时提供的参数校验 * @param code 授权码