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; } }