diff --git a/pom.xml b/pom.xml
index 6d95c7a..86ae5c3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -65,6 +65,8 @@
4.4
2.11.0
1.1.0
+ 5.8.8
+ 3.5.0
3.0.3
@@ -250,6 +252,16 @@
sharding-jdbc-spring-boot-starter
${shardingsphere.version}
+
+ cn.hutool
+ hutool-all
+ ${hutool.version}
+
+
+ com.google.zxing
+ core
+ ${zxing.version}
+
diff --git a/server/zyjblogs-oauth/pom.xml b/server/zyjblogs-oauth/pom.xml
index f699a8c..f9af723 100644
--- a/server/zyjblogs-oauth/pom.xml
+++ b/server/zyjblogs-oauth/pom.xml
@@ -77,6 +77,15 @@
org.springframework.boot
spring-boot-devtools
+
+ cn.hutool
+ hutool-all
+
+
+ com.google.zxing
+ core
+ 3.3.3
+
diff --git a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/config/security/AuthorizationServerConfiguration.java b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/config/security/AuthorizationServerConfiguration.java
index 2a1a7f5..9641609 100644
--- a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/config/security/AuthorizationServerConfiguration.java
+++ b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/config/security/AuthorizationServerConfiguration.java
@@ -1,20 +1,30 @@
package cn.zyjblogs.config.security;
import cn.zyjblogs.config.security.policy.OauthAuthorizationCodeServices;
+import cn.zyjblogs.config.security.policy.QrCodeTokenGranter;
import cn.zyjblogs.starter.redis.utils.RedisTemplateHandler;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
+import org.springframework.security.oauth2.provider.CompositeTokenGranter;
+import org.springframework.security.oauth2.provider.TokenGranter;
+import org.springframework.security.oauth2.provider.TokenRequest;
+import org.springframework.security.oauth2.provider.client.ClientCredentialsTokenGranter;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
+import org.springframework.security.oauth2.provider.code.AuthorizationCodeTokenGranter;
+import org.springframework.security.oauth2.provider.implicit.ImplicitTokenGranter;
+import org.springframework.security.oauth2.provider.password.ResourceOwnerPasswordTokenGranter;
+import org.springframework.security.oauth2.provider.refresh.RefreshTokenGranter;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
@@ -22,6 +32,7 @@ import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import javax.sql.DataSource;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -81,13 +92,13 @@ public class AuthorizationServerConfiguration extends AuthorizationServerConfigu
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
-
endpoints
//密码模式
- .authenticationManager(authenticationManager)
+// .authenticationManager(authenticationManager)
//授权码模式
- .authorizationCodeServices(authorizationCodeServices(dataSource))
- .tokenServices(tokenServices())
+// .authorizationCodeServices(authorizationCodeServices())
+// .tokenServices(tokenServices())
+ .tokenGranter(tokenGranter(endpoints))
.accessTokenConverter(accessTokenConverter)
//允许表单认证
.allowedTokenEndpointRequestMethods(HttpMethod.POST)
@@ -95,6 +106,39 @@ public class AuthorizationServerConfiguration extends AuthorizationServerConfigu
.exceptionTranslator(oAuthResponseExceptionTranslator);
}
+ private TokenGranter tokenGranter(AuthorizationServerEndpointsConfigurer endpoints) {
+ return new TokenGranter() {
+ private CompositeTokenGranter delegate;
+
+ @Override
+ public OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest) {
+ if (delegate == null) {
+ delegate = getTokenGranters(endpoints);
+ }
+ return delegate.grant(grantType, tokenRequest);
+ }
+ };
+
+ }
+
+ /**
+ * m
+ * 授权模式
+ *
+ * @param endpoints
+ * @return
+ */
+ private CompositeTokenGranter getTokenGranters(AuthorizationServerEndpointsConfigurer endpoints) {
+ List list = new ArrayList<>();
+ list.add(new ResourceOwnerPasswordTokenGranter(authenticationManager, tokenServices(), clientDetails(dataSource), endpoints.getOAuth2RequestFactory()));
+ list.add(new RefreshTokenGranter(tokenServices(), clientDetails(dataSource), endpoints.getOAuth2RequestFactory()));
+ list.add(new AuthorizationCodeTokenGranter(tokenServices(), authorizationCodeServices(), clientDetails(dataSource), endpoints.getOAuth2RequestFactory()));
+ list.add(new ImplicitTokenGranter(tokenServices(), clientDetails(dataSource), endpoints.getOAuth2RequestFactory()));
+ list.add(new ClientCredentialsTokenGranter(tokenServices(), clientDetails(dataSource), endpoints.getOAuth2RequestFactory()));
+ list.add(new QrCodeTokenGranter(tokenServices(), clientDetails(dataSource), endpoints.getOAuth2RequestFactory()));
+ return new CompositeTokenGranter(list);
+ }
+
/**
* 令牌管理服务
*
@@ -128,7 +172,7 @@ public class AuthorizationServerConfiguration extends AuthorizationServerConfigu
}
@Bean
- public AuthorizationCodeServices authorizationCodeServices(DataSource dataSource) {
+ public AuthorizationCodeServices authorizationCodeServices() {
//设置授权码模式的授权码如何存取
return new OauthAuthorizationCodeServices(redisTemplateHandler);
// return new JdbcAuthorizationCodeServices(dataSource);
diff --git a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/config/security/ResourceServerConfig.java b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/config/security/ResourceServerConfig.java
index c7d4985..152a234 100644
--- a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/config/security/ResourceServerConfig.java
+++ b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/config/security/ResourceServerConfig.java
@@ -13,6 +13,8 @@ import org.springframework.security.oauth2.config.annotation.web.configuration.R
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
+import java.util.List;
+
/**
* @author zhuyijun
*/
@@ -48,18 +50,19 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
*/
@Override
public void configure(HttpSecurity http) throws Exception {
+ List allowPaths = whiteListProperties.getAllowPaths();
+ String[] strings = allowPaths.toArray(new String[0]);
http.csrf().disable()
// .disable()
//限制资源服务器作用范围为 "/user/**", "/demo/**"
- .requestMatchers().antMatchers("/v*/**", "/demo/**",
- String.join(",", whiteListProperties.getAllowPaths()))
+ .requestMatchers().antMatchers("/v*/**", "/demo/**").antMatchers(strings)
.and()
.formLogin()
.and()
.authorizeRequests()
- .antMatchers(String.join(",", whiteListProperties.getAllowPaths()))
+ .antMatchers(strings).permitAll()
+ .antMatchers("/v*/user/login", "/v*/auth/refresh/token", "/v*/auth/authorize/code")
.permitAll()
- .antMatchers("/v*/user/login", "/v*/auth/refresh/token", "/v*/auth/authorize/code").permitAll()
.antMatchers("/v*/**").access("#oauth2.hasAnyScope('oauth','all')")
//以下请求必须认证通过
.anyRequest()
diff --git a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/config/security/WebSecurityConfiguration.java b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/config/security/WebSecurityConfiguration.java
index 5809679..879c90b 100644
--- a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/config/security/WebSecurityConfiguration.java
+++ b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/config/security/WebSecurityConfiguration.java
@@ -53,7 +53,11 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
//使HttpSecurity接收以"/login/","/oauth/"开头请求, 配置HttpSecurity不阻止swagger页面
- http.authorizeRequests()
+ http
+// .requestMatchers().antMatchers("/login")
+// .and()
+ .authorizeRequests()
+
// .antMatchers("/webjars/**", "/swagger-ui.html/**", "/swagger-resources/**", "/v2/api-docs/**")
// .permitAll()
// .antMatchers("/user/logout", "/login", "/oauth/**", "/user/login", "/user/refresh/token").permitAll()
diff --git a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/config/security/policy/QrCodeTokenGranter.java b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/config/security/policy/QrCodeTokenGranter.java
new file mode 100644
index 0000000..5ea380b
--- /dev/null
+++ b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/config/security/policy/QrCodeTokenGranter.java
@@ -0,0 +1,26 @@
+package cn.zyjblogs.config.security.policy;
+
+import cn.zyjblogs.server.user.dto.AuthorizationDto;
+import org.springframework.security.oauth2.provider.*;
+import org.springframework.security.oauth2.provider.token.AbstractTokenGranter;
+import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
+
+public class QrCodeTokenGranter extends AbstractTokenGranter {
+ private static final String GRANT_TYPE = "qrcode";
+
+ protected QrCodeTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, String grantType) {
+ super(tokenServices, clientDetailsService, requestFactory, grantType);
+ }
+
+ public QrCodeTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService
+ , OAuth2RequestFactory requestFactory) {
+ this(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
+ }
+
+ @Override
+ protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
+ AuthorizationDto authorization = new AuthorizationDto().createAuthorization();
+ OAuth2Request storedOAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest);
+ return new OAuth2Authentication(storedOAuth2Request, authorization);
+ }
+}
diff --git a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/qrcode/constant/QrCodeEnum.java b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/qrcode/constant/QrCodeEnum.java
new file mode 100644
index 0000000..ed0205b
--- /dev/null
+++ b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/qrcode/constant/QrCodeEnum.java
@@ -0,0 +1,23 @@
+package cn.zyjblogs.server.qrcode.constant;
+
+public enum QrCodeEnum {
+ EXPIRE(0, "过期"),
+ NO_EXPIRE(1, "过期"),
+ NO_EXPIRE_HAS_TOKEN(2, "过期");
+
+ QrCodeEnum(int code, String name) {
+ this.code = code;
+ this.name = name;
+ }
+
+ private int code;
+ private String name;
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/qrcode/controller/QrCodeController.java b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/qrcode/controller/QrCodeController.java
new file mode 100644
index 0000000..859d03b
--- /dev/null
+++ b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/qrcode/controller/QrCodeController.java
@@ -0,0 +1,89 @@
+package cn.zyjblogs.server.qrcode.controller;
+
+import cn.hutool.extra.qrcode.QrCodeUtil;
+import cn.zyjblogs.server.qrcode.dto.QrCode;
+import cn.zyjblogs.server.qrcode.service.QrCodeSerive;
+import cn.zyjblogs.server.user.handler.OauthRquestHander;
+import cn.zyjblogs.server.user.vo.OAuth2AccessTokenVo;
+import cn.zyjblogs.starter.common.entity.response.HttpCode;
+import cn.zyjblogs.starter.common.entity.response.ResponseObject;
+import cn.zyjblogs.starter.common.entity.response.ResponseResult;
+import cn.zyjblogs.starter.common.exception.AuthRuntimeException;
+import cn.zyjblogs.starter.web.apiversion.ApiVersion;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+@ApiVersion(1)
+@RequestMapping("/{v}/qrcode")
+@RestController
+@ResponseBody
+@RequiredArgsConstructor
+public class QrCodeController {
+ private final QrCodeSerive qrCodeSerive;
+ @Value("${zyjblogs.qrcode.redirect_url}")
+ private String qrcodeRedirectUrl;
+
+ //获取登录二维码、放入Token
+ @GetMapping("/get")
+ @ApiVersion(1)
+ public void createCodeImg(HttpServletRequest request, HttpServletResponse response, @RequestParam("appid") String appid) {
+ response.setHeader("Pragma", "No-cache");
+ response.setHeader("Cache-Control", "no-cache");
+ response.setContentType("image/jpeg");
+
+ try {
+ QrCode qrCode = qrCodeSerive.createQrId(appid);
+ Cookie cookie = new Cookie("qrsig", qrCode.getQrsig());
+ response.addCookie(cookie);
+ Map query = new LinkedHashMap<>();
+ query.put("k", qrCode.getQrsig());
+ query.put("f", qrCode.getClienId());
+ //这里没啥操作 就是生成一个UUID插入 数据库的表里
+ QrCodeUtil.generate(OauthRquestHander.append(qrcodeRedirectUrl, query, false), 111, 111, "png", response.getOutputStream());
+
+ } catch (Exception e) {
+ throw new AuthRuntimeException(HttpCode.BAD_REQUEST, e.getMessage());
+ }
+ }
+
+ /**
+ * 判断是否过期
+ *
+ * @param k
+ * @param f
+ * @return
+ */
+ @GetMapping("/isQrExpire")
+ @ApiVersion(1)
+ public Integer isQrExpire(@RequestParam("k") String k, @RequestParam("f") String f) {
+ try {
+ return qrCodeSerive.isQrExpire(k, f);
+ } catch (Exception e) {
+ throw new AuthRuntimeException(HttpCode.BAD_REQUEST, e.getMessage());
+ }
+ }
+
+ /**
+ * 获取登录token
+ *
+ * @param k
+ * @param f
+ * @return
+ */
+ @GetMapping("/login")
+ @ApiVersion(1)
+ public ResponseObject getToken(@RequestParam("k") String k, @RequestParam("f") String f) {
+ try {
+ return ResponseResult.success(qrCodeSerive.getToken(k, f));
+ } catch (Exception e) {
+ throw new AuthRuntimeException(HttpCode.BAD_REQUEST, e.getMessage());
+ }
+ }
+}
diff --git a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/qrcode/dto/QrCode.java b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/qrcode/dto/QrCode.java
new file mode 100644
index 0000000..88ffbb9
--- /dev/null
+++ b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/qrcode/dto/QrCode.java
@@ -0,0 +1,19 @@
+package cn.zyjblogs.server.qrcode.dto;
+
+import cn.zyjblogs.server.user.vo.OAuth2AccessTokenVo;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class QrCode implements Serializable {
+ private String qrsig;
+ private String clienId;
+ private OAuth2AccessTokenVo token;
+}
diff --git a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/qrcode/service/QrCodeSerive.java b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/qrcode/service/QrCodeSerive.java
new file mode 100644
index 0000000..a066ecd
--- /dev/null
+++ b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/qrcode/service/QrCodeSerive.java
@@ -0,0 +1,24 @@
+package cn.zyjblogs.server.qrcode.service;
+
+import cn.zyjblogs.server.qrcode.dto.QrCode;
+import cn.zyjblogs.server.user.vo.OAuth2AccessTokenVo;
+
+public interface QrCodeSerive {
+ /**
+ * 获取验证码id
+ *
+ * @return
+ */
+ QrCode createQrId(String clientId);
+
+ /**
+ * 校验验证码是否过期
+ *
+ * @return
+ */
+ Integer isQrExpire(String qrsig, String clientId);
+
+ OAuth2AccessTokenVo getToken(String qrsig, String clientId);
+
+
+}
diff --git a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/qrcode/service/impl/QrCodeSeriveImpl.java b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/qrcode/service/impl/QrCodeSeriveImpl.java
new file mode 100644
index 0000000..4f40abf
--- /dev/null
+++ b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/qrcode/service/impl/QrCodeSeriveImpl.java
@@ -0,0 +1,66 @@
+package cn.zyjblogs.server.qrcode.service.impl;
+
+import cn.hutool.core.util.IdUtil;
+import cn.zyjblogs.server.qrcode.constant.QrCodeEnum;
+import cn.zyjblogs.server.qrcode.dto.QrCode;
+import cn.zyjblogs.server.qrcode.service.QrCodeSerive;
+import cn.zyjblogs.server.user.vo.OAuth2AccessTokenVo;
+import cn.zyjblogs.starter.common.entity.constant.CommonRedisKeyConstant;
+import cn.zyjblogs.starter.common.entity.response.HttpCode;
+import cn.zyjblogs.starter.common.exception.AuthRuntimeException;
+import cn.zyjblogs.starter.redis.utils.RedisTemplateHandler;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.concurrent.TimeUnit;
+
+@Service
+@RequiredArgsConstructor
+public class QrCodeSeriveImpl implements QrCodeSerive {
+ private final RedisTemplateHandler redisTemplateHandler;
+
+ @Override
+ public QrCode createQrId(String clientId) {
+ if (clientId == null) {
+ throw new AuthRuntimeException(HttpCode.BAD_REQUEST, "appid不能为空");
+ }
+ String id2 = IdUtil.objectId();
+ QrCode qrCode = QrCode.builder()
+ .clienId(clientId)
+ .qrsig(id2)
+ .build();
+ redisTemplateHandler.set(getRediKey(qrCode.getQrsig(), qrCode.getClienId()), null, 3, TimeUnit.MINUTES);
+ return qrCode;
+ }
+
+ public String getRediKey(String qrsig, String clientId) {
+ return CommonRedisKeyConstant.QR_CODE + ":" + clientId + ":" + qrsig;
+ }
+
+ @Override
+ public Integer isQrExpire(String qrsig, String clientId) {
+ String rediKey = getRediKey(qrsig, clientId);
+ Boolean aBoolean = redisTemplateHandler.hasKey(rediKey);
+ if (!aBoolean) {
+ return QrCodeEnum.EXPIRE.getCode();
+ }
+ QrCode qrCode = redisTemplateHandler.get(rediKey);
+ if (qrCode == null) {
+ return QrCodeEnum.EXPIRE.getCode();
+ }
+ if (qrCode.getToken() == null) {
+ return QrCodeEnum.NO_EXPIRE.getCode();
+ }
+ return QrCodeEnum.NO_EXPIRE_HAS_TOKEN.getCode();
+ }
+
+ @Override
+ public OAuth2AccessTokenVo getToken(String qrsig, String clientId) {
+ QrCode qrCode = redisTemplateHandler.get(getRediKey(qrsig, clientId));
+ if (qrCode != null && qrCode.getToken() != null) {
+ return qrCode.getToken();
+ }
+ return null;
+ }
+
+}
diff --git a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/controller/AuthController.java b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/controller/AuthController.java
index a9256f5..779d168 100644
--- a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/controller/AuthController.java
+++ b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/controller/AuthController.java
@@ -5,17 +5,16 @@ import cn.zyjblogs.server.user.dto.AuthorizationCodeDto;
import cn.zyjblogs.server.user.dto.OAuth2AccessTokenDto;
import cn.zyjblogs.server.user.service.AuthService;
import cn.zyjblogs.server.user.vo.OAuth2AccessTokenVo;
+import cn.zyjblogs.starter.common.entity.response.HttpCode;
import cn.zyjblogs.starter.common.entity.response.ResponseObject;
import cn.zyjblogs.starter.common.entity.response.ResponseResult;
+import cn.zyjblogs.starter.common.exception.AuthRuntimeException;
import cn.zyjblogs.starter.web.apiversion.ApiVersion;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
/**
* @author zhuyijun
@@ -55,4 +54,14 @@ public class AuthController {
public ResponseObject getTokenByAuthorizationCode(@RequestBody @Validated AuthCodeDto authCodeDto) {
return ResponseResult.success(authService.getTokenByAuthorizationCode(authCodeDto));
}
+
+ @GetMapping("/qrcode/scan")
+ @ApiVersion(1)
+ public ResponseObject qrcodeScan(@RequestParam("k") String k, @RequestParam("f") String f) {
+ try {
+ return ResponseResult.success(authService.qrcodeScan(k, f));
+ } catch (Exception e) {
+ throw new AuthRuntimeException(HttpCode.BAD_REQUEST, e.getMessage());
+ }
+ }
}
diff --git a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/dto/AuthorizationDto.java b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/dto/AuthorizationDto.java
index 27e53f9..f1f7e92 100644
--- a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/dto/AuthorizationDto.java
+++ b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/dto/AuthorizationDto.java
@@ -1,5 +1,7 @@
package cn.zyjblogs.server.user.dto;
+import cn.zyjblogs.server.user.po.OauthUserDetails;
+import cn.zyjblogs.starter.common.entity.context.BaseContext;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
@@ -98,4 +100,16 @@ public class AuthorizationDto implements Authentication {
public void setAuthenticated(Boolean authenticated) {
this.authenticated = authenticated;
}
+
+ public AuthorizationDto createAuthorization() {
+ AuthorizationDto authorizationDto = new AuthorizationDto();
+ OauthUserDetails oauthUserDetails = new OauthUserDetails();
+ oauthUserDetails.setId(BaseContext.getUserId());
+ oauthUserDetails.setName(BaseContext.getName());
+ oauthUserDetails.setUsername(BaseContext.getUsername());
+ oauthUserDetails.setTenantId(BaseContext.getTenantId());
+ authorizationDto.setPrincipal(oauthUserDetails);
+ authorizationDto.setAuthenticated(true);
+ return authorizationDto;
+ }
}
diff --git a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/handler/OauthRquestHander.java b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/handler/OauthRquestHander.java
index ec816e4..66b6212 100644
--- a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/handler/OauthRquestHander.java
+++ b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/handler/OauthRquestHander.java
@@ -13,13 +13,7 @@ import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
/**
* @author zhuyijun
@@ -141,7 +135,7 @@ public class OauthRquestHander {
return builder.build().toUriString();
}
- private static String append(String base, Map query, boolean fragment) {
+ public static String append(String base, Map query, boolean fragment) {
return append(base, query, (Map) null, fragment);
}
diff --git a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/service/AuthService.java b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/service/AuthService.java
index af49817..47e54ef 100644
--- a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/service/AuthService.java
+++ b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/service/AuthService.java
@@ -39,4 +39,13 @@ public interface AuthService {
* @date 2022/10/15
*/
OAuth2AccessTokenVo getTokenByAuthorizationCode(AuthCodeDto authCodeDto);
+
+ /**
+ * 二维码扫码登录
+ *
+ * @param k
+ * @param f
+ * @return
+ */
+ Boolean qrcodeScan(String k, String f);
}
diff --git a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/service/impl/AuthServiceImpl.java b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/service/impl/AuthServiceImpl.java
index 805bc3d..50f2a01 100644
--- a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/service/impl/AuthServiceImpl.java
+++ b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/service/impl/AuthServiceImpl.java
@@ -1,17 +1,18 @@
package cn.zyjblogs.server.user.service.impl;
+import cn.zyjblogs.server.qrcode.dto.QrCode;
import cn.zyjblogs.server.user.dto.AuthCodeDto;
import cn.zyjblogs.server.user.dto.AuthorizationCodeDto;
import cn.zyjblogs.server.user.dto.AuthorizationDto;
import cn.zyjblogs.server.user.dto.OAuth2AccessTokenDto;
import cn.zyjblogs.server.user.handler.OauthRequestValidator;
import cn.zyjblogs.server.user.handler.OauthRquestHander;
-import cn.zyjblogs.server.user.po.OauthUserDetails;
import cn.zyjblogs.server.user.service.AuthService;
import cn.zyjblogs.server.user.vo.OAuth2AccessTokenVo;
-import cn.zyjblogs.starter.common.entity.context.BaseContext;
+import cn.zyjblogs.starter.common.entity.constant.CommonRedisKeyConstant;
import cn.zyjblogs.starter.common.entity.response.HttpCode;
import cn.zyjblogs.starter.common.exception.AuthRuntimeException;
+import cn.zyjblogs.starter.redis.utils.RedisTemplateHandler;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
@@ -33,6 +34,7 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.*;
+import java.util.concurrent.TimeUnit;
/**
* @author zhuyijun
@@ -46,11 +48,14 @@ public class AuthServiceImpl implements AuthService {
private final PasswordEncoder passwordEncoder;
private RedirectResolver redirectResolver;
private OauthRequestValidator oauthRequestValidator;
+ private RedisTemplateHandler redisTemplateHandler;
private final Object implicitLock = new Object();
public AuthServiceImpl(AuthorizationServerEndpointsConfiguration authorizationServerEndpointsConfiguration,
ClientDetailsService clientDetails,
- AuthorizationCodeServices authorizationCodeServices, PasswordEncoder passwordEncoder, OauthRequestValidator oauthRequestValidator) {
+ AuthorizationCodeServices authorizationCodeServices, PasswordEncoder passwordEncoder,
+ OauthRequestValidator oauthRequestValidator,
+ RedisTemplateHandler redisTemplateHandler) {
this.tokenGranter = authorizationServerEndpointsConfiguration.getEndpointsConfigurer().getTokenGranter();
this.clientDetails = clientDetails;
this.redirectResolver = new DefaultRedirectResolver();
@@ -58,6 +63,7 @@ public class AuthServiceImpl implements AuthService {
this.authorizationCodeServices = authorizationCodeServices;
this.passwordEncoder = passwordEncoder;
this.oauthRequestValidator = oauthRequestValidator;
+ this.redisTemplateHandler = redisTemplateHandler;
}
@Value("${security.oauth2.client.client-id}")
@@ -139,14 +145,7 @@ public class AuthServiceImpl implements AuthService {
if (responseTypes.contains("token")) {
return getImplicitGrantResponse(authorizationRequest);
}
- AuthorizationDto authorizationDto = new AuthorizationDto();
- OauthUserDetails oauthUserDetails = new OauthUserDetails();
- oauthUserDetails.setId(BaseContext.getUserId());
- oauthUserDetails.setName(BaseContext.getName());
- oauthUserDetails.setUsername(BaseContext.getUsername());
- oauthUserDetails.setTenantId(BaseContext.getTenantId());
- authorizationDto.setPrincipal(oauthUserDetails);
- authorizationDto.setAuthenticated(true);
+ AuthorizationDto authorizationDto = new AuthorizationDto().createAuthorization();
try {
return OauthRquestHander.getSuccessfulRedirect(authorizationRequest,
generateCode(authorizationRequest, authorizationDto));
@@ -179,6 +178,32 @@ public class AuthServiceImpl implements AuthService {
}
}
+ @Override
+ public Boolean qrcodeScan(String k, String f) {
+ Boolean aBoolean = redisTemplateHandler.hasKey(CommonRedisKeyConstant.QR_CODE + ":" + f + ":" + k);
+ if (!aBoolean) {
+ return false;
+ }
+ ClientDetails clientDetail = clientDetails.loadClientByClientId(f);
+ if (clientDetail == null) {
+ throw new AuthRuntimeException(HttpCode.BAD_REQUEST, "该appid不存在");
+ }
+ Map parameters = new HashMap<>();
+ parameters.put("grant_type", "qrcode");
+ parameters.put("k", k);
+ parameters.put("f", f);
+ TokenRequest tokenRequest = oAuth2RequestFactory.createTokenRequest(parameters, clientDetail);
+ OAuth2AccessToken token = tokenGranter.grant(tokenRequest.getGrantType(), tokenRequest);
+ OAuth2AccessTokenVo oAuth2AccessTokenVo = OAuth2AccessTokenVo.TransferToken(token);
+ QrCode qrCode = QrCode.builder()
+ .qrsig(k)
+ .clienId(f)
+ .token(oAuth2AccessTokenVo)
+ .build();
+ redisTemplateHandler.set(CommonRedisKeyConstant.QR_CODE + ":" + f + ":" + k, qrCode, 5, TimeUnit.MINUTES);
+ return true;
+ }
+
/**
* 处理
*
diff --git a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/vo/OAuth2AccessTokenVo.java b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/vo/OAuth2AccessTokenVo.java
index d523d04..04dd11a 100644
--- a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/vo/OAuth2AccessTokenVo.java
+++ b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/vo/OAuth2AccessTokenVo.java
@@ -4,7 +4,10 @@ import cn.zyjblogs.starter.common.entity.constant.ContextKeyConstant;
import cn.zyjblogs.starter.common.entity.context.BaseContext;
import cn.zyjblogs.starter.common.entity.dto.ContextDto;
import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
import lombok.Data;
+import lombok.NoArgsConstructor;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import java.io.Serializable;
@@ -17,6 +20,9 @@ import java.util.Set;
* @author zhuyijun
*/
@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
public class OAuth2AccessTokenVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "access token", dataType = "String", example = "abc.efg.hjk")
diff --git a/stater/zyjblogs-common-spring-boot-starter/src/main/java/cn/zyjblogs/starter/common/entity/constant/CommonRedisKeyConstant.java b/stater/zyjblogs-common-spring-boot-starter/src/main/java/cn/zyjblogs/starter/common/entity/constant/CommonRedisKeyConstant.java
index 1ff2d7e..393185f 100644
--- a/stater/zyjblogs-common-spring-boot-starter/src/main/java/cn/zyjblogs/starter/common/entity/constant/CommonRedisKeyConstant.java
+++ b/stater/zyjblogs-common-spring-boot-starter/src/main/java/cn/zyjblogs/starter/common/entity/constant/CommonRedisKeyConstant.java
@@ -18,6 +18,8 @@ public class CommonRedisKeyConstant {
*/
public static final String XSRF_TOKEN = "XSRF_TOKEN:";
+ public static final String QR_CODE = "OAUTH:QR_CODE:";
+
private CommonRedisKeyConstant() {
}
}
\ No newline at end of file
diff --git a/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/resource/ResourceServerConfig.java b/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/resource/ResourceServerConfig.java
index e47b61d..7fef9c9 100644
--- a/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/resource/ResourceServerConfig.java
+++ b/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/resource/ResourceServerConfig.java
@@ -14,6 +14,8 @@ import org.springframework.security.oauth2.config.annotation.web.configuration.R
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
+import java.util.List;
+
/**
* 资源服务
*
@@ -44,10 +46,13 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
+ List allowPaths = whiteListProperties.getAllowPaths();
+ String[] strings = allowPaths.toArray(new String[0]);
String scopeRs = "#oauth2.hasAnyScope(" + '\'' + scope + '\'' + ",'all')";
http.csrf().disable()
.authorizeRequests()
- .antMatchers("/webjars/**", "/swagger-ui.html/**", "/swagger-resources/**", "/v2/api-docs/**", String.join(",", whiteListProperties.getAllowPaths())).permitAll()
+ .antMatchers(strings).permitAll()
+ .antMatchers("/webjars/**", "/swagger-ui.html/**", "/swagger-resources/**", "/v2/api-docs/**").permitAll()
.antMatchers("/**").access(scopeRs)
.anyRequest()
.authenticated()