Spring Security配置多个WebSecurityConfigurerAdapter遇到的问题
有没有了解Spring Security的大佬?请教个问题,配置多个WebSecurityConfigurerAdapter
的实现,让他们使用不同的自定义认证逻辑即UserDetailsServiceImpl.loadUserByUsername()
。虽然配置不同的UserDetailsServiceImpl
但是会使用某个注入了authenticationManagerBean
的WebSecurityConfigurerAdapter
,导致所有的WebSecurityConfigurerAdapter
的实现都会使用某个UserDetailsServiceImpl
。
代码如下:
package com.xxx.xxx.web.config;
import ...;
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig {
/**
* 后台用户访问控制
*/
@Order(2)
@Configuration
public static class AdminSecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 自定义用户认证逻辑
*/
@Qualifier("adminUserDetailsServiceImpl")
@Autowired
private UserDetailsService userDetailsService;
/**
* token认证过滤器
*/
@Autowired
private JwtAuthenticationAdminTokenFilter authenticationTokenFilter;
/**
* 退出处理类
*/
@Autowired
private LogoutSuccessHandlerImpl logoutSuccessHandler;
@Bean(name = "adminAuthenticationManager")
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Autowired
@Qualifier("customAccessDeniedHandlerImpl")
private AccessDeniedHandler accessDeniedHandler;
/**
* 认证失败处理类
*/
@Autowired
private AdminAuthenticationEntryPointImpl unauthorizedHandler;
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.antMatcher("/admin/**").authorizeRequests()
.antMatchers("/admin/login").anonymous()
.anyRequest().authenticated()
.and().csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().exceptionHandling().accessDeniedHandler(accessDeniedHandler)
.and().exceptionHandling().authenticationEntryPoint(unauthorizedHandler);
// 退出登录设置退出登录成功处理器
httpSecurity.logout().logoutUrl("/admin/logout").logoutSuccessHandler(logoutSuccessHandler);
// 添加JWT filter
httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
}
/**
* 身份认证接口
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
daoAuthenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());
auth.authenticationProvider(daoAuthenticationProvider);
}
}
/**
* 用户端小程序访问控制
*/
@Order(1)
@Configuration
public static class SellerSecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 自定义用户认证逻辑
*/
@Qualifier("sellerUserDetailsServiceImpl")
@Autowired
private UserDetailsService userDetailsService;
/**
* token认证过滤器
*/
@Autowired
private JwtAuthenticationSellerTokenFilter authenticationTokenFilter;
/**
* 认证失败处理类
*/
@Autowired
private SellerAuthenticationEntryPointImpl unauthorizedHandler;
@Autowired
@Qualifier("customAccessDeniedHandlerImpl")
private AccessDeniedHandler accessDeniedHandler;
/**
* 退出处理类
*/
@Autowired
private LogoutSuccessHandlerImpl logoutSuccessHandler;
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.antMatcher("/seller/**").authorizeRequests()
.antMatchers("/seller/login").anonymous()
.anyRequest().authenticated()
.and().csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().exceptionHandling().accessDeniedHandler(accessDeniedHandler)
.and().exceptionHandling().authenticationEntryPoint(unauthorizedHandler);
// 退出登录设置退出登录成功处理器
httpSecurity.logout().logoutUrl("/seller/logout").logoutSuccessHandler(logoutSuccessHandler);
// 添加JWT filter
httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
}
/**
* 身份认证接口
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
daoAuthenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());
auth.authenticationProvider(daoAuthenticationProvider);
}
}
/**
* 用户端小程序访问控制
*/
@Order(0)
@Configuration
public static class ClientSecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 自定义用户认证逻辑
*/
@Qualifier("clientUserDetailsServiceImpl")
@Autowired
private UserDetailsService userDetailsService;
/**
* token认证过滤器
*/
@Autowired
private JwtAuthenticationClientTokenFilter authenticationTokenFilter;
/**
* 认证失败处理类
*/
@Autowired
private ClientAuthenticationEntryPointImpl unauthorizedHandler;
@Autowired
@Qualifier("customAccessDeniedHandlerImpl")
private AccessDeniedHandler accessDeniedHandler;
/**
* 退出处理类
*/
@Autowired
private LogoutSuccessHandlerImpl logoutSuccessHandler;
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.antMatcher("/client/**").authorizeRequests()
.antMatchers("/client/login").anonymous()
.anyRequest().authenticated()
.and().csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().exceptionHandling().accessDeniedHandler(accessDeniedHandler)
.and().exceptionHandling().authenticationEntryPoint(unauthorizedHandler);
// 退出登录设置退出登录成功处理器
httpSecurity.logout().logoutUrl("/client/logout").logoutSuccessHandler(logoutSuccessHandler);
// 添加JWT filter
httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
}
/**
* 身份认证接口
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
daoAuthenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());
auth.authenticationProvider(daoAuthenticationProvider);
}
}
/**
* 其他路由访问
*/
@Configuration
public static class OtherSecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 认证失败处理类
*/
@Autowired
private OtherAuthenticationEntryPointImpl unauthorizedHandler;
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
// CSRF禁用,因为不使用session,同时也会禁用了security默认的/login登录接口,除非再配置登录接口
.csrf().disable()
// 认证失败处理类
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler)
// 基于token,所以不需要session
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
// 开始过滤 其他所有 前缀的请求
.and().authorizeRequests()
.antMatchers("/captchaImage").anonymous()
// 静态资源允许GET请求访问
.antMatchers(
HttpMethod.GET,
"/*.html",
"/**/*.html",
"/**/*.css",
"/**/*.js"
).permitAll()
// 除上面外的所有请求全部需要鉴权认证
.anyRequest().authenticated()
.and().headers().frameOptions().disable();
}
/**
* swagger文档显示接口,因为接口请求被spring security拦截
* @param web
*/
@Override
public void configure(WebSecurity web) {
// allow Swagger URL to be accessed without authentication
web.ignoring().antMatchers(
//swagger api json
"/v2/api-docs",
//用来获取支持的动作
"/swagger-resources/configuration/ui",
//用来获取api-docs的URI
"/swagger-resources",
//安全选项
"/swagger-resources/configuration/security",
"/swagger-ui.html");
}
}
}
大佬们帮忙看看,不胜感激。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看了下源码试验了一下, configure(AuthenticationManagerBuilder auth)这个方法应该可以实现你的需求
OtherAuthenticationProvider实现了AuthenticationProvider(代码参考的DaoAuthenticationProvider ),ProviderManager.getProviders()方法返回的里面,就有我们自定义的OtherAuthenticationProvider,OtherAuthenticationProvider里面有userDetailsService和passwordEncoder字段,这样你就可以自己想传入什么实现就传入什么实现,
默认写死的10086
数据库的数据
都返回了token