|
@@ -22,6 +22,8 @@ package org.maxkey.authn.support.socialsignon;
|
|
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
|
|
|
+import me.zhyd.oauth.request.AuthMaxkeyRequest;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
import org.maxkey.authn.LoginCredential;
|
|
|
import org.maxkey.authn.annotation.CurrentUser;
|
|
|
import org.maxkey.authn.jwt.AuthJwt;
|
|
@@ -30,18 +32,18 @@ import org.maxkey.entity.Message;
|
|
|
import org.maxkey.entity.SocialsAssociate;
|
|
|
import org.maxkey.entity.SocialsProvider;
|
|
|
import org.maxkey.entity.UserInfo;
|
|
|
+import org.maxkey.uuid.UUID;
|
|
|
import org.maxkey.web.WebContext;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.http.ResponseEntity;
|
|
|
import org.springframework.security.core.Authentication;
|
|
|
import org.springframework.stereotype.Controller;
|
|
|
-import org.springframework.web.bind.annotation.PathVariable;
|
|
|
-import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
-import org.springframework.web.bind.annotation.RequestMethod;
|
|
|
-import org.springframework.web.bind.annotation.ResponseBody;
|
|
|
+import org.springframework.web.bind.annotation.*;
|
|
|
import me.zhyd.oauth.request.AuthRequest;
|
|
|
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
/**
|
|
|
* @author Crystal.Sea
|
|
|
*
|
|
@@ -50,7 +52,7 @@ import me.zhyd.oauth.request.AuthRequest;
|
|
|
@RequestMapping(value = "/logon/oauth20")
|
|
|
public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
|
|
|
final static Logger _logger = LoggerFactory.getLogger(SocialSignOnEndpoint.class);
|
|
|
-
|
|
|
+
|
|
|
@RequestMapping(value={"/authorize/{provider}"}, method = RequestMethod.GET)
|
|
|
@ResponseBody
|
|
|
public ResponseEntity<?> authorize( HttpServletRequest request,
|
|
@@ -59,13 +61,13 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
|
|
|
_logger.trace("SocialSignOn provider : " + provider);
|
|
|
String instId = WebContext.getInst().getId();
|
|
|
String originURL =WebContext.getHttpContextPath(request,false);
|
|
|
- String authorizationUrl =
|
|
|
+ String authorizationUrl =
|
|
|
buildAuthRequest(
|
|
|
instId,
|
|
|
provider,
|
|
|
originURL + applicationConfig.getFrontendUri()
|
|
|
).authorize(authTokenService.genRandomJwt());
|
|
|
-
|
|
|
+
|
|
|
_logger.trace("authorize SocialSignOn : " + authorizationUrl);
|
|
|
return new Message<Object>((Object)authorizationUrl).buildResponse();
|
|
|
}
|
|
@@ -85,7 +87,8 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
|
|
|
if(authRequest == null ) {
|
|
|
_logger.error("build authRequest fail .");
|
|
|
}
|
|
|
- String state = authTokenService.genRandomJwt();
|
|
|
+ String state = UUID.generate().toString();
|
|
|
+ //String state = authTokenService.genRandomJwt();
|
|
|
authRequest.authorize(state);
|
|
|
|
|
|
SocialsProvider socialSignOnProvider = socialSignOnProviderService.get(instId,provider);
|
|
@@ -94,10 +97,14 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
|
|
|
scanQrProvider.setRedirectUri(
|
|
|
socialSignOnProviderService.getRedirectUri(
|
|
|
originURL + applicationConfig.getFrontendUri(), provider));
|
|
|
+ //缓存state票据在缓存或者是redis中五分钟过期
|
|
|
+ if (provider.equalsIgnoreCase(AuthMaxkeyRequest.KEY)) {
|
|
|
+ socialSignOnProviderService.setToken(state);
|
|
|
+ }
|
|
|
|
|
|
return new Message<SocialsProvider>(scanQrProvider).buildResponse();
|
|
|
- }
|
|
|
-
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
@RequestMapping(value={"/bind/{provider}"}, method = RequestMethod.GET)
|
|
|
public ResponseEntity<?> bind(@PathVariable String provider,
|
|
@@ -105,7 +112,7 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
|
|
|
HttpServletRequest request) {
|
|
|
//auth call back may exception
|
|
|
try {
|
|
|
- String originURL =WebContext.getHttpContextPath(request,false);
|
|
|
+ String originURL = WebContext.getHttpContextPath(request,false);
|
|
|
SocialsAssociate socialsAssociate =
|
|
|
this.authCallback(userInfo.getInstId(),provider,originURL + applicationConfig.getFrontendUri());
|
|
|
socialsAssociate.setSocialUserInfo(accountJsonString);
|
|
@@ -125,6 +132,8 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
|
|
|
return new Message<AuthJwt>(Message.ERROR).buildResponse();
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
@RequestMapping(value={"/callback/{provider}"}, method = RequestMethod.GET)
|
|
|
public ResponseEntity<?> callback(@PathVariable String provider,
|
|
|
HttpServletRequest request) {
|
|
@@ -134,15 +143,20 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
|
|
|
String instId = WebContext.getInst().getId();
|
|
|
SocialsAssociate socialsAssociate =
|
|
|
this.authCallback(instId,provider,originURL + applicationConfig.getFrontendUri());
|
|
|
+
|
|
|
+ SocialsAssociate socialssssociate1 = this.socialsAssociateService.get(socialsAssociate);
|
|
|
|
|
|
- socialsAssociate=this.socialsAssociateService.get(socialsAssociate);
|
|
|
-
|
|
|
- _logger.debug("Loaded SocialSignOn Socials Associate : "+socialsAssociate);
|
|
|
-
|
|
|
- if(null == socialsAssociate) {
|
|
|
- return new Message<AuthJwt>(Message.ERROR).buildResponse();
|
|
|
- }
|
|
|
+ _logger.debug("Loaded SocialSignOn Socials Associate : "+socialssssociate1);
|
|
|
|
|
|
+ if (null == socialssssociate1) {
|
|
|
+ //如果存在第三方ID并且在数据库无法找到映射关系,则进行绑定逻辑
|
|
|
+ if (StringUtils.isNotEmpty(socialsAssociate.getSocialUserId())) {
|
|
|
+ //返回message为第三方用户标识
|
|
|
+ return new Message<AuthJwt>(Message.PROMPT,socialsAssociate.getSocialUserId()).buildResponse();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ socialsAssociate = socialssssociate1;
|
|
|
_logger.debug("Social Sign On from {} mapping to user {}",
|
|
|
socialsAssociate.getProvider(),socialsAssociate.getUsername());
|
|
|
|
|
@@ -163,4 +177,99 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
|
|
|
return new Message<AuthJwt>(Message.ERROR).buildResponse();
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 提供给第三方应用关联用户接口
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @RequestMapping(value={"/workweixin/qr/auth/login"}, method = {RequestMethod.POST})
|
|
|
+ public ResponseEntity<?> qrAuthLogin(
|
|
|
+ @RequestParam Map<String, String> param,
|
|
|
+ HttpServletRequest request) {
|
|
|
+
|
|
|
+ try {
|
|
|
+ if (null == param){
|
|
|
+ return new Message<AuthJwt>(Message.ERROR).buildResponse();
|
|
|
+ }
|
|
|
+ String token = param.get("token");
|
|
|
+ String username = param.get("username");
|
|
|
+ //判断token是否合法
|
|
|
+ String redisusername = this.socialSignOnProviderService.getToken(token);
|
|
|
+ if (StringUtils.isNotEmpty(redisusername)){
|
|
|
+ //设置token和用户绑定
|
|
|
+ boolean flag = this.socialSignOnProviderService.bindtoken(token,username);
|
|
|
+ if (flag) {
|
|
|
+ return new Message<AuthJwt>().buildResponse();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return new Message<AuthJwt>(Message.WARNING,"Invalid token").buildResponse();
|
|
|
+ }
|
|
|
+ }catch(Exception e) {
|
|
|
+ _logger.error("qrAuthLogin Exception ",e);
|
|
|
+ }
|
|
|
+ return new Message<AuthJwt>(Message.ERROR).buildResponse();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * maxkey 监听扫码回调
|
|
|
+ * @param provider
|
|
|
+ * @param state
|
|
|
+ * @param request
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @RequestMapping(value={"/qrcallback/{provider}/{state}"}, method = RequestMethod.GET)
|
|
|
+ public ResponseEntity<?> qrcallback(@PathVariable String provider,@PathVariable String state,
|
|
|
+ HttpServletRequest request) {
|
|
|
+ try {
|
|
|
+ //判断只有maxkey扫码
|
|
|
+ if (!provider.equalsIgnoreCase(AuthMaxkeyRequest.KEY)) {
|
|
|
+ return new Message<AuthJwt>(Message.ERROR).buildResponse();
|
|
|
+ }
|
|
|
+
|
|
|
+ String loginName = socialSignOnProviderService.getToken(state);
|
|
|
+ if (StringUtils.isEmpty(loginName)) {
|
|
|
+ //二维码过期
|
|
|
+ return new Message<AuthJwt>(Message.PROMPT).buildResponse();
|
|
|
+ }
|
|
|
+ if("-1".equalsIgnoreCase(loginName)){
|
|
|
+ //暂无用户扫码
|
|
|
+ return new Message<AuthJwt>(Message.WARNING).buildResponse();
|
|
|
+ }
|
|
|
+ String instId = WebContext.getInst().getId();
|
|
|
+
|
|
|
+ SocialsAssociate socialsAssociate = new SocialsAssociate();
|
|
|
+ socialsAssociate.setProvider(provider);
|
|
|
+ socialsAssociate.setSocialUserId(loginName);
|
|
|
+ socialsAssociate.setInstId(instId);
|
|
|
+
|
|
|
+
|
|
|
+ socialsAssociate = this.socialsAssociateService.get(socialsAssociate);
|
|
|
+
|
|
|
+ _logger.debug("qrcallback Loaded SocialSignOn Socials Associate : "+socialsAssociate);
|
|
|
+
|
|
|
+ if(null == socialsAssociate) {
|
|
|
+ return new Message<AuthJwt>(Message.ERROR).buildResponse();
|
|
|
+ }
|
|
|
+
|
|
|
+ _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<AuthJwt>(authTokenService.genAuthJwt(authentication)).buildResponse();
|
|
|
+ }catch(Exception e) {
|
|
|
+ _logger.error("qrcallback Exception ",e);
|
|
|
+ return new Message<AuthJwt>(Message.ERROR).buildResponse();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|