使用Java配置在Spring Security为基于注解角色检查和基本的HTTP认证 [英] Using Java config with Spring Security for annotation-based role checks and Basic HTTP Auth
问题描述
我试图完成的注释为基础的(使用 @ preAuthorize
)权限在我的控制器之一检查。我使用Java的配置,并有一个 SecurityConfig
类扩展 WebSecurityConfigurerAdapter
。
我还使用基本HTTP认证才能到需要授权的方法。
但 - 问题是,我的不要希望 SecurityConfig
确定使用哪些方法需要身份验证的 antPattern ()
或相似。这就是注解是!
如何配置我的 SecurityConfig
类,以便它正确地使用HTTP基本身份验证和配置的的AuthenticationManager
的方法与 @ preAuthorize
,并允许控制器的方法的不的附加任何安全注解?
当我尝试这个(尝试#1):
@Configuration
@EnableWebSecurity
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = TRUE)
公共类SecurityConfig扩展WebSecurityConfigurerAdapter { @覆盖
保护无效配置(HttpSecurity HTTP)抛出异常{
。http.authorizeRequests()anyRequest()验证()和()httpBasic()。;
} @Autowired
公共无效registerGlobal(AuthenticationManagerBuilder AUTH)抛出异常{
。auth.inMemoryAuthentication()withUser(克雷格),密码(craigpass)的角色(用户)。;
}
}
我的不受保护的方法失败:
全认证才能访问该资源
和我的保护(但正确-认证)测试失败,
错误:预期CSRF令牌没有找到。贵会话过期?
当我尝试这个(尝试#2):
@Configuration
@EnableWebSecurity
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = TRUE)
公共类SecurityConfig扩展WebSecurityConfigurerAdapter { @Autowired
公共无效registerGlobal(AuthenticationManagerBuilder AUTH)抛出异常{
。auth.inMemoryAuthentication()withUser(克雷格),密码(craigpass)的角色(用户)。;
}
}
我的不受保护的方法失败了 302
状态code,并重定向到 /登录
,和我的保护/验证方法失败:
错误:预期CSRF令牌没有找到。贵会话过期?
当我尝试这个(尝试3):
@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = TRUE)
公共类SecurityConfig扩展WebSecurityConfigurerAdapter { @覆盖
保护无效配置(HttpSecurity HTTP)抛出异常{
http.csrf()禁用()authorizeRequests()anyRequest()验证()和()httpBasic()。。。。;
} @Autowired
公共无效registerGlobal(AuthenticationManagerBuilder AUTH)抛出异常{
。auth.inMemoryAuthentication()withUser(克雷格),密码(craigpass)的角色(用户)。;
}
}
我的认证方法正常工作。 (宇豪!)但是,我的未受保护的方法失败, 401
,因为我的 HttpSecurity
似乎已被配置为的只有的允许访问,如果你验证 - 无论控制器方法与 @ preAuthorize
注释
当我尝试这种(企图#4):
@Configuration
@EnableWebSecurity
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = TRUE)
公共类SecurityConfig扩展WebSecurityConfigurerAdapter { @覆盖
保护无效配置(HttpSecurity HTTP)抛出异常{
http.csrf()禁用()authorizeRequests()anyRequest()permitAll()。。
} @Autowired
公共无效registerGlobal(AuthenticationManagerBuilder AUTH)抛出异常{
。auth.inMemoryAuthentication()withUser(克雷格),密码(craigpass)的角色(用户)。;
}
}
我的不受保护的方法正常工作(允许访问),但我的身份验证方法(他们是否有适当的HTTP认证与否)失败,状态code 403
:
错误:拒绝访问
我的认证测试方法失败与 403
使用 MockMvc
并在发送要求使用头文件:
{内容类型= [应用程序/ JSON],接受= [应用程序/ JSON],授权= [基本Y3JhaWc6Y3JhaWdwYXNz]}
这点我必须去codeD和验证,以及一个网址 / API /项目
与方法 POST
,应针对相应的方法:
@RequestMapping(值=/ API /项,方法= {} RequestMethod.POST)
@ preAuthorize(hasRole('ROLE_USER'))
公共无效postNewItem(HttpServletRequest的请求,HttpServletResponse的响应){
...
}
我已经做过类似,唯一的区别是,我有一些非常定制的认证方法的东西。如果你想的唯一事情是检查用户角色,你应该使用 @Secured
而不是 @ preAuthorize
在你的控制器方法,例如
@Secured({ROLE_SOMEROLE})
公共无效DoSomething的(...){
}
当角色在的AuthenticationProvider
设置为 SimpleGrantedAuthority
与 UsernamePasswordAuthenticationToken <列表/ code>。
下面是配置类:
@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(securedEnabled =真)
公共类SecurityConfig扩展WebSecurityConfigurerAdapter {@Autowired
私人的AuthenticationProvider authProvider;@Autowired
私人的AuthenticationEntryPoint的AuthenticationEntryPoint;@Autowired
公共无效configureGlobal(AuthenticationManagerBuilder AUTH)
抛出异常{
auth.authenticationProvider(authProvider);
}@覆盖
保护无效配置(HttpSecurity HTTP)抛出异常{
//有一些其他的呼吁CORS Ajax请求。
http.authorizeRequests()
.antMatchers(/注销)
.permitAll()
.anyRequest()
.authenticated()
。和()
.httpBasic()
.authenticationEntryPoint(的AuthenticationEntryPoint)
.csrf()
.disable();
}}
如果你的方法被注解为 @Secured
,而当前用户没有指定的角色,客户端将收到一个 403
响应否则请求经过。如果您尝试运行单元测试,您可以使用 @profile('测试')
您豆类和使用的AuthenticationProvider
硬codeD数据。在这里,对这种类型的方法后:
https://spring.io/blog/ 2011/02/14 /春天-3-1-M1-引入瞩目/
I'm trying to accomplish annotation-based (using @PreAuthorize
) permission checking on one of my controllers. I'm using Java config, and have a SecurityConfig
class extending WebSecurityConfigurerAdapter
.
I'm also using Basic HTTP Authentication to get to the methods that require authorization.
But - the problem is, I don't want the SecurityConfig
determining which methods require authentication using an antPattern()
or similar. That's what the annotations are for!
How can I configure my SecurityConfig
class so that it properly uses HTTP Basic authentication and the configured AuthenticationManager
for methods with @PreAuthorize
, and allows anonymous access to controller methods that do not have any security annotations attached?
When I try this (Attempt #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");
}
}
My unprotected methods fail with:
Full authentication is required to access this resource
And my protected (but properly-authenticating) tests fail with:
Error: Expected CSRF token not found. Has your session expired?
When I try this (Attempt #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");
}
}
My unprotected methods fail with a 302
status code, and redirect to /login
, and my protected/authenticating methods fail with:
Error: Expected CSRF token not found. Has your session expired?
When I try this (Attempt #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");
}
}
My authenticating method works properly. (Woo hoo!) But, my unprotected method fails with 401
because my HttpSecurity
has seemingly been configured to only allow access if you're authenticated - regardless of whether the controller method is annotated with @PreAuthorize
.
When I try this (Attempt #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");
}
}
My unprotected methods work properly (allow access), but my authenticating methods (whether they have the proper HTTP auth or not) fail with status code 403
:
Error: Access Denied
My authenticating test method that fails with 403
uses MockMvc
and sends in a request using headers:
{Content-Type=[application/json], Accept=[application/json], Authorization=[Basic Y3JhaWc6Y3JhaWdwYXNz]}
Which I have decoded and verified, and a URL /api/item
with method POST
, which should target the corresponding method:
@RequestMapping(value = "/api/item", method = { RequestMethod.POST })
@PreAuthorize("hasRole('ROLE_USER')")
public void postNewItem(HttpServletRequest request, HttpServletResponse response) {
...
}
I've done something similar the only difference is that i had some very customized authentication method. If the only thing you want is to check for user role you should use @Secured
instead of @PreAuthorize
on your controller methods e.g.
@Secured({"ROLE_SOMEROLE"})
public void doSomething(...) {
}
Where the role is set in AuthenticationProvider
as a list of SimpleGrantedAuthority
with UsernamePasswordAuthenticationToken
.
Here is the configuration class:
@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(securedEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthenticationProvider authProvider;
@Autowired
private AuthenticationEntryPoint authenticationEntryPoint;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.authenticationProvider(authProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// Had some other calls for CORS ajax requests.
http.authorizeRequests()
.antMatchers("/logout")
.permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint)
.csrf()
.disable();
}
}
If your methods are annotated with @Secured
and the current user does not have specified role the client will receive a 403
response else the request goes through. If you are trying to run unit testing you can use @Profile('test')
on your beans and use AuthenticationProvider
with hard coded data. Here a post on this type of approach:
https://spring.io/blog/2011/02/14/spring-3-1-m1-introducing-profile/
这篇关于使用Java配置在Spring Security为基于注解角色检查和基本的HTTP认证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!