configure(HttpSecurity http)和configure(AuthenticationManager



我正在尝试保护具有不同用户角色的spring应用程序。虽然设置了身份验证部分并完美地工作,但我在实现授权部分期间意识到,使用某些注释,SecurityConfiguration extends WebSecurityConfigurerAdapter class中的两个重写方法之一会被忽略。

public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private WebApplicationContext applicationContext;
private CredentialsService userDetailsService;
@Autowired
private DataSource dataSource;
@PostConstruct
public void completeSetup() {
userDetailsService =   applicationContext.getBean(CredentialsService.class);
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login")
.permitAll()
.and()
.formLogin()
.permitAll()
.and()
.httpBasic()
.disable()
.authorizeRequests()
.antMatchers("/admin", "/admin/**")
.hasRole("ADMIN")
.and()
.authorizeRequests()
.antMatchers("/employee", "/employee/**")
.hasRole("EMPLOYEE")
.and()
.authorizeRequests()
.antMatchers("/customer", "/customer/**")
.hasRole("CUSTOMER");
}
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(encoder())
.and()
.authenticationProvider(authenticationProvider())
.jdbcAuthentication()
.dataSource(dataSource);
}

@Bean
public DaoAuthenticationProvider authenticationProvider() {
final DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(encoder());
return authProvider;
}
@Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder(12);
}
}

现在的问题如下,这个类验证我的用户,但有一个主要缺点:

configure(final HttpSecurity http) throws Exception {

被完全忽略。

另一方面,如果我在类的顶部添加@Configuration注释,也就是
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {

被完全忽略,因此将破坏授权,因为它将无法在我的自定义UserDetailsService实现上调用getUsername()和getPassword。

正如您所看到的,我使用了DaoAuthenticationProvider实例作为authenticationProvider,因为我的应用程序从外部数据库检索用户/密码。

我现在采用的快速修复方法是在我的主类

中添加以下方法
@EnableGlobalMethodSecurity(
securedEnabled = true,
jsr250Enabled = true,
prePostEnabled = true
)

@Secured注释在我的受限控制器上的使用。这是有效的,但是我想了解为什么Spring有这样奇怪的行为,我可以采取什么步骤来解决这些问题。

由于您正在为用户分配角色,因此请使用语法

.antMatchers("/admin", "/admin/**")
.hasRole("ADMIN")

.antMatchers("/admin", "/admin/**")
.hasAuthority("ROLE_ADMIN")

角色只是作为权限存储,带有"ROLE_"前缀。
角色"ADMIN"相当于权限"ROLE_ADMIN"

编辑1

您还可以简化您的配置,以明确所有内容的来源。

因为你的UserDetailsService(CredentialsService)已经是一个bean,它将被Spring Security自动拾取。

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
// The password encoder should be a bean
@Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder(12);
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login")
.permitAll()
.and()
.formLogin()
.permitAll()
.and()
.authorizeRequests()
.antMatchers("/admin", "/admin/**")
.hasRole("ADMIN")
.and()
.authorizeRequests()
.antMatchers("/manager", "/manager/**")
.hasRole("MANAGER")
.and()
.authorizeRequests()
.antMatchers("/customer", "/customer/**")
.hasRole("CUSTOMER");
}
}

最新更新