2025-12-29 16:06:48 +08:00
|
|
|
|
package com.senmesh.security.config;
|
2025-06-11 09:42:13 +08:00
|
|
|
|
|
2025-12-29 16:06:48 +08:00
|
|
|
|
import com.senmesh.security.ucard.UcardAuthenticationFilter;
|
|
|
|
|
|
import com.senmesh.security.ucard.UcardAuthenticationProvider;
|
2025-06-11 09:42:13 +08:00
|
|
|
|
import org.apache.commons.lang3.ArrayUtils;
|
|
|
|
|
|
import org.apache.commons.lang3.BooleanUtils;
|
|
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
|
import org.springframework.security.access.AccessDecisionManager;
|
|
|
|
|
|
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.builders.WebSecurity;
|
|
|
|
|
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
|
|
|
|
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
|
|
|
|
|
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
|
|
|
|
|
import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter;
|
|
|
|
|
|
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
|
|
|
|
|
|
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
|
|
|
|
|
|
import org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
|
|
|
|
|
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
|
|
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
|
2025-12-29 16:06:48 +08:00
|
|
|
|
import com.senmesh.security.access.intercept.FilterSecurityInterceptor;
|
|
|
|
|
|
import com.senmesh.security.handle.MyAuthenctiationFailureHandler;
|
|
|
|
|
|
import com.senmesh.security.handle.MyLoginSuccessHandler;
|
|
|
|
|
|
import com.senmesh.security.handle.MyLoginUrlAuthenticationEntryPoint;
|
|
|
|
|
|
import com.senmesh.security.handle.MyLogoutSuccessHandler;
|
|
|
|
|
|
import com.senmesh.security.jwt.JwtAuthenticationTokenFilter;
|
|
|
|
|
|
import com.senmesh.security.mobile.MobileAuthenticationFilter;
|
|
|
|
|
|
import com.senmesh.security.mobile.MobileAuthenticationProvider;
|
|
|
|
|
|
import com.senmesh.security.social.service.StandardAuthorizationCodeTokenResponseClient;
|
|
|
|
|
|
import com.senmesh.security.social.service.StandardOAuth2UserService;
|
|
|
|
|
|
import com.senmesh.security.social.service.StandardOauth2AuthorizationRequestResolver;
|
|
|
|
|
|
import com.senmesh.security.temptoken.TokenAuthenticationFilter;
|
|
|
|
|
|
import com.senmesh.security.temptoken.TokenAuthenticationProvider;
|
|
|
|
|
|
import com.senmesh.security.upassword.UpasswordAuthenticationFilter;
|
|
|
|
|
|
import com.senmesh.security.upassword.UpasswordAuthenticationProvider;
|
|
|
|
|
|
import com.senmesh.swagger.config.SwaggerConfig;
|
|
|
|
|
|
import com.senmesh.usercenter.user.login.service.UserLoginService;
|
|
|
|
|
|
import com.senmesh.usercenter.websocket.util.WebSocketUtils;
|
2025-06-11 09:42:13 +08:00
|
|
|
|
|
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* security配置
|
2025-08-12 10:41:06 +08:00
|
|
|
|
*
|
2025-06-11 09:42:13 +08:00
|
|
|
|
* @author on 2019-11-05
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Slf4j
|
|
|
|
|
|
@Component
|
|
|
|
|
|
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private SecurityProperties securityProperties;
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private MyLogoutSuccessHandler myLogoutSuccessHandler;
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private MyLoginSuccessHandler myLoginSuccessHandler;
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private MyAuthenctiationFailureHandler myAuthenctiationFailureHandler;
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private FilterInvocationSecurityMetadataSource securityMetadataSource;
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private AccessDecisionManager accessDecisionManager;
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired(required = false)
|
|
|
|
|
|
private UpasswordAuthenticationProvider upasswordAuthenticationProvider;
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired(required = false)
|
|
|
|
|
|
private MobileAuthenticationProvider mobileAuthenticationProvider;
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired(required = false)
|
|
|
|
|
|
private TokenAuthenticationProvider tokenAuthenticationProvider;
|
|
|
|
|
|
|
2025-08-12 10:41:06 +08:00
|
|
|
|
@Autowired(required = false)
|
|
|
|
|
|
private UcardAuthenticationProvider ucardAuthenticationProvider;
|
|
|
|
|
|
|
2026-02-02 18:16:03 +08:00
|
|
|
|
@Autowired(required = false)
|
2025-06-11 09:42:13 +08:00
|
|
|
|
private SwaggerConfig swaggerConfig;
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired(required = false)
|
|
|
|
|
|
private UserLoginService userLoginService;
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired(required = false)
|
|
|
|
|
|
private ClientRegistrationRepository standardClientRegistrationRepository;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
|
|
|
|
|
// 添加cas认证提供者
|
|
|
|
|
|
auth.authenticationProvider(upasswordAuthenticationProvider)
|
2025-08-12 10:41:06 +08:00
|
|
|
|
.authenticationProvider(mobileAuthenticationProvider)
|
|
|
|
|
|
.authenticationProvider(tokenAuthenticationProvider)
|
|
|
|
|
|
.authenticationProvider(ucardAuthenticationProvider);
|
2025-06-11 09:42:13 +08:00
|
|
|
|
;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void configure(WebSecurity web) throws Exception {
|
|
|
|
|
|
String[] ignoringArray = securityProperties.getIgnoringArray();
|
|
|
|
|
|
// swagger 接口文档,不设置访问权限
|
2026-02-02 18:16:03 +08:00
|
|
|
|
if (swaggerConfig != null && swaggerConfig.isSwaggerEnable() && StringUtils.isNotBlank(SwaggerConfig.ACCESS_PREFIX)) {
|
2025-06-11 09:42:13 +08:00
|
|
|
|
ignoringArray = ArrayUtils.addAll(ignoringArray, SwaggerConfig.ACCESS_PREFIX.split(","));
|
|
|
|
|
|
}
|
|
|
|
|
|
// websocket
|
|
|
|
|
|
if (StringUtils.isNotBlank(WebSocketUtils.getPath())) {
|
|
|
|
|
|
ignoringArray = ArrayUtils.add(ignoringArray, WebSocketUtils.getPath());
|
|
|
|
|
|
}
|
|
|
|
|
|
// 忽略的资源,直接跳过spring security权限校验
|
|
|
|
|
|
web.ignoring()
|
|
|
|
|
|
.antMatchers(ignoringArray)/*.antMatchers(securityProperties.getAnonymousArray())*/;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
protected void configure(HttpSecurity http) throws Exception {
|
|
|
|
|
|
log.info("------WebSecurityConfigurer configure");
|
|
|
|
|
|
http
|
|
|
|
|
|
.logout()
|
|
|
|
|
|
.logoutSuccessHandler(myLogoutSuccessHandler).and()
|
|
|
|
|
|
// 自定义认证失败处理器
|
|
|
|
|
|
.exceptionHandling().authenticationEntryPoint(
|
|
|
|
|
|
new MyLoginUrlAuthenticationEntryPoint(securityProperties.getLoginPage()))
|
|
|
|
|
|
.and();
|
|
|
|
|
|
|
|
|
|
|
|
if (BooleanUtils.isTrue(securityProperties.getOauth2().getEnable())) {
|
|
|
|
|
|
// oauth2
|
|
|
|
|
|
http.oauth2Login()
|
|
|
|
|
|
.authorizationEndpoint()
|
|
|
|
|
|
.authorizationRequestResolver(
|
|
|
|
|
|
new StandardOauth2AuthorizationRequestResolver(
|
|
|
|
|
|
this.standardClientRegistrationRepository,
|
|
|
|
|
|
OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI))
|
|
|
|
|
|
.and()
|
|
|
|
|
|
.tokenEndpoint()
|
|
|
|
|
|
.accessTokenResponseClient(new StandardAuthorizationCodeTokenResponseClient())
|
|
|
|
|
|
.and()
|
|
|
|
|
|
.userInfoEndpoint().userService(new StandardOAuth2UserService()).and()
|
|
|
|
|
|
.failureHandler(myAuthenctiationFailureHandler)
|
|
|
|
|
|
.successHandler(myLoginSuccessHandler).and();
|
|
|
|
|
|
}
|
|
|
|
|
|
http.addFilterAfter(upasswordAuthenticationFilter(),
|
|
|
|
|
|
UsernamePasswordAuthenticationFilter.class);
|
|
|
|
|
|
http.addFilterAfter(mobileAuthenticationFilter(), UpasswordAuthenticationFilter.class);
|
|
|
|
|
|
http.addFilterAfter(tokenAuthenticationFilter(), UpasswordAuthenticationFilter.class);
|
2025-08-12 10:41:06 +08:00
|
|
|
|
http.addFilterAfter(ucardAuthenticationFilter(), UpasswordAuthenticationFilter.class);
|
|
|
|
|
|
|
2025-06-11 09:42:13 +08:00
|
|
|
|
|
|
|
|
|
|
// 禁用CSRF
|
2026-03-27 18:28:05 +08:00
|
|
|
|
// http.csrf().disable();
|
2025-06-11 09:42:13 +08:00
|
|
|
|
http.headers().frameOptions().deny();
|
|
|
|
|
|
http.headers().xssProtection().block(true);
|
|
|
|
|
|
http.headers().contentTypeOptions();
|
|
|
|
|
|
|
|
|
|
|
|
// 拦截器
|
|
|
|
|
|
FilterSecurityInterceptor securityInterceptor = createFilterSecurityInterceptor();
|
|
|
|
|
|
http.addFilterAfter(securityInterceptor,
|
|
|
|
|
|
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.class);
|
|
|
|
|
|
|
|
|
|
|
|
http.setSharedObject(FilterSecurityInterceptor.class, securityInterceptor);
|
|
|
|
|
|
|
|
|
|
|
|
// 启用jwt
|
|
|
|
|
|
if (Boolean.TRUE.equals(securityProperties.getJwt().getEnable())) {
|
|
|
|
|
|
JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter =
|
|
|
|
|
|
createJwtAuthenticationTokenFilter();
|
|
|
|
|
|
http.addFilterAfter(jwtAuthenticationTokenFilter,
|
|
|
|
|
|
AnonymousAuthenticationFilter.class);
|
|
|
|
|
|
// 禁用session
|
|
|
|
|
|
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2025-08-12 10:41:06 +08:00
|
|
|
|
|
2025-06-11 09:42:13 +08:00
|
|
|
|
private JwtAuthenticationTokenFilter createJwtAuthenticationTokenFilter() {
|
|
|
|
|
|
return new JwtAuthenticationTokenFilter(securityProperties);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 拦截器
|
2025-08-12 10:41:06 +08:00
|
|
|
|
*
|
2025-06-11 09:42:13 +08:00
|
|
|
|
* @return
|
|
|
|
|
|
* @throws Exception
|
|
|
|
|
|
* @author sr on 2019-11-28
|
|
|
|
|
|
*/
|
|
|
|
|
|
private FilterSecurityInterceptor createFilterSecurityInterceptor() throws Exception {
|
|
|
|
|
|
FilterSecurityInterceptor securityInterceptor = new FilterSecurityInterceptor();
|
|
|
|
|
|
securityInterceptor.setSecurityMetadataSource(securityMetadataSource);
|
|
|
|
|
|
securityInterceptor.setAccessDecisionManager(accessDecisionManager);
|
|
|
|
|
|
// httpSecurity中shareobject共用的authenticationBuilder
|
|
|
|
|
|
securityInterceptor.setAuthenticationManager(this.authenticationManagerBean());
|
|
|
|
|
|
securityInterceptor.setUserLoginService(userLoginService);
|
|
|
|
|
|
securityInterceptor.afterPropertiesSet();
|
|
|
|
|
|
return securityInterceptor;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 手机号登录请求过滤器
|
2025-08-12 10:41:06 +08:00
|
|
|
|
*
|
2026-03-27 18:28:05 +08:00
|
|
|
|
* @param
|
2025-06-11 09:42:13 +08:00
|
|
|
|
* @return
|
|
|
|
|
|
* @throws Exception
|
2025-08-12 10:41:06 +08:00
|
|
|
|
* @author sr on 2020-06-04
|
2025-06-11 09:42:13 +08:00
|
|
|
|
*/
|
|
|
|
|
|
private MobileAuthenticationFilter mobileAuthenticationFilter() throws Exception {
|
|
|
|
|
|
MobileAuthenticationFilter filter = new MobileAuthenticationFilter();
|
|
|
|
|
|
addHandler(filter);
|
|
|
|
|
|
return filter;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void addHandler(AbstractAuthenticationProcessingFilter filter) throws Exception {
|
|
|
|
|
|
filter.setAuthenticationManager(this.authenticationManagerBean());
|
|
|
|
|
|
filter.setAuthenticationSuccessHandler(myLoginSuccessHandler);
|
|
|
|
|
|
filter.setAuthenticationFailureHandler(myAuthenctiationFailureHandler);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 账号密码
|
2025-08-12 10:41:06 +08:00
|
|
|
|
*
|
2025-06-11 09:42:13 +08:00
|
|
|
|
* @return
|
|
|
|
|
|
* @throws Exception
|
2025-08-12 10:41:06 +08:00
|
|
|
|
* @author sr on 2021-06-22
|
2025-06-11 09:42:13 +08:00
|
|
|
|
*/
|
|
|
|
|
|
private UpasswordAuthenticationFilter upasswordAuthenticationFilter() throws Exception {
|
|
|
|
|
|
UpasswordAuthenticationFilter filter = new UpasswordAuthenticationFilter();
|
|
|
|
|
|
addHandler(filter);
|
|
|
|
|
|
return filter;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 临时token
|
2025-08-12 10:41:06 +08:00
|
|
|
|
*
|
2025-06-11 09:42:13 +08:00
|
|
|
|
* @return
|
|
|
|
|
|
* @throws Exception
|
2025-08-12 10:41:06 +08:00
|
|
|
|
* @author sr on 2021-06-22
|
2025-06-11 09:42:13 +08:00
|
|
|
|
*/
|
|
|
|
|
|
private TokenAuthenticationFilter tokenAuthenticationFilter() throws Exception {
|
|
|
|
|
|
TokenAuthenticationFilter filter = new TokenAuthenticationFilter();
|
|
|
|
|
|
addHandler(filter);
|
|
|
|
|
|
return filter;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-27 18:28:05 +08:00
|
|
|
|
|
2025-06-11 09:42:13 +08:00
|
|
|
|
|
2025-08-12 10:41:06 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 身份证登录
|
|
|
|
|
|
* @return
|
|
|
|
|
|
* @throws Exception
|
|
|
|
|
|
* @author sr on 2024-09-23
|
|
|
|
|
|
*/
|
|
|
|
|
|
private UcardAuthenticationFilter ucardAuthenticationFilter() throws Exception {
|
|
|
|
|
|
UcardAuthenticationFilter filter = new UcardAuthenticationFilter();
|
|
|
|
|
|
addHandler(filter);
|
|
|
|
|
|
return filter;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-06-11 09:42:13 +08:00
|
|
|
|
}
|