Spring Security 具有不同用户详细信息的多个 HTTPSecurity 服务在 Spring Boot 中不起作用
Posted
技术标签:
【中文标题】Spring Security 具有不同用户详细信息的多个 HTTPSecurity 服务在 Spring Boot 中不起作用【英文标题】:Spring Security Multiple HTTPSecurity with Different User Details Services Not Working in Spring Boot 【发布时间】:2020-01-01 08:11:37 【问题描述】:我有两种类型的用户:应用程序用户和最终用户,我为这些用户设置了单独的表格。现在,我想对这两个表应用安全性。
我为应用程序用户提供了 UserDetailsService 的自定义实现:
@Component("applicationUserDetailsService")
public class ApplicationUserDetailsService implements UserDetailsService
而且,我为最终用户提供了 UserDetailsService 的另一个自定义实现:
@Component("endUserDetailsService")
public class EndUserDetailsService implements UserDetailsService
现在,在下面的代码 sn-p 中,我为这两种类型的用户注册了两个端点。我已经为应用程序和最终用户分别注入了 UserDetailsService 的实现并通过 @Overide configure(AuthenticationManagerBuilder auth)
方法注册。
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Import(SecurityProblemSupport.class)
public class SecurityConfiguration
// Injected via Constructor Injection
private final EndUserDetailsService endUserDetailsService;
private final ApplicationUserDetailsService applicationUserDetailsService;
@Configuration
@Order(1)
public class ApplicationUserSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter
@Override
public void configure(WebSecurity web) throws Exception
web.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**")
.antMatchers("/swagger-ui/index.html")
.antMatchers("/test/**");
@Override
public void configure(HttpSecurity http) throws Exception
// @formatter:off
http
.csrf()
.disable()
.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
.exceptionHandling()
.authenticationEntryPoint(problemSupport)
.accessDeniedHandler(problemSupport)
.and()
.headers()
.frameOptions()
.disable()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.antMatcher("/api/customer/**")
.authorizeRequests()
.antMatchers("/api/customer/authenticate").permitAll()
.antMatchers("/api/customer/**")
.authenticated()
.and()
.apply(securityConfigurerAdapter());
// @formatter:on
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
auth.userDetailsService(endUserDetailsService);
//no @Order defaults to last
@Configuration
public class EndUserSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter
@Override
public void configure(WebSecurity web) throws Exception
web.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**")
.antMatchers("/swagger-ui/index.html")
.antMatchers("/test/**");
@Override
public void configure(HttpSecurity http) throws Exception
// @formatter:off
http
.csrf()
.disable()
.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
.exceptionHandling()
.authenticationEntryPoint(problemSupport)
.accessDeniedHandler(problemSupport)
.and()
.headers()
.frameOptions()
.disable()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/api/authenticate").permitAll()
.antMatchers("/api/**").authenticated()
.and()
.apply(securityConfigurerAdapter());
// @formatter:on
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
auth.userDetailsService(applicationUserDetailsService);
private JWTConfigurer securityConfigurerAdapter()
return new JWTConfigurer(tokenProvider);
而且,我正在尝试像这样对用户进行身份验证:
//Injected via Constructor Injection
private final AuthenticationManagerBuilder authenticationManagerBuilder;
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(loginVM.getUsername(), loginVM.getPassword());
Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
当上面的代码sn-p被执行时,我得到了空指针异常,因为authenticationManagerBuilder.getObject()
返回空值。当我使用 @Component("userDetailsService")
实现 UserDetailService 并且没有在安全配置中设置 UserDetailService 时使用 @ 987654329@,它工作正常,但这样我无法从多个表中实现身份验证。
我想要实现的目标: 简而言之,我希望 Spring Security 从两个表中对用户进行身份验证。
【问题讨论】:
这正是我想要实现的目标:***.com/questions/52783807/… 但找不到任何方法 【参考方案1】:requestMatchers()
是您需要的调用,因为它允许您通过 URL 隔离适配器:
@Order(1)
@EnableWebSecurity
class EndUserConfig extends WebSecurityConfigurerAdapter
@Override
protected void configure(HttpSecurity http) throws Exception
http
.requestMatchers()
.antMatchers("/api/customer/**")
.and()
.authorizeRequests()
.antMatchers("/**").hasRole("CUSTOMER")
.and()
.apply(yourJointConfigurations());
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
auth.userDetailsService(endUserDetailsService);
关于直接调用AuthenticationManager
,如果您可以依靠现有的过滤器链为您完成工作,那将是理想的选择。例如,由于您是无状态的,HTTP Basic 可能更适合您,您可以将其应用于两种配置,而不是尝试使用专用的 /authenticate
端点。
【讨论】:
感谢您拯救了我的一天。以上是关于Spring Security 具有不同用户详细信息的多个 HTTPSecurity 服务在 Spring Boot 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Spring security 自定义用户详细信息@Id 问题
基于 Java Spring Security 的关注微信公众号即登录的设计与实现 ya
spring security - 针对不同 CURL 模式的多重身份验证