Files
senmesh-zc/src/main/java/com/senmesh/security/config/WebSecurityConfigurer.java
ran.shang 1f52669b52 fix
2026-04-08 09:26:57 +08:00

263 lines
9.9 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.senmesh.security.config;
import com.senmesh.security.ucard.UcardAuthenticationFilter;
import com.senmesh.security.ucard.UcardAuthenticationProvider;
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;
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;
import lombok.extern.slf4j.Slf4j;
/**
* security配置
*
* @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;
@Autowired(required = false)
private UcardAuthenticationProvider ucardAuthenticationProvider;
@Autowired(required = false)
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)
.authenticationProvider(mobileAuthenticationProvider)
.authenticationProvider(tokenAuthenticationProvider)
.authenticationProvider(ucardAuthenticationProvider);
;
}
@Override
public void configure(WebSecurity web) throws Exception {
String[] ignoringArray = securityProperties.getIgnoringArray();
// swagger 接口文档,不设置访问权限
if (swaggerConfig != null && swaggerConfig.isSwaggerEnable() && StringUtils.isNotBlank(SwaggerConfig.ACCESS_PREFIX)) {
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);
http.addFilterAfter(ucardAuthenticationFilter(), UpasswordAuthenticationFilter.class);
// 禁用CSRF
// http.csrf().disable();
http.csrf(c -> c.ignoringAntMatchers("/login")) // 登录接口免 CSRF
;
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);
}
}
private JwtAuthenticationTokenFilter createJwtAuthenticationTokenFilter() {
return new JwtAuthenticationTokenFilter(securityProperties);
}
/**
* 拦截器
*
* @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;
}
/**
* 手机号登录请求过滤器
*
* @param
* @return
* @throws Exception
* @author sr on 2020-06-04
*/
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);
}
/**
* 账号密码
*
* @return
* @throws Exception
* @author sr on 2021-06-22
*/
private UpasswordAuthenticationFilter upasswordAuthenticationFilter() throws Exception {
UpasswordAuthenticationFilter filter = new UpasswordAuthenticationFilter();
addHandler(filter);
return filter;
}
/**
* 临时token
*
* @return
* @throws Exception
* @author sr on 2021-06-22
*/
private TokenAuthenticationFilter tokenAuthenticationFilter() throws Exception {
TokenAuthenticationFilter filter = new TokenAuthenticationFilter();
addHandler(filter);
return filter;
}
/**
* 身份证登录
* @return
* @throws Exception
* @author sr on 2024-09-23
*/
private UcardAuthenticationFilter ucardAuthenticationFilter() throws Exception {
UcardAuthenticationFilter filter = new UcardAuthenticationFilter();
addHandler(filter);
return filter;
}
}