mirror of
https://gitee.com/log4j/pig.git
synced 2024-12-23 05:00:23 +08:00
refactor(satoken): 修改 common-log 、common-data 适配 sa-token api
This commit is contained in:
parent
48da1acd2a
commit
5fbf844d99
@ -7,6 +7,7 @@ package com.pig4cloud.pig.auth.support.filter;
|
|||||||
* @date 2024/4/3
|
* @date 2024/4/3
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.http.ContentType;
|
import cn.hutool.http.ContentType;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
@ -24,7 +25,6 @@ import jakarta.servlet.http.HttpServletResponse;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.filter.OncePerRequestFilter;
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ public class ValidateCodeFilter extends OncePerRequestFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 如果登录URL 但是刷新token的请求,直接向下执行
|
// 如果登录URL 但是刷新token的请求,直接向下执行
|
||||||
String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE);
|
String grantType = request.getParameter(SaOAuth2Consts.Param.grant_type);
|
||||||
if (StrUtil.equals(SecurityConstants.REFRESH_TOKEN, grantType)) {
|
if (StrUtil.equals(SecurityConstants.REFRESH_TOKEN, grantType)) {
|
||||||
filterChain.doFilter(request, response);
|
filterChain.doFilter(request, response);
|
||||||
return;
|
return;
|
||||||
|
@ -1,158 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* Redistributions of source code must retain the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
|
||||||
* contributors may be used to endorse or promote products derived from
|
|
||||||
* this software without specific prior written permission.
|
|
||||||
* Author: lengleng (wangiegie@gmail.com)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.pig4cloud.pig.bootstrap;
|
|
||||||
|
|
||||||
import com.pig4cloud.pig.auth.support.core.PigDaoAuthenticationProvider;
|
|
||||||
import com.pig4cloud.pig.auth.support.filter.PasswordDecoderFilter;
|
|
||||||
import com.pig4cloud.pig.auth.support.filter.ValidateCodeFilter;
|
|
||||||
import com.pig4cloud.pig.auth.support.handler.PigAuthenticationFailureEventHandler;
|
|
||||||
import com.pig4cloud.pig.auth.support.handler.PigAuthenticationSuccessEventHandler;
|
|
||||||
import com.pig4cloud.pig.auth.support.password.OAuth2ResourceOwnerPasswordAuthenticationProvider;
|
|
||||||
import com.pig4cloud.pig.auth.support.sms.OAuth2ResourceOwnerSmsAuthenticationProvider;
|
|
||||||
import com.pig4cloud.pig.common.core.constant.SecurityConstants;
|
|
||||||
import com.pig4cloud.pig.common.security.component.PermitAllUrlProperties;
|
|
||||||
import com.pig4cloud.pig.common.security.component.PigBearerTokenExtractor;
|
|
||||||
import com.pig4cloud.pig.common.security.component.ResourceAuthExceptionEntryPoint;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.core.Ordered;
|
|
||||||
import org.springframework.core.annotation.Order;
|
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
|
||||||
import org.springframework.security.config.Customizer;
|
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
|
||||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
|
||||||
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
|
|
||||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
|
|
||||||
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
|
|
||||||
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
|
|
||||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator;
|
|
||||||
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
|
|
||||||
import org.springframework.security.web.DefaultSecurityFilterChain;
|
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
|
||||||
import org.springframework.security.web.authentication.AuthenticationConverter;
|
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
|
||||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lengleng 认证授权服务器配置
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class PigBootSecurityServerConfiguration {
|
|
||||||
|
|
||||||
private final ResourceAuthExceptionEntryPoint resourceAuthExceptionEntryPoint;
|
|
||||||
|
|
||||||
private final OpaqueTokenIntrospector customOpaqueTokenIntrospector;
|
|
||||||
|
|
||||||
private final AuthenticationConverter accessTokenRequestConverter;
|
|
||||||
|
|
||||||
private final OAuth2AuthorizationService authorizationService;
|
|
||||||
|
|
||||||
private final PigBearerTokenExtractor pigBearerTokenExtractor;
|
|
||||||
|
|
||||||
private final PasswordDecoderFilter passwordDecoderFilter;
|
|
||||||
|
|
||||||
private final OAuth2TokenGenerator oAuth2TokenGenerator;
|
|
||||||
|
|
||||||
private final ValidateCodeFilter validateCodeFilter;
|
|
||||||
|
|
||||||
private final PermitAllUrlProperties permitAllUrl;
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
|
||||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
|
||||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer();
|
|
||||||
|
|
||||||
// 增加验证码过滤器
|
|
||||||
http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class);
|
|
||||||
// 增加密码解密过滤器
|
|
||||||
http.addFilterBefore(passwordDecoderFilter, UsernamePasswordAuthenticationFilter.class);
|
|
||||||
|
|
||||||
// 认证服务器配置
|
|
||||||
http.with(authorizationServerConfigurer.tokenEndpoint((tokenEndpoint) -> {// 个性化认证授权端点
|
|
||||||
tokenEndpoint.accessTokenRequestConverter(accessTokenRequestConverter) // 注入自定义的授权认证Converter
|
|
||||||
.accessTokenResponseHandler(new PigAuthenticationSuccessEventHandler()) // 登录成功处理器
|
|
||||||
.errorResponseHandler(new PigAuthenticationFailureEventHandler());// 登录失败处理器
|
|
||||||
}).clientAuthentication(oAuth2ClientAuthenticationConfigurer -> // 个性化客户端认证
|
|
||||||
oAuth2ClientAuthenticationConfigurer.errorResponseHandler(new PigAuthenticationFailureEventHandler()))// 处理客户端认证异常
|
|
||||||
, Customizer.withDefaults())
|
|
||||||
.with(authorizationServerConfigurer.authorizationService(authorizationService)// redis存储token的实现
|
|
||||||
.authorizationServerSettings(
|
|
||||||
AuthorizationServerSettings.builder().issuer(SecurityConstants.PROJECT_LICENSE).build()),
|
|
||||||
Customizer.withDefaults());
|
|
||||||
|
|
||||||
// 资源服务器配置
|
|
||||||
AntPathRequestMatcher[] requestMatchers = permitAllUrl.getUrls()
|
|
||||||
.stream()
|
|
||||||
.map(AntPathRequestMatcher::new)
|
|
||||||
.toList()
|
|
||||||
.toArray(new AntPathRequestMatcher[] {});
|
|
||||||
|
|
||||||
http.authorizeHttpRequests(authorizeRequests -> authorizeRequests.requestMatchers(requestMatchers)
|
|
||||||
.permitAll()
|
|
||||||
.anyRequest()
|
|
||||||
.authenticated())
|
|
||||||
.oauth2ResourceServer(
|
|
||||||
oauth2 -> oauth2.opaqueToken(token -> token.introspector(customOpaqueTokenIntrospector))
|
|
||||||
.authenticationEntryPoint(resourceAuthExceptionEntryPoint)
|
|
||||||
.bearerTokenResolver(pigBearerTokenExtractor))
|
|
||||||
.exceptionHandling(configurer -> configurer.authenticationEntryPoint(resourceAuthExceptionEntryPoint))
|
|
||||||
.headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
|
|
||||||
.csrf(AbstractHttpConfigurer::disable);
|
|
||||||
|
|
||||||
http.with(authorizationServerConfigurer.authorizationService(authorizationService)// redis存储token的实现
|
|
||||||
.authorizationServerSettings(
|
|
||||||
AuthorizationServerSettings.builder().issuer(SecurityConstants.PROJECT_LICENSE).build()),
|
|
||||||
Customizer.withDefaults());
|
|
||||||
|
|
||||||
DefaultSecurityFilterChain securityFilterChain = http.build();
|
|
||||||
|
|
||||||
// 注入自定义授权模式实现
|
|
||||||
addCustomOAuth2GrantAuthenticationProvider(http);
|
|
||||||
return securityFilterChain;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 注入授权模式实现提供方
|
|
||||||
* <p>
|
|
||||||
* 1. 密码模式 </br>
|
|
||||||
* 2. 短信登录 </br>
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private void addCustomOAuth2GrantAuthenticationProvider(HttpSecurity http) {
|
|
||||||
AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class);
|
|
||||||
OAuth2AuthorizationService authorizationService = http.getSharedObject(OAuth2AuthorizationService.class);
|
|
||||||
|
|
||||||
OAuth2ResourceOwnerPasswordAuthenticationProvider resourceOwnerPasswordAuthenticationProvider = new OAuth2ResourceOwnerPasswordAuthenticationProvider(
|
|
||||||
authenticationManager, authorizationService, oAuth2TokenGenerator);
|
|
||||||
|
|
||||||
OAuth2ResourceOwnerSmsAuthenticationProvider resourceOwnerSmsAuthenticationProvider = new OAuth2ResourceOwnerSmsAuthenticationProvider(
|
|
||||||
authenticationManager, authorizationService, oAuth2TokenGenerator);
|
|
||||||
|
|
||||||
// 处理 UsernamePasswordAuthenticationToken
|
|
||||||
http.authenticationProvider(new PigDaoAuthenticationProvider());
|
|
||||||
// 处理 OAuth2ResourceOwnerPasswordAuthenticationToken
|
|
||||||
http.authenticationProvider(resourceOwnerPasswordAuthenticationProvider);
|
|
||||||
// 处理 OAuth2ResourceOwnerSmsAuthenticationToken
|
|
||||||
http.authenticationProvider(resourceOwnerSmsAuthenticationProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -49,14 +49,10 @@
|
|||||||
<groupId>com.pig4cloud</groupId>
|
<groupId>com.pig4cloud</groupId>
|
||||||
<artifactId>pig-upms-api</artifactId>
|
<artifactId>pig-upms-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--安全依赖获取上下文信息-->
|
<!-- 安全框架 API 方便获取用户信息-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.security</groupId>
|
<groupId>cn.dev33</groupId>
|
||||||
<artifactId>spring-security-core</artifactId>
|
<artifactId>sa-token-core</artifactId>
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.security</groupId>
|
|
||||||
<artifactId>spring-security-oauth2-core</artifactId>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.pig4cloud.pig.common.log.util;
|
package com.pig4cloud.pig.common.log.util;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
import cn.hutool.core.util.URLUtil;
|
import cn.hutool.core.util.URLUtil;
|
||||||
@ -33,8 +34,6 @@ import org.springframework.expression.Expression;
|
|||||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.security.core.Authentication;
|
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
|
||||||
import org.springframework.web.context.request.RequestContextHolder;
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
|
||||||
@ -75,11 +74,12 @@ public class SysLogUtils {
|
|||||||
* @return username
|
* @return username
|
||||||
*/
|
*/
|
||||||
private String getUsername() {
|
private String getUsername() {
|
||||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
|
||||||
if (authentication == null) {
|
Object username = StpUtil.getLoginIdDefaultNull();
|
||||||
|
if (Objects.isNull(username)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return authentication.getName();
|
return username.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,11 +62,10 @@
|
|||||||
<artifactId>spring-webmvc</artifactId>
|
<artifactId>spring-webmvc</artifactId>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--security 依赖-->
|
<!-- 安全框架 API 方便获取用户信息-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.security</groupId>
|
<groupId>cn.dev33</groupId>
|
||||||
<artifactId>spring-security-core</artifactId>
|
<artifactId>sa-token-core</artifactId>
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.pig4cloud</groupId>
|
<groupId>com.pig4cloud</groupId>
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
package com.pig4cloud.pig.common.mybatis.config;
|
package com.pig4cloud.pig.common.mybatis.config;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
||||||
import com.pig4cloud.pig.common.core.constant.CommonConstants;
|
import com.pig4cloud.pig.common.core.constant.CommonConstants;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.ibatis.reflection.MetaObject;
|
import org.apache.ibatis.reflection.MetaObject;
|
||||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
|
||||||
import org.springframework.security.core.Authentication;
|
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Optional;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MybatisPlus 自动填充配置
|
* MybatisPlus 自动填充配置
|
||||||
@ -74,21 +72,16 @@ public class MybatisPlusMetaObjectHandler implements MetaObjectHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取 spring security 当前的用户名
|
* 获取用户名
|
||||||
* @return 当前用户名
|
*
|
||||||
|
* @return {@link String }
|
||||||
*/
|
*/
|
||||||
private String getUserName() {
|
private String getUserName() {
|
||||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
Object username = StpUtil.getLoginIdDefaultNull();
|
||||||
// 匿名接口直接返回
|
if (Objects.isNull(username)) {
|
||||||
if (authentication instanceof AnonymousAuthenticationToken) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
return username.toString();
|
||||||
if (Optional.ofNullable(authentication).isPresent()) {
|
|
||||||
return authentication.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user