From 7efa9dd9f524e3229371bf42cd05ef0a100a4953 Mon Sep 17 00:00:00 2001 From: MaxKey Date: Mon, 25 Nov 2024 07:38:47 +0800 Subject: [PATCH] =?UTF-8?q?#238=20=E9=A3=9E=E4=B9=A6=E6=89=AB=E7=A0=81?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../maxkey/authn/jwt/AuthJwtService.java | 2 +- .../interceptor/PermissionInterceptor.java | 2 +- .../AbstractSocialSignOnEndpoint.java | 6 +- .../socialsignon/SocialSignOnEndpoint.java | 144 ++++++++---------- .../service/SocialSignOnProviderService.java | 8 +- .../src/app/core/net/default.interceptor.ts | 4 +- .../app/routes/passport/callback.component.ts | 13 +- .../passport/login/login.component.html | 10 +- .../routes/passport/login/login.component.ts | 75 +++++---- .../app/service/socials-provider.service.ts | 2 +- .../maxkey-web-app/src/index.html | 6 +- .../maxkey/autoconfigure/MaxKeyMvcConfig.java | 1 + 12 files changed, 127 insertions(+), 146 deletions(-) diff --git a/maxkey-authentications/maxkey-authentication-core/src/main/java/org/dromara/maxkey/authn/jwt/AuthJwtService.java b/maxkey-authentications/maxkey-authentication-core/src/main/java/org/dromara/maxkey/authn/jwt/AuthJwtService.java index 4fd592753..93fa2e51c 100644 --- a/maxkey-authentications/maxkey-authentication-core/src/main/java/org/dromara/maxkey/authn/jwt/AuthJwtService.java +++ b/maxkey-authentications/maxkey-authentication-core/src/main/java/org/dromara/maxkey/authn/jwt/AuthJwtService.java @@ -119,7 +119,7 @@ public class AuthJwtService { * @return true or false */ public boolean validateJwtToken(String authToken) { - if(StringUtils.isNotBlank(authToken)) { + if(StringUtils.isNotBlank(authToken) && authToken.length() > 20) { try { JWTClaimsSet claims = resolve(authToken); boolean isExpiration = claims.getExpirationTime().after(DateTime.now().toDate()); diff --git a/maxkey-authentications/maxkey-authentication-core/src/main/java/org/dromara/maxkey/authn/web/interceptor/PermissionInterceptor.java b/maxkey-authentications/maxkey-authentication-core/src/main/java/org/dromara/maxkey/authn/web/interceptor/PermissionInterceptor.java index 99573d18f..1ca630137 100644 --- a/maxkey-authentications/maxkey-authentication-core/src/main/java/org/dromara/maxkey/authn/web/interceptor/PermissionInterceptor.java +++ b/maxkey-authentications/maxkey-authentication-core/src/main/java/org/dromara/maxkey/authn/web/interceptor/PermissionInterceptor.java @@ -64,7 +64,7 @@ public class PermissionInterceptor implements AsyncHandlerInterceptor { SignPrincipal principal = AuthorizationUtils.getPrincipal(); //判断用户是否登录,判断用户是否登录用户 if(principal == null){ - _logger.trace("No Authentication ... forward to /auth/entrypoint , request URI " + request.getRequestURI()); + _logger.debug("No Authentication ... forward to /auth/entrypoint , request URI {}" , request.getRequestURI()); RequestDispatcher dispatcher = request.getRequestDispatcher("/auth/entrypoint"); dispatcher.forward(request, response); return false; diff --git a/maxkey-starter/maxkey-starter-social/src/main/java/org/dromara/maxkey/authn/support/socialsignon/AbstractSocialSignOnEndpoint.java b/maxkey-starter/maxkey-starter-social/src/main/java/org/dromara/maxkey/authn/support/socialsignon/AbstractSocialSignOnEndpoint.java index daac0aa31..3578cb1ee 100644 --- a/maxkey-starter/maxkey-starter-social/src/main/java/org/dromara/maxkey/authn/support/socialsignon/AbstractSocialSignOnEndpoint.java +++ b/maxkey-starter/maxkey-starter-social/src/main/java/org/dromara/maxkey/authn/support/socialsignon/AbstractSocialSignOnEndpoint.java @@ -107,11 +107,11 @@ public class AbstractSocialSignOnEndpoint { } AuthResponse authResponse=authRequest.login(authCallback); - _logger.debug("Response : " + authResponse.getData()); + _logger.debug("Response : {}" , authResponse.getData()); + String socialUserId = socialSignOnProviderService.getAccountId(provider, authResponse); socialsAssociate =new SocialsAssociate(); socialsAssociate.setProvider(provider); - socialsAssociate.setSocialUserId( - socialSignOnProviderService.getAccountId(provider, authResponse)); + socialsAssociate.setSocialUserId(socialUserId); socialsAssociate.setInstId(instId); return socialsAssociate; diff --git a/maxkey-starter/maxkey-starter-social/src/main/java/org/dromara/maxkey/authn/support/socialsignon/SocialSignOnEndpoint.java b/maxkey-starter/maxkey-starter-social/src/main/java/org/dromara/maxkey/authn/support/socialsignon/SocialSignOnEndpoint.java index 04995fc29..0753bf56e 100644 --- a/maxkey-starter/maxkey-starter-social/src/main/java/org/dromara/maxkey/authn/support/socialsignon/SocialSignOnEndpoint.java +++ b/maxkey-starter/maxkey-starter-social/src/main/java/org/dromara/maxkey/authn/support/socialsignon/SocialSignOnEndpoint.java @@ -35,7 +35,6 @@ import org.dromara.maxkey.web.WebContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.Authentication; -import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import jakarta.servlet.http.HttpServletRequest; @@ -47,17 +46,14 @@ import java.util.Map; * @author Crystal.Sea * */ -@Controller +@RestController @RequestMapping(value = "/logon/oauth20") public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{ static final Logger _logger = LoggerFactory.getLogger(SocialSignOnEndpoint.class); - @RequestMapping(value={"/authorize/{provider}"}, method = RequestMethod.GET) - @ResponseBody - public Message authorize( HttpServletRequest request, - @PathVariable("provider") String provider - ) { - _logger.trace("SocialSignOn provider : " + provider); + @GetMapping("/authorize/{provider}") + public Message authorize( HttpServletRequest request,@PathVariable("provider") String provider) { + _logger.trace("SocialSignOn provider : {}" , provider); String instId = WebContext.getInst().getId(); String originURL =WebContext.getContextPath(request,false); String authorizationUrl = @@ -67,14 +63,12 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{ originURL + applicationConfig.getFrontendUri() ).authorize(authTokenService.genRandomJwt()); - _logger.trace("authorize SocialSignOn : " + authorizationUrl); - return new Message((Object)authorizationUrl); + _logger.trace("authorize SocialSignOn : {}" , authorizationUrl); + return new Message(authorizationUrl); } - @RequestMapping(value={"/scanqrcode/{provider}"}, method = RequestMethod.GET) - @ResponseBody - public Message scanQRCode(HttpServletRequest request, - @PathVariable("provider") String provider) { + @GetMapping("/scanqrcode/{provider}") + public Message scanQRCode(HttpServletRequest request,@PathVariable("provider") String provider) { String instId = WebContext.getInst().getId(); String originURL =WebContext.getContextPath(request,false); AuthRequest authRequest = @@ -82,30 +76,30 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{ instId, provider, originURL + applicationConfig.getFrontendUri()); - - if(authRequest == null ) { - _logger.error("build authRequest fail ."); + SocialsProvider scanQrProvider = null; + if(authRequest != null ) { + String state = UUID.generate().toString(); + //String state = authTokenService.genRandomJwt(); + authRequest.authorize(state); + + SocialsProvider socialSignOnProvider = socialSignOnProviderService.get(instId,provider); + scanQrProvider = new SocialsProvider(socialSignOnProvider); + scanQrProvider.setState(state); + scanQrProvider.setRedirectUri( + socialSignOnProviderService.getRedirectUri( + originURL + applicationConfig.getFrontendUri(), provider)); + //缓存state票据在缓存或者是redis中五分钟过期 + if (provider.equalsIgnoreCase(AuthMaxkeyRequest.KEY)) { + socialSignOnProviderService.setToken(state); + } + }else { + _logger.error("build authRequest fail ."); } - String state = UUID.generate().toString(); - //String state = authTokenService.genRandomJwt(); - authRequest.authorize(state); - - SocialsProvider socialSignOnProvider = socialSignOnProviderService.get(instId,provider); - SocialsProvider scanQrProvider = new SocialsProvider(socialSignOnProvider); - scanQrProvider.setState(state); - scanQrProvider.setRedirectUri( - socialSignOnProviderService.getRedirectUri( - originURL + applicationConfig.getFrontendUri(), provider)); - //缓存state票据在缓存或者是redis中五分钟过期 - if (provider.equalsIgnoreCase(AuthMaxkeyRequest.KEY)) { - socialSignOnProviderService.setToken(state); - } - return new Message(scanQrProvider); + return new Message<>(scanQrProvider); } - - @RequestMapping(value={"/bind/{provider}"}, method = RequestMethod.GET) + @GetMapping("/bind/{provider}") public Message bind(@PathVariable("provider") String provider, @CurrentUser UserInfo userInfo, HttpServletRequest request) { @@ -118,24 +112,18 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{ socialsAssociate.setUserId(userInfo.getId()); socialsAssociate.setUsername(userInfo.getUsername()); socialsAssociate.setInstId(userInfo.getInstId()); - //socialsAssociate.setAccessToken(JsonUtils.object2Json(accessToken)); - //socialsAssociate.setExAttribute(JsonUtils.object2Json(accessToken.getResponseObject())); - _logger.debug("Social Bind : "+socialsAssociate); + _logger.debug("Social Bind : {}",socialsAssociate); this.socialsAssociateService.delete(socialsAssociate); this.socialsAssociateService.insert(socialsAssociate); - return new Message(); + return new Message<>(); }catch(Exception e) { _logger.error("callback Exception ",e); } - - return new Message(Message.ERROR); + return new Message<>(Message.ERROR); } - - - @RequestMapping(value={"/callback/{provider}"}, method = RequestMethod.GET) - public Message callback(@PathVariable("provider") String provider, - HttpServletRequest request) { + @GetMapping("/callback/{provider}") + public Message callback(@PathVariable("provider") String provider,HttpServletRequest request) { //auth call back may exception try { String originURL =WebContext.getContextPath(request,false); @@ -145,36 +133,38 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{ SocialsAssociate socialssssociate1 = this.socialsAssociateService.get(socialsAssociate); - _logger.debug("Loaded SocialSignOn Socials Associate : "+socialssssociate1); + _logger.debug("Loaded SocialSignOn Socials Associate : {}",socialssssociate1); if (null == socialssssociate1) { //如果存在第三方ID并且在数据库无法找到映射关系,则进行绑定逻辑 if (StringUtils.isNotEmpty(socialsAssociate.getSocialUserId())) { //返回message为第三方用户标识 - return new Message(Message.PROMPT,socialsAssociate.getSocialUserId()); + return new Message<>(Message.PROMPT,socialsAssociate.getSocialUserId()); } } socialsAssociate = socialssssociate1; - _logger.debug("Social Sign On from {} mapping to user {}", + if(socialsAssociate != null) { + _logger.debug("Social Sign On from {} mapping to user {}", socialsAssociate.getProvider(),socialsAssociate.getUsername()); - - LoginCredential loginCredential =new LoginCredential( - socialsAssociate.getUsername(),"",ConstsLoginType.SOCIALSIGNON); - SocialsProvider socialSignOnProvider = socialSignOnProviderService.get(instId,provider); - loginCredential.setProvider(socialSignOnProvider.getProviderName()); - - Authentication authentication = authenticationProvider.authenticate(loginCredential,true); - //socialsAssociate.setAccessToken(JsonUtils.object2Json(this.accessToken)); - socialsAssociate.setSocialUserInfo(accountJsonString); - //socialsAssociate.setExAttribute(JsonUtils.object2Json(accessToken.getResponseObject())); - - this.socialsAssociateService.update(socialsAssociate); - return new Message(authTokenService.genAuthJwt(authentication)); + LoginCredential loginCredential =new LoginCredential( + socialsAssociate.getUsername(),"",ConstsLoginType.SOCIALSIGNON); + SocialsProvider socialSignOnProvider = socialSignOnProviderService.get(instId,provider); + loginCredential.setProvider(socialSignOnProvider.getProviderName()); + + Authentication authentication = authenticationProvider.authenticate(loginCredential,true); + socialsAssociate.setSocialUserInfo(accountJsonString); + + this.socialsAssociateService.update(socialsAssociate); + return new Message<>(authTokenService.genAuthJwt(authentication)); + }else { + + } }catch(Exception e) { _logger.error("callback Exception ",e); - return new Message(Message.ERROR); + } + return new Message<>(Message.ERROR); } @@ -182,14 +172,14 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{ * 提供给第三方应用关联用户接口 * @return */ - @RequestMapping(value={"/workweixin/qr/auth/login"}, method = {RequestMethod.POST}) + @PostMapping("/workweixin/qr/auth/login") public Message qrAuthLogin( @RequestParam Map param, HttpServletRequest request) { try { if (null == param){ - return new Message(Message.ERROR); + return new Message<>(Message.ERROR); } String token = param.get("token"); String username = param.get("username"); @@ -199,15 +189,15 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{ //设置token和用户绑定 boolean flag = this.socialSignOnProviderService.bindtoken(token,username); if (flag) { - return new Message(); + return new Message<>(); } } else { - return new Message(Message.WARNING,"Invalid token"); + return new Message<>(Message.WARNING,"Invalid token"); } }catch(Exception e) { _logger.error("qrAuthLogin Exception ",e); } - return new Message(Message.ERROR); + return new Message<>(Message.ERROR); } @@ -218,23 +208,23 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{ * @param request * @return */ - @RequestMapping(value={"/qrcallback/{provider}/{state}"}, method = RequestMethod.GET) + @PostMapping("/qrcallback/{provider}/{state}") public Message qrcallback(@PathVariable("provider") String provider,@PathVariable("state") String state, HttpServletRequest request) { try { //判断只有maxkey扫码 if (!provider.equalsIgnoreCase(AuthMaxkeyRequest.KEY)) { - return new Message(Message.ERROR); + return new Message<>(Message.ERROR); } String loginName = socialSignOnProviderService.getToken(state); if (StringUtils.isEmpty(loginName)) { //二维码过期 - return new Message(Message.PROMPT); + return new Message<>(Message.PROMPT); } if("-1".equalsIgnoreCase(loginName)){ //暂无用户扫码 - return new Message(Message.WARNING); + return new Message<>(Message.WARNING); } String instId = WebContext.getInst().getId(); @@ -246,29 +236,25 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{ socialsAssociate = this.socialsAssociateService.get(socialsAssociate); - _logger.debug("qrcallback Loaded SocialSignOn Socials Associate : "+socialsAssociate); + _logger.debug("qrcallback Loaded SocialSignOn Socials Associate : {}",socialsAssociate); if(null == socialsAssociate) { - return new Message(Message.ERROR); + return new Message<>(Message.ERROR); } - _logger.debug("qrcallback Social Sign On from {} mapping to user {}", socialsAssociate.getProvider(),socialsAssociate.getUsername()); - LoginCredential loginCredential =new LoginCredential( socialsAssociate.getUsername(),"",ConstsLoginType.SOCIALSIGNON); SocialsProvider socialSignOnProvider = socialSignOnProviderService.get(instId,provider); loginCredential.setProvider(socialSignOnProvider.getProviderName()); Authentication authentication = authenticationProvider.authenticate(loginCredential,true); - //socialsAssociate.setAccessToken(JsonUtils.object2Json(this.accessToken)); socialsAssociate.setSocialUserInfo(accountJsonString); - //socialsAssociate.setExAttribute(JsonUtils.object2Json(accessToken.getResponseObject())); this.socialsAssociateService.update(socialsAssociate); - return new Message(authTokenService.genAuthJwt(authentication)); + return new Message<>(authTokenService.genAuthJwt(authentication)); }catch(Exception e) { _logger.error("qrcallback Exception ",e); - return new Message(Message.ERROR); + return new Message<>(Message.ERROR); } } } diff --git a/maxkey-starter/maxkey-starter-social/src/main/java/org/dromara/maxkey/authn/support/socialsignon/service/SocialSignOnProviderService.java b/maxkey-starter/maxkey-starter-social/src/main/java/org/dromara/maxkey/authn/support/socialsignon/service/SocialSignOnProviderService.java index 20b4ab67e..91bbfa3fc 100644 --- a/maxkey-starter/maxkey-starter-social/src/main/java/org/dromara/maxkey/authn/support/socialsignon/service/SocialSignOnProviderService.java +++ b/maxkey-starter/maxkey-starter-social/src/main/java/org/dromara/maxkey/authn/support/socialsignon/service/SocialSignOnProviderService.java @@ -43,7 +43,7 @@ import me.zhyd.oauth.model.AuthUser; import me.zhyd.oauth.request.*; public class SocialSignOnProviderService{ - private static Logger _logger = LoggerFactory.getLogger(SocialSignOnProviderService.class); + private static final Logger _logger = LoggerFactory.getLogger(SocialSignOnProviderService.class); private static final String DEFAULT_SELECT_STATEMENT = "select * from mxk_socials_provider where instid = ? and status = 1 order by sortindex"; @@ -52,7 +52,7 @@ public class SocialSignOnProviderService{ .expireAfterWrite(ConstsTimeInterval.ONE_HOUR, TimeUnit.MINUTES) .build(); - HashMapsocialSignOnProviderMaps = new HashMap(); + HashMapsocialSignOnProviderMaps = new HashMap<>(); private final JdbcTemplate jdbcTemplate; @@ -199,9 +199,9 @@ public class SocialSignOnProviderService{ List listSocialsProvider = jdbcTemplate.query( DEFAULT_SELECT_STATEMENT, new SocialsProviderRowMapper(),instId); - _logger.trace("query SocialsProvider " + listSocialsProvider); + _logger.trace("query SocialsProvider {}" , listSocialsProvider); - List socialSignOnProviders = new ArrayList(); + List socialSignOnProviders = new ArrayList<>(); socialsLogin = new SocialsProviderLogin(socialSignOnProviders); for(SocialsProvider socialsProvider : listSocialsProvider){ _logger.debug("Social Provider {} ({})" , diff --git a/maxkey-web-frontend/maxkey-web-app/src/app/core/net/default.interceptor.ts b/maxkey-web-frontend/maxkey-web-app/src/app/core/net/default.interceptor.ts index e05d6df07..b883005a8 100644 --- a/maxkey-web-frontend/maxkey-web-app/src/app/core/net/default.interceptor.ts +++ b/maxkey-web-frontend/maxkey-web-app/src/app/core/net/default.interceptor.ts @@ -107,14 +107,14 @@ export class DefaultInterceptor implements HttpInterceptor { */ private refreshTokenRequest(): Observable { const model = this.tokenSrv.get(); - return this.http.post(`/auth/token/refresh`, null, { refresh_token: model?.['refresh_token'] || '' }); + return this.http.post(`/auth/token/refresh?_allow_anonymous=true`, null, { refresh_token: model?.['refresh_token'] || '' }); } // #region 刷新Token方式一:使用 401 重新刷新 Token private tryRefreshToken(ev: HttpResponseBase, req: HttpRequest, next: HttpHandler): Observable { // 1、若请求为刷新Token请求,表示来自刷新Token可以直接跳转登录页 - if ([`/auth/token/refresh`].some(url => req.url.includes(url))) { + if ([`/auth/token/refresh?_allow_anonymous=true`].some(url => req.url.includes(url))) { this.toLogin(); return throwError(ev); } diff --git a/maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/callback.component.ts b/maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/callback.component.ts index 0f25a3a64..d18a1c2c1 100644 --- a/maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/callback.component.ts +++ b/maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/callback.component.ts @@ -19,9 +19,10 @@ import { ActivatedRoute, Router } from '@angular/router'; import { ReuseTabService } from '@delon/abc/reuse-tab'; import { SettingsService } from '@delon/theme'; import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal'; + import { AuthnService } from '../../service/authn.service'; import { SocialsProviderService } from '../../service/socials-provider.service'; -import {SocialsProviderBindUserComponent} from "./socials-provider-bind-user/socials-provider-bind-user.component"; +import { SocialsProviderBindUserComponent } from './socials-provider-bind-user/socials-provider-bind-user.component'; @Component({ selector: 'app-callback', @@ -52,10 +53,9 @@ export class CallbackComponent implements OnInit { this.reuseTabService.clear(); // 设置用户Token信息 this.authnService.auth(res.data); - } - else if (res.code === 102) { + } else if (res.code === 102) { //绑定用户 - this.openBindUser(res.message) + this.openBindUser(res.message); return; } this.authnService.navigate({}); @@ -70,7 +70,7 @@ export class CallbackComponent implements OnInit { } openBindUser(socialUserId: String) { - console.log("bind user : ",this.provider,socialUserId); + console.log('bind user : ', this.provider, socialUserId); const modal = this.modalService.create({ nzContent: SocialsProviderBindUserComponent, nzViewContainerRef: this.viewContainerRef, @@ -83,10 +83,7 @@ export class CallbackComponent implements OnInit { // Return a result when closed modal.afterClose.subscribe(result => { if (result.refresh) { - } }); - - } } diff --git a/maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/login/login.component.html b/maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/login/login.component.html index 2ae5ef7a7..dad2175d9 100644 --- a/maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/login/login.component.html +++ b/maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/login/login.component.html @@ -14,7 +14,7 @@ {{ 'mxk.login.tab-mobile' | i18n }} -