**在很多业务场景中,在数据库中存在多张数据表,如果是同类型的用户表,那还好办但是更多的是怎么区分开用户分别认证鉴权呢?
这里笔者遇到了这样的问题,在网上找到的答案不是很详细,经过研究最终实现了;
那么我们可以定义多个过滤器链,总的来说过滤器都是按照顺序执行的,但是我们可以做的就是放行逻辑;
比如我们定义第一个过滤器放行/admin/**,第二个过滤器放行/app/** ,那么这两个过滤器就会完美错开,该怎么写逻辑就怎么写逻辑话不多说贴出配置逻辑:
package com.rubik.merchant.config;
import com.rubik.merchant.security.admin.*;
import com.rubik.merchant.security.app.AppAuthTokenJWTFilter;
import com.rubik.merchant.security.app.AppUserAuthenticationProvider;
import com.rubik.merchant.security.app.AppUserLoginSuccessHandler;
import com.rubik.merchant.security.handler.UserAuthAccessDeniedHandler;
import com.rubik.merchant.security.handler.UserAuthenticationEntryPointHandler;
import com.rubik.merchant.security.handler.UserLoginFailureHandler;
import com.rubik.merchant.security.handler.UserLogoutSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
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.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import java.util.Arrays;
/**
* @Auther: MR.rp
* @Date: 2021/9/22 17:21
* @Description:
*/
@Configuration
public class SecurityConfig {
@Configuration
@Order(2) //这里的数字是指定优先级的,加上这个注解,数字越小优先级越高;
static class SecurityConfig01 extends WebSecurityConfigurerAdapter{
/**
* 自定义登录成功处理器
*/
@Autowired
private AdminUserLoginSuccessHandler userLoginSuccessHandler;
/**
* 自定义登录失败处理器
*/
@Autowired
private UserLoginFailureHandler userLoginFailureHandler;
/**
* 自定义注销成功处理器
*/
@Autowired
private UserLogoutSuccessHandler userLogoutSuccessHandler;
/**
* 自定义暂无权限处理器
*/
@Autowired
private UserAuthAccessDeniedHandler userAuthAccessDeniedHandler;
/**
* 自定义未登录的处理器
*/
@Autowired
private UserAuthenticationEntryPointHandler userAuthenticationEntryPointHandler;
/**
* 自定义登录逻辑验证器
*/
@Autowired
private AdminUserAuthenticationProvider userAuthenticationProvider;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/admin/**").
authorizeRequests()
// 不进行权限验证的请求或资源(从配置文件中读取)
// .antMatchers(JWTConfig.antMatchers.split(",")).permitAll()
// 其他的需要登陆后才能访问
.anyRequest().authenticated()
.and()
// 配置未登录自定义处理类
.httpBasic().authenticationEntryPoint(userAuthenticationEntryPointHandler)
.and()
// 配置登录地址
.formLogin()
// .loginPage("/index.html")
.loginProcessingUrl("/admin/login")
// 配置登录成功自定义处理类
.successHandler(userLoginSuccessHandler)
// 配置登录失败自定义处理类
.failureHandler(userLoginFailureHandler)
.and()
// 配置登出地址
.logout()
.logoutUrl("/logout/admin")
// 配置用户登出自定义处理类
.logoutSuccessHandler(userLogoutSuccessHandler)
.and()
// 配置没有权限自定义处理类
.exceptionHandling().accessDeniedHandler(userAuthAccessDeniedHandler)
.and()
// 开启跨域
.cors().configurationSource(corsConfigurationSource())
.and()
// 取消跨站请求伪造防护
.csrf().disable();
// 基于Token不需要session
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// 禁用缓存
http.headers().cacheControl();
// 添加JWT过滤器
http.addFilter(new AdminAuthTokenJWTFilter(authenticationManager()));
}
/**
* 配置登录验证逻辑
*/
@Override
protected void configure(AuthenticationManagerBuilder auth){
//这里可启用我们自己的登陆验证逻辑
auth.authenticationProvider(userAuthenticationProvider);
}
@Bean
public CorsConfigurationSource corsConfigurationSource(){
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowedHeaders(Arrays.asList("*"));
corsConfiguration.setAllowedMethods(Arrays.asList("*"));
corsConfiguration.setAllowedOrigins(Arrays.asList("*"));
corsConfiguration.setMaxAge(3600L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**",corsConfiguration);
return source;
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/swagger-ui.html","/webjars/**","/v2/**","/swagger-resources/**","/doc.html","/file/**","/images/**");
}
}
@Configuration
@Order(1)
static class SecurityConfig02 extends WebSecurityConfigurerAdapter{
/**
* 自定义登录成功处理器
*/
@Autowired
private AppUserLoginSuccessHandler userLoginSuccessHandler;
/**
* 自定义登录失败处理器
*/
@Autowired
private UserLoginFailureHandler userLoginFailureHandler;
/**
* 自定义注销成功处理器
*/
@Autowired
private UserLogoutSuccessHandler userLogoutSuccessHandler;
/**
* 自定义暂无权限处理器
*/
@Autowired
private UserAuthAccessDeniedHandler userAuthAccessDeniedHandler;
/**
* 自定义未登录的处理器
*/
@Autowired
private UserAuthenticationEntryPointHandler userAuthenticationEntryPointHandler;
/**
* 自定义登录逻辑验证器
*/
@Autowired
private AppUserAuthenticationProvider userAuthenticationProvider;
@Autowired
private CorsConfigurationSource corsConfigurationSource;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/app/**").
authorizeRequests()
// 不进行权限验证的请求或资源(从配置文件中读取)
// .antMatchers(JWTConfig.antMatchers.split(",")).permitAll()
// 其他的需要登陆后才能访问
.anyRequest().authenticated()
.and()
// 配置未登录自定义处理类
.httpBasic().authenticationEntryPoint(userAuthenticationEntryPointHandler)
.and()
// 配置登录地址
.formLogin()
// .loginPage("/index.html")
.loginProcessingUrl("/app/login")
// 配置登录成功自定义处理类
.successHandler(userLoginSuccessHandler)
// 配置登录失败自定义处理类
.failureHandler(userLoginFailureHandler)
.and()
// 配置登出地址
.logout()
.logoutUrl("/app/logout")
// 配置用户登出自定义处理类
.logoutSuccessHandler(userLogoutSuccessHandler)
.and()
// 配置没有权限自定义处理类
.exceptionHandling().accessDeniedHandler(userAuthAccessDeniedHandler)
.and()
// 开启跨域
.cors().configurationSource(corsConfigurationSource)
.and()
// 取消跨站请求伪造防护
.csrf().disable();
// 基于Token不需要session
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// 禁用缓存
http.headers().cacheControl();
// 添加JWT过滤器
http.addFilter(new AppAuthTokenJWTFilter(authenticationManager()));
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/swagger-ui.html","/webjars/**","/v2/**","/swagger-resources/**","/doc.html","/file/**","/images/**");
}
/**
* 配置登录验证逻辑
*/
@Override
protected void configure(AuthenticationManagerBuilder auth){
auth.authenticationProvider(userAuthenticationProvider);
}
}
}
这里写了很多自定义的逻辑,需要自己实现下,大体的流程是这样,有什么更好的办法也可以讨论和学习一下哦