搞了很久终于把配置全部弄完了,从登录验权限,token缓存和验证,到资源白名单验证和openapi 一系列配置到此完成了
注意点:
1、springboot mvc 配置WebMvcConfig 不能继承 WebMvcConfigurationSupport,否则会和Security的映射冲突,如果需要配置,则需要继承接口 WebMvcConfigurer,就不会与他冲突
资源白名单配置
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
private final static String web_file_whiteList = "/web_file_whitelist.properties";
private Resource resource = new ClassPathResource(web_file_whiteList);
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
Properties props = null;
try {
props = PropertiesLoaderUtils.loadProperties(resource);
} catch (IOException e) {
e.printStackTrace();
}
if (props != null){
for(String key : props.stringPropertyNames()){
String value = (String)props.getProperty(key);
registry.addResourceHandler(key).addResourceLocations(value);
}
}
}
}
资源地址
web_file_whitelist.propertie 参数
#mvc文件资源访问白名单 key 访问路径path value 访问目录
/img/**=classpath:/templates/img/
/static/**=classpath:/static/
/templates/**=classpath:/templates/
cors跨域配置
具体根据自己设置,设置header,设置访问路径等
/**
* @author hmy
* desc: cors跨域配置
* @date 2021/11/8 11:10
*/
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**") // 允许跨域访问的路径
.allowedOrigins("*") // 允许跨域访问的源
.allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") // 允许请求方法
.maxAge(168000) // 预检间隔时间
.allowedHeaders("*") // 允许头部设置
.allowCredentials(true); // 是否发送cookie
}
}
SecurityConfig 权限配置类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserCache;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.core.io.Resource;
import java.io.IOException;
import java.util.Properties;
/**
* @author hmy
* desc: security权限配置类
* @date 2021/11/5 16:46
*/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final String whiteFileName = "/security_whitelist.properties";//白名单放行文件
private static final String whiteDirName ="security_whitelist_dir.properties";//静态资源放行目录
@Autowired
private AjaxAuthenticationEntryPoint authenticationEntryPoint; // 未登陆时返回 JSON 格式的数据给前端(否则为 html)
@Autowired
private AjaxAuthenticationSuccessHandler authenticationSuccessHandler; // 登录成功返回的 JSON 格式数据给前端(否则为 html)
@Autowired
private AjaxAuthenticationFailureHandler authenticationFailureHandler; // 登录失败返回的 JSON 格式数据给前端(否则为 html)
@Autowired
private AjaxLogoutSuccessHandler logoutSuccessHandler; // 注销成功返回的 JSON 格式数据给前端(否则为 登录时的 html)
@Autowired
private AjaxAccessDeniedHandler accessDeniedHandler; // 无权访问返回的 JSON 格式数据给前端(否则为 403 html 页面)
@Autowired
private UserDetailsService userDetailsService;//用户详情服务
//jwt 服务
@Autowired
private JwtInfoService jwtInfoService;
//认证句柄
@Autowired
private AuthenticationHandler authenticationHandler;
@Autowired
private SecurityWhitelistHandler whitelistHandler;
@Autowired
private UserCache userCache;
/**
* 权限访问白名单管理
* @return
*/
@Bean
public static Resource securityWhitelistResource() {
return new ClassPathResource(whiteFileName);
}
//配置认证登录
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
// 使用自定义登录身份认证组件
auth.authenticationProvider(new JwtAuthenticationProvider(userDetailsService, jwtInfoService, authenticationHandler,userCache));
//这东西千万不能忘
auth.userDetailsService(userDetailsService)
.passwordEncoder(new BCryptPasswordEncoder());
}
//http访问接口登录
@Override
protected void configure(HttpSecurity http) throws Exception {
//关闭csrf
//whitelistHandler.handle(http).cors().and().csrf().disable();//关闭csrf每条都必须待token
//请求权限
// .authorizeRequests()
// // 方形白名单
// .antMatchers("/js/**","/logon","/**/*.html","/apidoc"
// ,"/api/file/**","/img/**").permitAll()
// .authorizeRequests().anyRequest().authenticated();// 其他所有请求需要身份认证
whitelistHandler.handle(http);
//资源设置
// MyRequestCache myRequestCache = new MyRequestCache();
// myRequestCache.addMatcher("/img/**").addMatcher("/static/**").addEnd();
// http.setSharedObject(RequestCache.class, myRequestCache);
//增加数据过滤登陆权限验证
http.addFilter(new JwtVerifyFilter(super.authenticationManager(), jwtInfoService,
new ClassPathResource(whiteFileName)))
//未登陆返回
.httpBasic().authenticationEntryPoint(authenticationEntryPoint);
//注销
http.logout().logoutSuccessHandler(logoutSuccessHandler);
//无权限访问
http.exceptionHandling().accessDeniedHandler(accessDeniedHandler); // 无权访问 JSON 格式的数据
//用户认证方式 --》自定义认证token方式
http.addFilterAt(myAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);//增加请求数据格式
http.cors().and().csrf().disable();//关闭csrf每条都必须待token访问
}
@Override
public void configure(WebSecurity web) throws Exception {
Resource resource = new ClassPathResource(whiteDirName);
Properties props = null;
try {
props = PropertiesLoaderUtils.loadProperties(resource);
} catch (IOException e) {
e.printStackTrace();
}
if (props != null){
String[] liString = new String[props.values().size()];
props.values().toArray(liString);
web.ignoring().antMatchers(liString);
// web.ignoring().antMatchers("/css/**", "/js/**","/img/**");
}
// 设置拦截忽略文件夹,可以对静态资源放行
}
/**
* 登陆权限验证
* @return
* @throws Exception
*/
@Bean
MyAuthenticationFilter myAuthenticationFilter() throws Exception {
MyAuthenticationFilter filter = new MyAuthenticationFilter(jwtInfoService);
//设置要处理的登陆请求的路径
filter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/api/admin/login", "POST"));
filter.setAuthenticationSuccessHandler(authenticationSuccessHandler);
filter.setAuthenticationFailureHandler(authenticationFailureHandler);
filter.setAuthenticationManager(authenticationManagerBean());
return filter;
}
}
这里面很多我自己的函数,具体配置按照官方的配置来吧,可以参考配置目录,别自己copy代码,自己思考下