From e3aa1b0fd03ece475c53556a4c68980afe10296c Mon Sep 17 00:00:00 2001
From: ytChen <1650611030@qq.com>
Date: Mon, 11 Mar 2024 14:36:28 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
hoe-admin/admin-boot/pom.xml | 15 ++
.../admin/boot/config/SaTokenConfigure.java | 35 ++++
hoe-auth/pom.xml | 23 +--
.../comm/exception/AuthExceptionHandler.java | 107 ----------
.../recovery/auth/comm/utils/CommonUtils.java | 36 ----
.../config/AuthorizationServerConfig.java | 138 -------------
.../auth/config/SaTokenConfigure.java | 32 +++
.../auth/config/WebSecurityConfig.java | 85 --------
.../auth/controller/AuthController.java | 46 ++++-
.../client/ClientDetailsServiceImpl.java | 43 ----
.../user/JwtAuthenticationRequest.java | 74 -------
.../security/details/user/SysUserDetails.java | 76 -------
.../user/SysUserDetailsServiceImpl.java | 79 --------
.../auth/service/impl/AuthServiceImpl.java | 7 -
hoe-gateway/pom.xml | 16 ++
.../gateway/config/SaTokenConfigure.java | 42 ++++
.../security/ResourceServerConfig.java | 160 +++++++--------
.../security/ResourceServerManager.java | 189 +++++++-----------
.../security/SecurityGlobalFilter.java | 131 ++++++------
pom.xml | 10 +
20 files changed, 419 insertions(+), 925 deletions(-)
create mode 100644 hoe-admin/admin-boot/src/main/java/com/recovery/admin/boot/config/SaTokenConfigure.java
delete mode 100644 hoe-auth/src/main/java/com/recovery/auth/comm/exception/AuthExceptionHandler.java
delete mode 100644 hoe-auth/src/main/java/com/recovery/auth/comm/utils/CommonUtils.java
delete mode 100644 hoe-auth/src/main/java/com/recovery/auth/config/AuthorizationServerConfig.java
create mode 100644 hoe-auth/src/main/java/com/recovery/auth/config/SaTokenConfigure.java
delete mode 100644 hoe-auth/src/main/java/com/recovery/auth/config/WebSecurityConfig.java
delete mode 100644 hoe-auth/src/main/java/com/recovery/auth/security/details/client/ClientDetailsServiceImpl.java
delete mode 100644 hoe-auth/src/main/java/com/recovery/auth/security/details/user/JwtAuthenticationRequest.java
delete mode 100644 hoe-auth/src/main/java/com/recovery/auth/security/details/user/SysUserDetails.java
delete mode 100644 hoe-auth/src/main/java/com/recovery/auth/security/details/user/SysUserDetailsServiceImpl.java
create mode 100644 hoe-gateway/src/main/java/com/recovery/gateway/config/SaTokenConfigure.java
diff --git a/hoe-admin/admin-boot/pom.xml b/hoe-admin/admin-boot/pom.xml
index d28b45c..7993851 100644
--- a/hoe-admin/admin-boot/pom.xml
+++ b/hoe-admin/admin-boot/pom.xml
@@ -53,6 +53,21 @@
spring-cloud-starter-alibaba-nacos-config
+
+
+ cn.dev33
+ sa-token-spring-boot-starter
+ 1.37.0
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+
com.nimbusds
diff --git a/hoe-admin/admin-boot/src/main/java/com/recovery/admin/boot/config/SaTokenConfigure.java b/hoe-admin/admin-boot/src/main/java/com/recovery/admin/boot/config/SaTokenConfigure.java
new file mode 100644
index 0000000..54853a3
--- /dev/null
+++ b/hoe-admin/admin-boot/src/main/java/com/recovery/admin/boot/config/SaTokenConfigure.java
@@ -0,0 +1,35 @@
+package com.recovery.admin.boot.config;
+
+import cn.dev33.satoken.context.SaHolder;
+import cn.dev33.satoken.filter.SaServletFilter;
+import cn.dev33.satoken.same.SaSameUtil;
+import cn.dev33.satoken.util.SaResult;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * Sa-Token 权限认证 配置类
+ */
+@Configuration
+@Slf4j
+public class SaTokenConfigure implements WebMvcConfigurer {
+ // 注册 Sa-Token 全局过滤器
+ @Bean
+ public SaServletFilter getSaServletFilter() {
+ log.info("校验是否是网关转发请求:====================");
+ return new SaServletFilter()
+ .addInclude("/**")
+ .addExclude("/favicon.ico")
+ .setAuth(obj -> {
+ // 校验 Same-Token 身份凭证 —— 以下两句代码可简化为:SaSameUtil.checkCurrentRequestToken();
+ String token = SaHolder.getRequest().getHeader(SaSameUtil.SAME_TOKEN);
+ SaSameUtil.checkToken(token);
+ })
+ .setError(e -> {
+ return SaResult.error(e.getMessage());
+ })
+ ;
+ }
+}
\ No newline at end of file
diff --git a/hoe-auth/pom.xml b/hoe-auth/pom.xml
index 25fd989..3746785 100644
--- a/hoe-auth/pom.xml
+++ b/hoe-auth/pom.xml
@@ -35,6 +35,15 @@
spring-cloud-starter-alibaba-nacos-discovery
+
+
+
+ cn.dev33
+ sa-token-spring-boot-starter
+ 1.37.0
+
+
+
org.springframework.cloud
spring-cloud-starter-loadbalancer
@@ -46,25 +55,13 @@
spring-cloud-starter-alibaba-nacos-config
-
- org.springframework.security
- spring-security-oauth2-jose
-
+
com.recovery
common-web
${hoe-version}
-
-
- org.springframework.security.oauth.boot
- spring-security-oauth2-autoconfigure
-
-
- org.springframework.security
- spring-security-oauth2-jose
-
diff --git a/hoe-auth/src/main/java/com/recovery/auth/comm/exception/AuthExceptionHandler.java b/hoe-auth/src/main/java/com/recovery/auth/comm/exception/AuthExceptionHandler.java
deleted file mode 100644
index 4c0ba1d..0000000
--- a/hoe-auth/src/main/java/com/recovery/auth/comm/exception/AuthExceptionHandler.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package com.recovery.auth.comm.exception;
-
-
-import com.recovery.common.base.result.ApiResult;
-import com.recovery.common.base.result.ResultCode;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.core.annotation.Order;
-import org.springframework.http.HttpStatus;
-import org.springframework.security.authentication.InternalAuthenticationServiceException;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
-import org.springframework.security.oauth2.common.exceptions.InvalidClientException;
-import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
-import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
-import org.springframework.security.oauth2.provider.NoSuchClientException;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.bind.annotation.ResponseStatus;
-import org.springframework.web.bind.annotation.RestControllerAdvice;
-
-/**
- * @author:
- */
-@RestControllerAdvice
-@Slf4j
-@Order(-1)
-public class AuthExceptionHandler {
-
- /**
- * 用户不存在
- *
- * @param e
- * @return
- */
- @ResponseStatus(HttpStatus.BAD_REQUEST)
- @ExceptionHandler(UsernameNotFoundException.class)
- public ApiResult handleUsernameNotFoundException(UsernameNotFoundException e) {
- log.error("错误信息:{}", e.getMessage(),e);
- return ApiResult.failed(ResultCode.USER_NOT_EXIST);
- }
-
- /**
- * 用户名和密码异常
- *
- * @param e
- * @return
- */
- @ResponseStatus(HttpStatus.BAD_REQUEST)
- @ExceptionHandler(InvalidGrantException.class)
- public ApiResult handleInvalidGrantException(InvalidGrantException e) {
- log.error("错误信息:{}", e.getMessage(),e);
- return ApiResult.failed(ResultCode.USERNAME_OR_PASSWORD_ERROR);
- }
-
- /**
- * 用户名和密码异常
- *
- * @param e
- * @return
- */
- @ResponseStatus(HttpStatus.BAD_REQUEST)
- @ExceptionHandler(InvalidClientException.class)
- public ApiResult handleInvalidGrantException(InvalidClientException e) {
- log.error("错误信息:{}", e.getMessage(),e);
- return ApiResult.failed(ResultCode.CLIENT_AUTHENTICATION_FAILED);
- }
-
-
- /**
- * 账户异常(禁用、锁定、过期)
- *
- * @param e
- * @return
- */
- @ResponseStatus(HttpStatus.BAD_REQUEST)
- @ExceptionHandler({InternalAuthenticationServiceException.class})
- public ApiResult handleInternalAuthenticationServiceException(InternalAuthenticationServiceException e) {
- log.error("错误信息:{}", e.getMessage(),e);
- return ApiResult.failed(e.getMessage());
- }
-
- /**
- * token 无效或已过期
- *
- * @param e
- * @return
- */
- @ResponseStatus(HttpStatus.BAD_REQUEST)
- @ExceptionHandler({InvalidTokenException.class})
- public ApiResult handleInvalidTokenExceptionException(InvalidTokenException e) {
- log.error("错误信息:{}", e.getMessage(),e);
- return ApiResult.failed(e.getMessage());
- }
-
- /**
- * token 无效或已过期
- *
- * @param e
- * @return
- */
- @ResponseStatus(HttpStatus.BAD_REQUEST)
- @ExceptionHandler({NoSuchClientException.class})
- public ApiResult noSuchClientException(NoSuchClientException e) {
- log.error("错误信息:{}", e.getMessage(),e);
- return ApiResult.failed(e.getMessage());
- }
-
-
-}
diff --git a/hoe-auth/src/main/java/com/recovery/auth/comm/utils/CommonUtils.java b/hoe-auth/src/main/java/com/recovery/auth/comm/utils/CommonUtils.java
deleted file mode 100644
index 528af4e..0000000
--- a/hoe-auth/src/main/java/com/recovery/auth/comm/utils/CommonUtils.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.recovery.auth.comm.utils;
-
-import cn.hutool.core.util.StrUtil;
-
-import com.recovery.common.base.constant.SecurityConstants;
-import org.apache.logging.log4j.util.Strings;
-import org.springframework.web.context.request.RequestContextHolder;
-import org.springframework.web.context.request.ServletRequestAttributes;
-
-import javax.servlet.http.HttpServletRequest;
-import java.nio.charset.StandardCharsets;
-import java.util.Base64;
-
-/**
- * @author:
- * @date: 2022/5/23
- */
-public class CommonUtils {
- public static String getOAuth2ClientId() {
-
- HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
-
- String clientId = request.getParameter(SecurityConstants.CLIENT_ID_KEY);
- if (StrUtil.isNotBlank(clientId)) {
- return clientId;
- }
-
- String basic = request.getHeader(SecurityConstants.AUTHORIZATION_KEY);
- if (StrUtil.isNotBlank(basic) && basic.startsWith(SecurityConstants.BASIC_PREFIX)) {
- basic = basic.replace(SecurityConstants.BASIC_PREFIX, Strings.EMPTY);
- String basicPlainText = new String(Base64.getDecoder().decode(basic.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
- clientId = basicPlainText.split(":")[0];
- }
- return clientId;
- }
-}
diff --git a/hoe-auth/src/main/java/com/recovery/auth/config/AuthorizationServerConfig.java b/hoe-auth/src/main/java/com/recovery/auth/config/AuthorizationServerConfig.java
deleted file mode 100644
index 520d47c..0000000
--- a/hoe-auth/src/main/java/com/recovery/auth/config/AuthorizationServerConfig.java
+++ /dev/null
@@ -1,138 +0,0 @@
-package com.recovery.auth.config;
-
-import cn.hutool.core.collection.CollectionUtil;
-
-import com.recovery.auth.security.details.client.ClientDetailsServiceImpl;
-import com.recovery.auth.security.details.user.SysUserDetails;
-import lombok.RequiredArgsConstructor;
-import lombok.SneakyThrows;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
-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.provider.CompositeTokenGranter;
-import org.springframework.security.oauth2.provider.TokenGranter;
-import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
-import org.springframework.security.oauth2.provider.token.TokenEnhancer;
-import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
-import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
-import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;
-
-import java.security.KeyPair;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Created with IntelliJ IDEA.
- *
- * @author
- * @date: 2021/11/24
- * @description:
- * @modifiedBy:
- * @version: 1.0
- */
-@Configuration
-@EnableAuthorizationServer
-@RequiredArgsConstructor
-public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
-
- private final AuthenticationManager authenticationManager;
- private final ClientDetailsServiceImpl clientDetailsService;
-
- /**
- * OAuth2客户端
- */
- @Override
- @SneakyThrows
- public void configure(ClientDetailsServiceConfigurer clients) {
- clients.withClientDetails(clientDetailsService);
- }
-
- /**
- * 配置授权(authorization)以及令牌(token)的访问端点和令牌服务(token services)
- */
- @Override
- public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
- // Token增强
- TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
- List tokenEnhancers = new ArrayList<>();
- tokenEnhancers.add(tokenEnhancer());
- tokenEnhancers.add(jwtAccessTokenConverter());
- tokenEnhancerChain.setTokenEnhancers(tokenEnhancers);
-
- // 获取原有默认授权模式(授权码模式、密码模式、客户端模式、简化模式)的授权者
- List granterList = new ArrayList<>(Arrays.asList(endpoints.getTokenGranter()));
-
- CompositeTokenGranter compositeTokenGranter = new CompositeTokenGranter(granterList);
- endpoints
- .authenticationManager(authenticationManager)
- .accessTokenConverter(jwtAccessTokenConverter())
- .tokenEnhancer(tokenEnhancerChain)
- .tokenGranter(compositeTokenGranter)
- .reuseRefreshTokens(true)
- .tokenServices(tokenServices(endpoints))
- ;
- }
-
- public DefaultTokenServices tokenServices(AuthorizationServerEndpointsConfigurer endpoints) {
- TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
- List tokenEnhancers = new ArrayList<>();
- tokenEnhancers.add(tokenEnhancer());
- tokenEnhancers.add(jwtAccessTokenConverter());
- tokenEnhancerChain.setTokenEnhancers(tokenEnhancers);
-
- DefaultTokenServices tokenServices = new DefaultTokenServices();
- tokenServices.setTokenStore(endpoints.getTokenStore());
- tokenServices.setSupportRefreshToken(true);
- tokenServices.setClientDetailsService(clientDetailsService);
- tokenServices.setTokenEnhancer(tokenEnhancerChain);
- return tokenServices;
-
- }
-
- /**
- * JWT内容增强
- */
- @Bean
- public TokenEnhancer tokenEnhancer() {
- return (accessToken, authentication) -> {
- Map additionalInfo = CollectionUtil.newHashMap();
- Object principal = authentication.getUserAuthentication().getPrincipal();
- if (principal instanceof SysUserDetails){
- SysUserDetails sysUserDetails = (SysUserDetails) principal;
- additionalInfo.put("userId", sysUserDetails.getUserId());
- additionalInfo.put("username", sysUserDetails.getUsername());
- ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
- }
-
- return accessToken;
- };
- }
-
- /**
- * 使用非对称加密算法对token签名
- */
- @Bean
- public JwtAccessTokenConverter jwtAccessTokenConverter() {
- JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
- converter.setKeyPair(keyPair());
- return converter;
- }
-
- /**
- * 密钥库中获取密钥对(公钥+私钥)
- */
- @Bean
- public KeyPair keyPair() {
- KeyStoreKeyFactory factory = new KeyStoreKeyFactory(new ClassPathResource("jwt.jks"), "afd123".toCharArray());
- KeyPair keyPair = factory.getKeyPair("jwt", "afd123".toCharArray());
- return keyPair;
- }
-}
\ No newline at end of file
diff --git a/hoe-auth/src/main/java/com/recovery/auth/config/SaTokenConfigure.java b/hoe-auth/src/main/java/com/recovery/auth/config/SaTokenConfigure.java
new file mode 100644
index 0000000..68849d3
--- /dev/null
+++ b/hoe-auth/src/main/java/com/recovery/auth/config/SaTokenConfigure.java
@@ -0,0 +1,32 @@
+package com.recovery.auth.config;
+
+import cn.dev33.satoken.context.SaHolder;
+import cn.dev33.satoken.filter.SaServletFilter;
+import cn.dev33.satoken.same.SaSameUtil;
+import cn.dev33.satoken.util.SaResult;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * Sa-Token 权限认证 配置类
+ */
+@Configuration
+public class SaTokenConfigure implements WebMvcConfigurer {
+ // 注册 Sa-Token 全局过滤器
+ @Bean
+ public SaServletFilter getSaServletFilter() {
+ return new SaServletFilter()
+ .addInclude("/**")
+ .addExclude("/favicon.ico")
+ .setAuth(obj -> {
+ // 校验 Same-Token 身份凭证 —— 以下两句代码可简化为:SaSameUtil.checkCurrentRequestToken();
+ String token = SaHolder.getRequest().getHeader(SaSameUtil.SAME_TOKEN);
+ SaSameUtil.checkToken(token);
+ })
+ .setError(e -> {
+ return SaResult.error(e.getMessage());
+ })
+ ;
+ }
+}
\ No newline at end of file
diff --git a/hoe-auth/src/main/java/com/recovery/auth/config/WebSecurityConfig.java b/hoe-auth/src/main/java/com/recovery/auth/config/WebSecurityConfig.java
deleted file mode 100644
index b77aac9..0000000
--- a/hoe-auth/src/main/java/com/recovery/auth/config/WebSecurityConfig.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package com.recovery.auth.config;
-
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.security.crypto.factory.PasswordEncoderFactories;
-import org.springframework.security.crypto.password.PasswordEncoder;
-
-/**
- * Created with IntelliJ IDEA.
- *
- * @author:
- * @date: 2021/11/24
- * @description:
- * @modifiedBy:
- * @version: 1.0
- */
-@Configuration
-@EnableWebSecurity
-@Slf4j
-@RequiredArgsConstructor
-public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
-
- private final UserDetailsService sysUserDetailsService;
-
-
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- http
- .authorizeRequests().antMatchers("/api/oauth/**").permitAll()
- .anyRequest().authenticated()
- .and()
- .httpBasic()
- .and()
- .csrf().disable();
- }
-
- /**
- * 认证管理对象
- *
- * @return
- * @throws Exception
- */
- @Bean
- public AuthenticationManager authenticationManagerBean() throws Exception {
- return super.authenticationManagerBean();
- }
-
- /**
- * 添加自定义认证器
- *
- * @param auth
- */
- @Override
- public void configure(AuthenticationManagerBuilder auth) throws Exception {
- auth.authenticationProvider(daoAuthenticationProvider());
- }
-
- /**
- * 设置默认的用户名密码认证授权提供者
- *
- * @return
- */
- @Bean
- public DaoAuthenticationProvider daoAuthenticationProvider() {
- DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
- provider.setUserDetailsService(sysUserDetailsService);
- provider.setPasswordEncoder(passwordEncoder());
- provider.setHideUserNotFoundExceptions(false); // 是否隐藏用户不存在异常,默认:true-隐藏;false-抛出异常;
- return provider;
- }
-
- @Bean
- public PasswordEncoder passwordEncoder() {
- return PasswordEncoderFactories.createDelegatingPasswordEncoder();
- }
-}
\ No newline at end of file
diff --git a/hoe-auth/src/main/java/com/recovery/auth/controller/AuthController.java b/hoe-auth/src/main/java/com/recovery/auth/controller/AuthController.java
index c99d74f..fab7eba 100644
--- a/hoe-auth/src/main/java/com/recovery/auth/controller/AuthController.java
+++ b/hoe-auth/src/main/java/com/recovery/auth/controller/AuthController.java
@@ -1,25 +1,25 @@
package com.recovery.auth.controller;
-import com.nimbusds.jose.jwk.JWKSet;
-import com.nimbusds.jose.jwk.RSAKey;
+import cn.dev33.satoken.stp.SaTokenInfo;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.dev33.satoken.util.SaResult;
+import com.recovery.auth.exception.BusinessException;
+import com.recovery.auth.feign.UserFeignClient;
import com.recovery.auth.security.details.user.JwtAuthenticationRequest;
import com.recovery.auth.service.AuthService;
+import com.recovery.common.base.dto.UserAuthDTO;
+import com.recovery.common.base.dto.UserAuthorityDto;
import com.recovery.common.base.result.ApiResult;
+import com.recovery.common.base.result.ResultCode;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.security.oauth2.common.OAuth2AccessToken;
-import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
-import org.springframework.web.HttpRequestMethodNotSupportedException;
+import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
-import java.security.KeyPair;
-import java.security.Principal;
-import java.security.interfaces.RSAPublicKey;
import java.util.HashMap;
-import java.util.Map;
/**
* @author:
@@ -32,6 +32,8 @@ public class AuthController {
@Resource
AuthService authService;
+ @Resource
+ UserFeignClient userFeignClient;
@PostMapping("/token")
public ApiResult postAccessToken(@RequestBody JwtAuthenticationRequest authenticationRequest, HttpServletRequest request){
@@ -46,6 +48,32 @@ public class AuthController {
return ApiResult.ok(map);
}
+ @GetMapping("/doLogin")
+ public SaResult doLogin(@RequestBody JwtAuthenticationRequest authenticationRequest) {
+ if(StringUtils.isEmpty(authenticationRequest.getUsername())){
+ throw new BusinessException("账户不能为空");
+ }
+ if(StringUtils.isEmpty(authenticationRequest.getPassword())){
+ throw new BusinessException("密码不能为空");
+ }
+
+ ApiResult result = userFeignClient.getUserByUsername(authenticationRequest.getUsername());
+ UserAuthDTO userDetails = new UserAuthDTO();
+ if (ResultCode.SUCCESS.getCode().equals(result.getCode())) {
+ userDetails = result.getData();
+ }
+ // 此处仅作模拟示例,真实项目需要从数据库中查询数据进行比对
+ if (userDetails.getUserName().equals(authenticationRequest.getUsername()) && userDetails.getPassword().equals(authenticationRequest.getPassword())) {
+ log.info("密码校验成功!");
+ StpUtil.login(userDetails.getUserName());
+ }else {
+ return SaResult.error("密码错误");
+ }
+ // 第3步,返回给前端
+ SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
+ return SaResult.ok("登录成功").setData(tokenInfo);
+ }
+
// @GetMapping("/public-key")
// public Map getPublicKey() {
// //单例模式
diff --git a/hoe-auth/src/main/java/com/recovery/auth/security/details/client/ClientDetailsServiceImpl.java b/hoe-auth/src/main/java/com/recovery/auth/security/details/client/ClientDetailsServiceImpl.java
deleted file mode 100644
index 9d3bec7..0000000
--- a/hoe-auth/src/main/java/com/recovery/auth/security/details/client/ClientDetailsServiceImpl.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.recovery.auth.security.details.client;
-
-
-
-import com.recovery.common.base.enums.PasswordEncoderTypeEnum;
-import lombok.RequiredArgsConstructor;
-import org.springframework.cache.annotation.Cacheable;
-import org.springframework.security.oauth2.provider.ClientDetails;
-import org.springframework.security.oauth2.provider.ClientDetailsService;
-import org.springframework.security.oauth2.provider.client.BaseClientDetails;
-import org.springframework.stereotype.Service;
-
-/**
- * Created with IntelliJ IDEA.
- *
- * @author: AI码师
- * @date: 2021/11/24
- * @description:
- * @modifiedBy:
- * @version: 1.0
- */
-@Service
-@RequiredArgsConstructor
-public class ClientDetailsServiceImpl implements ClientDetailsService {
- @Override
- @Cacheable(cacheNames = "auth", key = "'oauth-client:'+#clientId")
- public ClientDetails loadClientByClientId(String clientId) {
- // 后面通过feign从管理端获取,目前写死
- BaseClientDetails clientDetails = new BaseClientDetails(
- "hoe",
- "",
- "all",
- "password,client_credentials,refresh_token,authorization_code",
- "",
- "http://www.baidu.com"
-
- );
- clientDetails.setClientSecret(PasswordEncoderTypeEnum.NOOP.getPrefix() + "hoe");
- clientDetails.setAccessTokenValiditySeconds(3600);
- clientDetails.setRefreshTokenValiditySeconds(36000000);
- return clientDetails;
- }
-}
diff --git a/hoe-auth/src/main/java/com/recovery/auth/security/details/user/JwtAuthenticationRequest.java b/hoe-auth/src/main/java/com/recovery/auth/security/details/user/JwtAuthenticationRequest.java
deleted file mode 100644
index 342f09e..0000000
--- a/hoe-auth/src/main/java/com/recovery/auth/security/details/user/JwtAuthenticationRequest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package com.recovery.auth.security.details.user;
-
-import java.io.Serializable;
-
-public class JwtAuthenticationRequest implements Serializable {
-
- private static final long serialVersionUID = -8445943548965154778L;
-
- private String username;
- private String phone;
- private String password;
- private String verifyCode;
- private String loginMethod;
- private String visitorsType;
-
- public JwtAuthenticationRequest(String username,String phone,String password,String verifyCode,String loginMethod,String visitorsType) {
- this.username = username;
- this.phone = phone;
- this.password = password;
- this.verifyCode = verifyCode;
- this.loginMethod = loginMethod;
- this.visitorsType = visitorsType;
- }
-
- public JwtAuthenticationRequest() {
- }
-
- public String getPassword() {
- return password;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public String getUserPhone() {
- return phone;
- }
-
- public void setUserPhone(String phone) {
- this.phone = phone;
- }
-
- public String getVerifyCode() {
- return verifyCode;
- }
-
- public void setVerifyCode(String verifyCode) {
- this.verifyCode = verifyCode;
- }
-
- public String getLoginMethod() {
- return loginMethod;
- }
-
- public void setLoginMethod(String loginMethod) {
- this.loginMethod = loginMethod;
- }
- public String getVisitorsType() {
- return visitorsType;
- }
-
- public void setVisitorsType(String visitorsType) {
- this.visitorsType = visitorsType;
- }
-}
diff --git a/hoe-auth/src/main/java/com/recovery/auth/security/details/user/SysUserDetails.java b/hoe-auth/src/main/java/com/recovery/auth/security/details/user/SysUserDetails.java
deleted file mode 100644
index 89b04c3..0000000
--- a/hoe-auth/src/main/java/com/recovery/auth/security/details/user/SysUserDetails.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package com.recovery.auth.security.details.user;
-
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-
-import java.util.Collection;
-
-/**
- * @author:
- */
-@Data
-@Builder
-@AllArgsConstructor
-@NoArgsConstructor
-public class SysUserDetails implements UserDetails {
-
- /**
- * 扩展字段
- */
- private Long userId;
-
- /**
- * 默认字段
- */
- private String username;
- private String password;
- /**
- * 是否启用
- */
- private Boolean enabled;
- /**
- * 角色
- */
- private Collection authorities;
-
-
- @Override
- public Collection extends GrantedAuthority> getAuthorities() {
- return this.authorities;
- }
-
- @Override
- public String getPassword() {
- return this.password;
- }
-
- @Override
- public String getUsername() {
- return this.username;
- }
-
- @Override
- public boolean isAccountNonExpired() {
- return true;
- }
-
- @Override
- public boolean isAccountNonLocked() {
- return true;
- }
-
- @Override
- public boolean isCredentialsNonExpired() {
- return true;
- }
-
- @Override
- public boolean isEnabled() {
- return this.enabled;
- }
-}
diff --git a/hoe-auth/src/main/java/com/recovery/auth/security/details/user/SysUserDetailsServiceImpl.java b/hoe-auth/src/main/java/com/recovery/auth/security/details/user/SysUserDetailsServiceImpl.java
deleted file mode 100644
index 626cba7..0000000
--- a/hoe-auth/src/main/java/com/recovery/auth/security/details/user/SysUserDetailsServiceImpl.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package com.recovery.auth.security.details.user;
-
-import com.recovery.auth.feign.UserFeignClient;
-import com.recovery.common.base.dto.UserAuthDTO;
-import com.recovery.common.base.enums.PasswordEncoderTypeEnum;
-import com.recovery.common.base.result.ApiResult;
-import com.recovery.common.base.result.ResultCode;
-import com.recovery.common.base.util.RedisUtil;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.security.authentication.AccountExpiredException;
-import org.springframework.security.authentication.DisabledException;
-import org.springframework.security.authentication.LockedException;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
-import org.springframework.stereotype.Service;
-
-import javax.annotation.Resource;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * @author:
- */
-@Service("sysUserDetailsService")
-@Slf4j
-@RequiredArgsConstructor
-public class SysUserDetailsServiceImpl implements UserDetailsService {
-
-
- @Resource
- private UserFeignClient userFeignClient;
- @Resource
- RedisUtil redisUtil;
-
- @Override
- public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
- // 后面从管理端获取用户信息
- ApiResult result = userFeignClient.getUserByUsername(username);
- SysUserDetails userDetails = null;
- if (ApiResult.ok().getCode().equals(result.getCode())) {
- UserAuthDTO user = result.getData();
- if (null != user) {
- userDetails = SysUserDetails.builder()
- .userId(user.getUserId())
- .username(user.getUserName())
- //角色
-// .authorities(handleRoles(user.getRoles()))
- .enabled(user.getStatus() == 1)
- .password(PasswordEncoderTypeEnum.BCRYPT.getPrefix() + user.getPassword())
- .build();
- }
- }
- if (Objects.isNull(userDetails)) {
- throw new UsernameNotFoundException(ResultCode.USER_NOT_EXIST.getMsg());
- } else if (!userDetails.isEnabled()) {
- throw new DisabledException("该账户已被禁用!");
- } else if (!userDetails.isAccountNonLocked()) {
- throw new LockedException("该账号已被锁定!");
- } else if (!userDetails.isAccountNonExpired()) {
- throw new AccountExpiredException("该账号已过期!");
- }
- return userDetails;
- }
-
- private Collection handleRoles(List roles) {
- Collection authorities = new ArrayList<>();
- for (String role : roles) {
- authorities.add(new SimpleGrantedAuthority(role));
- }
- return authorities;
- }
-
-
-}
diff --git a/hoe-auth/src/main/java/com/recovery/auth/service/impl/AuthServiceImpl.java b/hoe-auth/src/main/java/com/recovery/auth/service/impl/AuthServiceImpl.java
index e330dbd..2752009 100644
--- a/hoe-auth/src/main/java/com/recovery/auth/service/impl/AuthServiceImpl.java
+++ b/hoe-auth/src/main/java/com/recovery/auth/service/impl/AuthServiceImpl.java
@@ -1,11 +1,9 @@
package com.recovery.auth.service.impl;
-import com.alibaba.fastjson.JSON;
import com.recovery.auth.exception.BusinessException;
import com.recovery.auth.feign.UserFeignClient;
import com.recovery.auth.security.details.user.JwtAuthenticationRequest;
-import com.recovery.auth.security.details.user.SysUserDetails;
import com.recovery.auth.service.AuthService;
import com.recovery.common.base.dto.UserAuthDTO;
import com.recovery.common.base.dto.UserAuthorityDto;
@@ -15,16 +13,11 @@ import com.recovery.common.base.util.EncryptUtil;
import com.recovery.common.base.util.RedisUtil;
import com.recovery.common.base.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.security.authentication.AccountExpiredException;
-import org.springframework.security.authentication.DisabledException;
-import org.springframework.security.authentication.LockedException;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
-import java.util.Map;
import java.util.Objects;
/**
diff --git a/hoe-gateway/pom.xml b/hoe-gateway/pom.xml
index 33e695d..4af5e16 100644
--- a/hoe-gateway/pom.xml
+++ b/hoe-gateway/pom.xml
@@ -48,6 +48,22 @@
spring-jdbc
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.13
+
+
+
+
+
+ cn.dev33
+ sa-token-reactor-spring-boot-starter
+ 1.34.0
+
+
+
mysql
diff --git a/hoe-gateway/src/main/java/com/recovery/gateway/config/SaTokenConfigure.java b/hoe-gateway/src/main/java/com/recovery/gateway/config/SaTokenConfigure.java
new file mode 100644
index 0000000..9c949f7
--- /dev/null
+++ b/hoe-gateway/src/main/java/com/recovery/gateway/config/SaTokenConfigure.java
@@ -0,0 +1,42 @@
+package com.recovery.gateway.config;
+
+
+import cn.dev33.satoken.reactor.filter.SaReactorFilter;
+import cn.dev33.satoken.router.SaRouter;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.dev33.satoken.util.SaResult;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * [Sa-Token 权限认证] 配置类
+ */
+@Configuration
+public class SaTokenConfigure {
+ // 注册 Sa-Token全局过滤器
+ @Bean
+ public SaReactorFilter getSaReactorFilter() {
+ return new SaReactorFilter()
+ // 拦截地址
+ .addInclude("/**") /* 拦截全部path */
+ // 开放地址
+ .addExclude("/favicon.ico")
+ // 鉴权方法:每次访问进入
+ .setAuth(obj -> {
+ // 登录校验 -- 拦截所有路由,并排除/user/doLogin 用于开放登录
+ SaRouter.match("/**", "/auth/oauth/doLogin", r -> StpUtil.checkLogin());
+
+ // 权限认证 -- 不同模块, 校验不同权限
+ SaRouter.match("/api/test1", r -> StpUtil.checkPermission("api.test1"));
+ SaRouter.match("/api/test2", r -> StpUtil.checkPermission("api.test2"));
+ SaRouter.match("/api/test3", r -> StpUtil.checkRoleOr("admin", "super"));
+
+ // 更多匹配 ... */
+ })
+ // 异常处理方法:每次setAuth函数出现异常时进入
+ .setError(e -> {
+ return SaResult.error(e.getMessage());
+ })
+ ;
+ }
+}
diff --git a/hoe-gateway/src/main/java/com/recovery/gateway/security/ResourceServerConfig.java b/hoe-gateway/src/main/java/com/recovery/gateway/security/ResourceServerConfig.java
index 4a869a3..e2af47c 100644
--- a/hoe-gateway/src/main/java/com/recovery/gateway/security/ResourceServerConfig.java
+++ b/hoe-gateway/src/main/java/com/recovery/gateway/security/ResourceServerConfig.java
@@ -1,80 +1,80 @@
-package com.recovery.gateway.security;
-
-
-import com.recovery.common.base.constant.SecurityConstants;
-import com.recovery.common.base.result.ResultCode;
-import com.recovery.gateway.util.ResponseUtils;
-import lombok.AllArgsConstructor;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.convert.converter.Converter;
-import org.springframework.security.authentication.AbstractAuthenticationToken;
-import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
-import org.springframework.security.config.web.server.ServerHttpSecurity;
-import org.springframework.security.oauth2.jwt.Jwt;
-import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
-import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
-import org.springframework.security.oauth2.server.resource.authentication.ReactiveJwtAuthenticationConverterAdapter;
-import org.springframework.security.web.server.SecurityWebFilterChain;
-import org.springframework.security.web.server.ServerAuthenticationEntryPoint;
-import org.springframework.security.web.server.authorization.ServerAccessDeniedHandler;
-import reactor.core.publisher.Mono;
-/**
- * @author:
- */
-@AllArgsConstructor
-@Configuration
-@EnableWebFluxSecurity
-public class ResourceServerConfig {
-
- private final ResourceServerManager resourceServerManager;
-
- @Bean
- public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
- http.oauth2ResourceServer().jwt().jwtAuthenticationConverter(jwtAuthenticationConverter());
- http.oauth2ResourceServer().authenticationEntryPoint(authenticationEntryPoint());
- http.authorizeExchange()
- .anyExchange().access(resourceServerManager)
- .and()
- .exceptionHandling()
- .accessDeniedHandler(accessDeniedHandler()) // 处理未授权
- .authenticationEntryPoint(authenticationEntryPoint()) //处理未认证
- .and().csrf().disable();
- return http.build();
- }
-
- /**
- * 自定义未授权响应
- */
- @Bean
- ServerAccessDeniedHandler accessDeniedHandler() {
- return (exchange, denied) -> {
- Mono mono = Mono.defer(() -> Mono.just(exchange.getResponse()))
- .flatMap(response -> ResponseUtils.writeErrorInfo(response, ResultCode.ACCESS_UNAUTHORIZED));
- return mono;
- };
- }
-
- /**
- * token无效或者已过期自定义响应
- */
- @Bean
- ServerAuthenticationEntryPoint authenticationEntryPoint() {
- return (exchange, e) -> {
- Mono mono = Mono.defer(() -> Mono.just(exchange.getResponse()))
- .flatMap(response -> ResponseUtils.writeErrorInfo(response, ResultCode.TOKEN_INVALID_OR_EXPIRED));
- return mono;
- };
- }
-
- @Bean
- public Converter> jwtAuthenticationConverter() {
- JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
- jwtGrantedAuthoritiesConverter.setAuthorityPrefix(SecurityConstants.AUTHORITY_PREFIX);
- jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName(SecurityConstants.JWT_AUTHORITIES_KEY);
-
- JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
- jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(jwtGrantedAuthoritiesConverter);
- return new ReactiveJwtAuthenticationConverterAdapter(jwtAuthenticationConverter);
- }
-}
\ No newline at end of file
+//package com.recovery.gateway.security;
+//
+//
+//import com.recovery.common.base.constant.SecurityConstants;
+//import com.recovery.common.base.result.ResultCode;
+//import com.recovery.gateway.util.ResponseUtils;
+//import lombok.AllArgsConstructor;
+//import org.springframework.context.annotation.Bean;
+//import org.springframework.context.annotation.Configuration;
+//import org.springframework.core.convert.converter.Converter;
+//import org.springframework.security.authentication.AbstractAuthenticationToken;
+//import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
+//import org.springframework.security.config.web.server.ServerHttpSecurity;
+//import org.springframework.security.oauth2.jwt.Jwt;
+//import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
+//import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
+//import org.springframework.security.oauth2.server.resource.authentication.ReactiveJwtAuthenticationConverterAdapter;
+//import org.springframework.security.web.server.SecurityWebFilterChain;
+//import org.springframework.security.web.server.ServerAuthenticationEntryPoint;
+//import org.springframework.security.web.server.authorization.ServerAccessDeniedHandler;
+//import reactor.core.publisher.Mono;
+///**
+// * @author:
+// */
+//@AllArgsConstructor
+//@Configuration
+//@EnableWebFluxSecurity
+//public class ResourceServerConfig {
+//
+// private final ResourceServerManager resourceServerManager;
+//
+// @Bean
+// public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
+// http.oauth2ResourceServer().jwt().jwtAuthenticationConverter(jwtAuthenticationConverter());
+// http.oauth2ResourceServer().authenticationEntryPoint(authenticationEntryPoint());
+// http.authorizeExchange()
+// .anyExchange().access(resourceServerManager)
+// .and()
+// .exceptionHandling()
+// .accessDeniedHandler(accessDeniedHandler()) // 处理未授权
+// .authenticationEntryPoint(authenticationEntryPoint()) //处理未认证
+// .and().csrf().disable();
+// return http.build();
+// }
+//
+// /**
+// * 自定义未授权响应
+// */
+// @Bean
+// ServerAccessDeniedHandler accessDeniedHandler() {
+// return (exchange, denied) -> {
+// Mono mono = Mono.defer(() -> Mono.just(exchange.getResponse()))
+// .flatMap(response -> ResponseUtils.writeErrorInfo(response, ResultCode.ACCESS_UNAUTHORIZED));
+// return mono;
+// };
+// }
+//
+// /**
+// * token无效或者已过期自定义响应
+// */
+// @Bean
+// ServerAuthenticationEntryPoint authenticationEntryPoint() {
+// return (exchange, e) -> {
+// Mono mono = Mono.defer(() -> Mono.just(exchange.getResponse()))
+// .flatMap(response -> ResponseUtils.writeErrorInfo(response, ResultCode.TOKEN_INVALID_OR_EXPIRED));
+// return mono;
+// };
+// }
+//
+// @Bean
+// public Converter> jwtAuthenticationConverter() {
+// JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
+// jwtGrantedAuthoritiesConverter.setAuthorityPrefix(SecurityConstants.AUTHORITY_PREFIX);
+// jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName(SecurityConstants.JWT_AUTHORITIES_KEY);
+//
+// JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
+// jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(jwtGrantedAuthoritiesConverter);
+// return new ReactiveJwtAuthenticationConverterAdapter(jwtAuthenticationConverter);
+// }
+//}
\ No newline at end of file
diff --git a/hoe-gateway/src/main/java/com/recovery/gateway/security/ResourceServerManager.java b/hoe-gateway/src/main/java/com/recovery/gateway/security/ResourceServerManager.java
index 637e013..5a0c519 100644
--- a/hoe-gateway/src/main/java/com/recovery/gateway/security/ResourceServerManager.java
+++ b/hoe-gateway/src/main/java/com/recovery/gateway/security/ResourceServerManager.java
@@ -1,122 +1,79 @@
-package com.recovery.gateway.security;
-
-import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.convert.Convert;
-import cn.hutool.core.util.StrUtil;
-
-import com.recovery.common.base.constant.GlobalConstants;
-import com.recovery.common.base.constant.SecurityConstants;
-import com.recovery.gateway.util.UrlPatternUtils;
-import lombok.RequiredArgsConstructor;
-import lombok.Setter;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.server.reactive.ServerHttpRequest;
-import org.springframework.security.authorization.AuthorizationDecision;
-import org.springframework.security.authorization.ReactiveAuthorizationManager;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.web.server.authorization.AuthorizationContext;
-import org.springframework.stereotype.Component;
-import org.springframework.util.AntPathMatcher;
-import org.springframework.util.PathMatcher;
-import reactor.core.publisher.Mono;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-/**
- * Created with IntelliJ IDEA.
- *
- * @author: AI码师 关注公众号"AI码师"获取完整源码
- * @date: 2021/11/24
- * @description:
- * @modifiedBy:
- * @version: 1.0
- */
-@Component
-@RequiredArgsConstructor
-@Slf4j
-@ConfigurationProperties(prefix = "security")
-public class ResourceServerManager implements ReactiveAuthorizationManager {
- private final RedisTemplate redisTemplate;
-
- @Setter
- private List ignoreUrls;
-
- @Override
- public Mono check(Mono mono, AuthorizationContext authorizationContext) {
- ServerHttpRequest request = authorizationContext.getExchange().getRequest();
- if (request.getMethod() == HttpMethod.OPTIONS) { // 预检请求放行
- return Mono.just(new AuthorizationDecision(true));
- }
- PathMatcher pathMatcher = new AntPathMatcher();
- String method = request.getMethodValue();
- String path = request.getURI().getPath();
-
- // 跳过token校验,放在这里去做是为了能够动态刷新
-// if (skipValid(path)) {
- return Mono.just(new AuthorizationDecision(true));
-// }
-
-// // 如果token为空 或者token不合法 则进行拦截
-// String restfulPath = method + ":" + path; // RESTFul接口权限设计 @link https://www.cnblogs.com/haoxianrui/p/14961707.html
-// String token = request.getHeaders().getFirst(SecurityConstants.AUTHORIZATION_KEY);
-// if (StrUtil.isBlank(token) || !StrUtil.startWithIgnoreCase(token, SecurityConstants.JWT_PREFIX)) {
-// return Mono.just(new AuthorizationDecision(false));
-// }
+//package com.recovery.gateway.security;
//
-// // 从redis中获取资源权限
-// Map urlPermRolesRules = redisTemplate.opsForHash().entries(GlobalConstants.URL_PERM_ROLES_KEY);
-// List authorizedRoles = new ArrayList<>(); // 拥有访问权限的角色
-// boolean requireCheck = false; // 是否需要鉴权,默认未设置拦截规则不需鉴权
+//import cn.hutool.core.collection.CollectionUtil;
+//import cn.hutool.core.convert.Convert;
+//import cn.hutool.core.util.StrUtil;
//
-// // 获取当前资源 所需要的角色
-// for (Map.Entry permRoles : urlPermRolesRules.entrySet()) {
-// String perm = permRoles.getKey();
-// if (pathMatcher.match(perm, restfulPath)) {
-// List roles = Convert.toList(String.class, permRoles.getValue());
-// authorizedRoles.addAll(Convert.toList(String.class, roles));
-// if (requireCheck == false) {
-// requireCheck = true;
-// }
-// }
-// }
+//import com.recovery.common.base.constant.GlobalConstants;
+//import com.recovery.common.base.constant.SecurityConstants;
+//import com.recovery.gateway.util.UrlPatternUtils;
+//import lombok.RequiredArgsConstructor;
+//import lombok.Setter;
+//import lombok.extern.slf4j.Slf4j;
+//import org.springframework.boot.context.properties.ConfigurationProperties;
+//import org.springframework.data.redis.core.RedisTemplate;
+//import org.springframework.http.HttpMethod;
+//import org.springframework.http.server.reactive.ServerHttpRequest;
+//import org.springframework.security.authorization.AuthorizationDecision;
+//import org.springframework.security.authorization.ReactiveAuthorizationManager;
+//import org.springframework.security.core.Authentication;
+//import org.springframework.security.core.GrantedAuthority;
+//import org.springframework.security.web.server.authorization.AuthorizationContext;
+//import org.springframework.stereotype.Component;
+//import org.springframework.util.AntPathMatcher;
+//import org.springframework.util.PathMatcher;
+//import reactor.core.publisher.Mono;
//
-// // 如果资源不需要权限 则直接返回授权成功
-// if (!requireCheck) {
+//import java.util.ArrayList;
+//import java.util.List;
+//import java.util.Map;
+///**
+// * Created with IntelliJ IDEA.
+// *
+// * @author:
+// * @date: 2021/11/24
+// * @description:
+// * @modifiedBy:
+// * @version: 1.0
+// */
+//@Component
+//@RequiredArgsConstructor
+//@Slf4j
+//@ConfigurationProperties(prefix = "security")
+//public class ResourceServerManager implements ReactiveAuthorizationManager {
+// private final RedisTemplate redisTemplate;
+//
+// @Setter
+// private List ignoreUrls;
+//
+// @Override
+// public Mono check(Mono mono, AuthorizationContext authorizationContext) {
+// ServerHttpRequest request = authorizationContext.getExchange().getRequest();
+// if (request.getMethod() == HttpMethod.OPTIONS) { // 预检请求放行
// return Mono.just(new AuthorizationDecision(true));
// }
+// PathMatcher pathMatcher = new AntPathMatcher();
+// String method = request.getMethodValue();
+// String path = request.getURI().getPath();
//
-// // 判断JWT中携带的用户角色是否有权限访问
-// Mono authorizationDecisionMono = mono
-// .filter(Authentication::isAuthenticated)
-// .flatMapIterable(Authentication::getAuthorities)
-// .map(GrantedAuthority::getAuthority)
-// .any(authority -> {
-// String roleCode = authority.substring(SecurityConstants.AUTHORITY_PREFIX.length()); // 用户的角色
-// boolean hasAuthorized = CollectionUtil.isNotEmpty(authorizedRoles) && authorizedRoles.contains(roleCode);
-// return hasAuthorized;
-// })
-// .map(AuthorizationDecision::new)
-// .defaultIfEmpty(new AuthorizationDecision(false));
-// return authorizationDecisionMono;
- }
-
- /**
- * 跳过校验
- *
- * @param path
- * @return
- */
- private boolean skipValid(String path) {
- for (String skipPath : ignoreUrls) {
- if (UrlPatternUtils.match(skipPath, path)) {
- return true;
- }
- }
- return false;
- }
-}
\ No newline at end of file
+// // 跳过token校验,放在这里去做是为了能够动态刷新
+//// if (skipValid(path)) {
+// return Mono.just(new AuthorizationDecision(true));
+//// }
+// }
+//
+// /**
+// * 跳过校验
+// *
+// * @param path
+// * @return
+// */
+// private boolean skipValid(String path) {
+// for (String skipPath : ignoreUrls) {
+// if (UrlPatternUtils.match(skipPath, path)) {
+// return true;
+// }
+// }
+// return false;
+// }
+//}
\ No newline at end of file
diff --git a/hoe-gateway/src/main/java/com/recovery/gateway/security/SecurityGlobalFilter.java b/hoe-gateway/src/main/java/com/recovery/gateway/security/SecurityGlobalFilter.java
index 5dc9a9c..ff3fa02 100644
--- a/hoe-gateway/src/main/java/com/recovery/gateway/security/SecurityGlobalFilter.java
+++ b/hoe-gateway/src/main/java/com/recovery/gateway/security/SecurityGlobalFilter.java
@@ -1,62 +1,69 @@
-package com.recovery.gateway.security;
-
-import cn.hutool.core.util.StrUtil;
-
-import com.nimbusds.jose.JWSObject;
-import com.recovery.common.base.constant.SecurityConstants;
-import lombok.RequiredArgsConstructor;
-import lombok.SneakyThrows;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.logging.log4j.util.Strings;
-import org.springframework.cloud.gateway.filter.GatewayFilterChain;
-import org.springframework.cloud.gateway.filter.GlobalFilter;
-import org.springframework.core.Ordered;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.http.server.reactive.ServerHttpRequest;
-import org.springframework.http.server.reactive.ServerHttpResponse;
-import org.springframework.stereotype.Component;
-import org.springframework.web.server.ServerWebExchange;
-import reactor.core.publisher.Mono;
-
-import java.net.URLEncoder;
-/**
- * Created with IntelliJ IDEA.
- *
- * @author: AI码师 关注公众号"AI码师"获取完整源码
- * @date: 2021/11/24
- * @description:
- * @modifiedBy:
- * @version: 1.0
- */
-@Component
-@Slf4j
-@RequiredArgsConstructor
-public class SecurityGlobalFilter implements GlobalFilter, Ordered {
-
- @SneakyThrows
- @Override
- public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
-
- ServerHttpRequest request = exchange.getRequest();
- log.info("接受到请求地址:"+request.getURI());
- ServerHttpResponse response = exchange.getResponse();
- // 不是正确的的JWT不做解析处理
- String token = request.getHeaders().getFirst(SecurityConstants.AUTHORIZATION_KEY);
- if (StrUtil.isBlank(token) || !StrUtil.startWithIgnoreCase(token, SecurityConstants.JWT_PREFIX)) {
- return chain.filter(exchange);
- }
- // 解析JWT获取jti,以jti为key判断redis的黑名单列表是否存在,存在则拦截访问
- token = StrUtil.replaceIgnoreCase(token, SecurityConstants.JWT_PREFIX, Strings.EMPTY);
- String payload = StrUtil.toString(JWSObject.parse(token).getPayload());
- request = exchange.getRequest().mutate()
- .header(SecurityConstants.JWT_PAYLOAD_KEY, URLEncoder.encode(payload, "UTF-8"))
- .build();
- exchange = exchange.mutate().request(request).build();
- return chain.filter(exchange);
- }
-
- @Override
- public int getOrder() {
- return 0;
- }
-}
\ No newline at end of file
+//package com.recovery.gateway.security;
+//
+//import cn.dev33.satoken.same.SaSameUtil;
+//import cn.hutool.core.util.StrUtil;
+//
+//import com.nimbusds.jose.JWSObject;
+//import com.recovery.common.base.constant.SecurityConstants;
+//import lombok.RequiredArgsConstructor;
+//import lombok.SneakyThrows;
+//import lombok.extern.slf4j.Slf4j;
+//import org.apache.logging.log4j.util.Strings;
+//import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+//import org.springframework.cloud.gateway.filter.GlobalFilter;
+//import org.springframework.core.Ordered;
+//import org.springframework.data.redis.core.RedisTemplate;
+//import org.springframework.http.server.reactive.ServerHttpRequest;
+//import org.springframework.http.server.reactive.ServerHttpResponse;
+//import org.springframework.stereotype.Component;
+//import org.springframework.web.server.ServerWebExchange;
+//import reactor.core.publisher.Mono;
+//
+//import java.net.URLEncoder;
+///**
+// * Created with IntelliJ IDEA.
+// *
+// * @author: AI码师 关注公众号"AI码师"获取完整源码
+// * @date: 2021/11/24
+// * @description:
+// * @modifiedBy:
+// * @version: 1.0
+// */
+//@Component
+//@Slf4j
+//@RequiredArgsConstructor
+//public class SecurityGlobalFilter implements GlobalFilter, Ordered {
+//
+// @SneakyThrows
+// @Override
+// public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+//
+// ServerHttpRequest request = exchange.getRequest();
+// log.info("接受到请求地址:"+request.getURI());
+// ServerHttpResponse response = exchange.getResponse();
+// // 不是正确的的JWT不做解析处理
+// String token = request.getHeaders().getFirst(SecurityConstants.AUTHORIZATION_KEY);
+// if (StrUtil.isBlank(token) || !StrUtil.startWithIgnoreCase(token, SecurityConstants.JWT_PREFIX)) {
+// return chain.filter(exchange);
+// }
+// // 为请求追加 Same-Token 参数
+// request.mutate()
+// // 为请求追加 Same-Token 参数
+// .header(SaSameUtil.SAME_TOKEN, SaSameUtil.getToken())
+// .build();
+// //结束
+// // 解析JWT获取jti,以jti为key判断redis的黑名单列表是否存在,存在则拦截访问
+// token = StrUtil.replaceIgnoreCase(token, SecurityConstants.JWT_PREFIX, Strings.EMPTY);
+// String payload = StrUtil.toString(JWSObject.parse(token).getPayload());
+// request = exchange.getRequest().mutate()
+// .header(SecurityConstants.JWT_PAYLOAD_KEY, URLEncoder.encode(payload, "UTF-8"))
+// .build();
+// exchange = exchange.mutate().request(request).build();
+// return chain.filter(exchange);
+// }
+//
+// @Override
+// public int getOrder() {
+// return 0;
+// }
+//}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index ad9c009..2c85a3f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,6 +46,16 @@
hutool-all
${hutool-version}
+
+
+ cn.dev33
+ sa-token-redis-jackson
+ 1.37.0
+
+
+ org.apache.commons
+ commons-pool2
+