package com.sandu.common.security.config;
|
|
import com.sandu.common.security.JwtAccessDeniedHandler;
|
import com.sandu.common.security.JwtAuthenticationEntryPoint;
|
import com.sandu.common.security.TokenFilter;
|
import com.sandu.common.security.annotation.AnonymousAccess;
|
import com.sandu.common.security.token.TokenProvider;
|
import lombok.AllArgsConstructor;
|
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Configuration;
|
import org.springframework.http.HttpMethod;
|
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
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.config.core.GrantedAuthorityDefaults;
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
import org.springframework.web.filter.CorsFilter;
|
import org.springframework.web.method.HandlerMethod;
|
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
|
import java.util.HashSet;
|
import java.util.Map;
|
import java.util.Set;
|
|
/**
|
* 配置类
|
*
|
* @author chenjiantian
|
*/
|
@Configuration
|
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
@EnableWebSecurity
|
@AllArgsConstructor
|
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|
private final TokenProvider tokenProvider;
|
private final CorsFilter corsFilter;
|
private final SecurityProperties properties;
|
private final JwtAuthenticationEntryPoint authenticationErrorHandler;
|
private final JwtAccessDeniedHandler jwtAccessDeniedHandler;
|
private final ApplicationContext applicationContext;
|
|
@Bean
|
GrantedAuthorityDefaults grantedAuthorityDefaults() {
|
// 去除 ROLE_ 前缀
|
return new GrantedAuthorityDefaults("");
|
}
|
|
@Bean
|
public PasswordEncoder passwordEncoder() {
|
// 密码加密方式
|
return new BCryptPasswordEncoder();
|
}
|
|
@Override
|
protected void configure(HttpSecurity httpSecurity) throws Exception {
|
// 搜寻匿名标记 url: @AnonymousAccess
|
Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = applicationContext.getBean(RequestMappingHandlerMapping.class).getHandlerMethods();
|
Set<String> anonymousUrls = new HashSet<>();
|
for (Map.Entry<RequestMappingInfo, HandlerMethod> infoEntry : handlerMethodMap.entrySet()) {
|
HandlerMethod handlerMethod = infoEntry.getValue();
|
AnonymousAccess anonymousAccess = handlerMethod.getMethodAnnotation(AnonymousAccess.class);
|
if (null != anonymousAccess) {
|
anonymousUrls.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
|
}
|
}
|
httpSecurity
|
// 禁用 CSRF
|
.csrf().disable()
|
.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
|
// 授权异常
|
.exceptionHandling()
|
.authenticationEntryPoint(authenticationErrorHandler)
|
.accessDeniedHandler(jwtAccessDeniedHandler)
|
|
// 防止iframe 造成跨域
|
.and()
|
.headers()
|
.frameOptions()
|
.disable()
|
|
// 不创建会话
|
.and()
|
.sessionManagement()
|
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
|
.and()
|
.authorizeRequests()
|
// 静态资源等等
|
.antMatchers(
|
HttpMethod.GET,
|
"/*.html",
|
"/**/*.html",
|
"/**/*.css",
|
"/**/*.js",
|
"/webSocket/**"
|
).permitAll()
|
// swagger 文档
|
.antMatchers("/swagger-ui.html").permitAll()
|
.antMatchers("/swagger-resources/**").permitAll()
|
.antMatchers("/webjars/**").permitAll()
|
.antMatchers("/*/api-docs").permitAll()
|
.antMatchers("/v2/api-docs-ext").permitAll()
|
.antMatchers("/serv/vnnox/screenshot").permitAll()
|
.antMatchers("/serv/vnnox/progress").permitAll()
|
//.antMatchers("/api/wxmp/**").permitAll()
|
|
// 文件
|
.antMatchers("/avatar/**").permitAll()
|
.antMatchers("/file/**").permitAll()
|
// 阿里巴巴 druid
|
.antMatchers("/druid/**").permitAll()
|
// 放行OPTIONS请求
|
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
|
|
// 自定义匿名访问所有url放行 : 允许匿名和带权限以及登录用户访问
|
.antMatchers(anonymousUrls.toArray(new String[0])).permitAll()
|
// 所有请求都需要认证
|
.anyRequest().authenticated()
|
.and()
|
.addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
|
// .apply(securityConfigurerAdapter());
|
}
|
|
@Bean
|
public TokenFilter jwtAuthenticationTokenFilter() {
|
return new TokenFilter(tokenProvider, properties);
|
}
|
}
|