【发布时间】:2014-11-25 13:17:00
【问题描述】:
我正在尝试在我的一个控制器上完成基于注释的(使用@PreAuthorize)权限检查。我正在使用 Java 配置,并且有一个 SecurityConfig 类扩展 WebSecurityConfigurerAdapter。
我还使用基本 HTTP 身份验证来获取需要授权的方法。
但是 - 问题是,我不希望 SecurityConfig 确定哪些方法需要使用 antPattern() 或类似的身份验证。这就是注释的用途!
如何配置我的SecurityConfig 类,以便它正确使用HTTP Basic 身份验证和配置的AuthenticationManager 用于具有@PreAuthorize 的方法,并允许匿名访问不的控制器方法是否附加了任何安全注释?
当我尝试这个时(尝试 #1):
@Configuration
@EnableWebSecurity
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
}
@Autowired
public void registerGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("craig").password("craigpass").roles("USER");
}
}
我未受保护的方法失败:
Full authentication is required to access this resource
而我的受保护(但经过正确验证)测试失败:
Error: Expected CSRF token not found. Has your session expired?
当我尝试这个时(尝试 #2):
@Configuration
@EnableWebSecurity
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void registerGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("craig").password("craigpass").roles("USER");
}
}
我的未受保护方法失败并显示302 状态代码,并重定向到/login,而我的受保护/身份验证方法失败并显示:
Error: Expected CSRF token not found. Has your session expired?
当我尝试这个时(尝试 #3):
@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().anyRequest().authenticated().and().httpBasic();
}
@Autowired
public void registerGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("craig").password("craigpass").roles("USER");
}
}
我的身份验证方法可以正常工作。 (呜呼!)但是,我的不受保护的方法因401 而失败,因为我的HttpSecurity 似乎已配置为仅在您通过身份验证时允许访问 - 无论控制器方法是否带有注释@PreAuthorize.
当我尝试这个时(尝试 #4):
@Configuration
@EnableWebSecurity
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().anyRequest().permitAll();
}
@Autowired
public void registerGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("craig").password("craigpass").roles("USER");
}
}
我未受保护的方法正常工作(允许访问),但我的身份验证方法(无论它们是否具有正确的 HTTP 身份验证)失败,状态码为 403:
Error: Access Denied
我的身份验证测试方法使用 403 失败并使用 MockMvc 并使用标头发送请求:
{Content-Type=[application/json], Accept=[application/json], Authorization=[Basic Y3JhaWc6Y3JhaWdwYXNz]}
我已经解码和验证的,以及带有方法POST的URL/api/item,它应该针对相应的方法:
@RequestMapping(value = "/api/item", method = { RequestMethod.POST })
@PreAuthorize("hasRole('ROLE_USER')")
public void postNewItem(HttpServletRequest request, HttpServletResponse response) {
...
}
【问题讨论】:
标签: java spring spring-mvc authentication spring-security