Bil*_*een 5 spring spring-security spring-boot
我有两种类型的用户:应用程序用户和最终用户,我有单独的表。现在,我想对这两个表应用安全性。
我为应用程序用户提供了UserDetailsService 的自定义实现:
@Component("applicationUserDetailsService")
public class ApplicationUserDetailsService implements UserDetailsService {}
Run Code Online (Sandbox Code Playgroud)
而且,我为最终用户提供了UserDetailsService 的另一个自定义实现:
@Component("endUserDetailsService")
public class EndUserDetailsService implements UserDetailsService {}
Run Code Online (Sandbox Code Playgroud)
现在,在以下代码片段中,我为这两种类型的用户注册了两个端点。我已经分别为应用程序和最终用户注入了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);
}
}
Run Code Online (Sandbox Code Playgroud)
而且,我正在尝试像这样对用户进行身份验证:
//Injected via Constructor Injection
private final AuthenticationManagerBuilder authenticationManagerBuilder;
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(loginVM.getUsername(), loginVM.getPassword());
Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
Run Code Online (Sandbox Code Playgroud)
当上面的代码片段被执行时,我得到空指针异常,因为authenticationManagerBuilder.getObject()返回 NULL。当我在UserDetailService 的实现中使用@Component("userDetailsService")而不是在安全配置中设置UserDetailService时auth.userDetailsService("..."),它工作正常,但通过这种方式我无法从多个表实现身份验证。
我想要实现的目标: 简单来说,我希望 spring security 能够对来自两个表的用户进行身份验证。
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);
}
}
Run Code Online (Sandbox Code Playgroud)
关于直接调用AuthenticationManager,如果您可以依靠现有的过滤器链来为您完成工作,那将是理想的选择。例如,由于您是无状态的,HTTP Basic 可能更适合您,您可以将其应用于这两种配置,而不是尝试拥有专用端点/authenticate。
| 归档时间: |
|
| 查看次数: |
1756 次 |
| 最近记录: |