为什么 Spring Security permitAll() 不适用于 OAuth2.0?
Why Spring Security permitAll() is not working with OAuth2.0?
我有一个使用 OAuth2.0 保护的 REST API
我可以使用 http://localhost:8085/auth/token?grant_type=password&username=22@gmail.com&password=mypass(连同用户名传递基本身份验证)获取访问令牌。
但是当我尝试访问 http://localhost:8085/api/v1/signup 时,API returns 出现 401 unauthorized
错误。
虽然我使用了 antMatchers("/signup").permitAll()
,但为什么 API 期望 access-token
来访问此资源?将 access-token
与此请求一起传递将注册一个用户。
这是我的资源服务器配置
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
//require beans and methods here
@Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth) {
auth.authenticationProvider(authProvider());
}
@Override
public void configure(final HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/signup").permitAll()
.anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.csrf().disable();
}
}
更新:正如this 线程所建议的那样,我在`` 处忽略了/signup
,但这也没有用。
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
@ComponentScan(basePackages = { "com.sample.rest.security" })
@Order(2)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//other Beans & methods
@Override
protected void configure(HttpSecurity http) throws Exception {
List<RequestMatcher> requestMatchers = new ArrayList<RequestMatcher>();
requestMatchers.add(new AntPathRequestMatcher("/signup/**"));
http.
requestMatcher(new OrRequestMatcher(requestMatchers)).
authorizeRequests().antMatchers("/signup/**")
.permitAll();
}
}
我认为顺序是问题和匹配器**。
@Override
public void configure(final HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/signup**")
.permitAll()
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .csrf().disable();
}
我知道了。这是导致问题的上下文路径。我有一个用映射 URL /api/v1/*
定义的调度程序 servlet,并且可以看到我的 signup
请求,它包含一个上下文路径,即 http://localhost:8085/api/v1/signup
对于 Spring 中的 OAuth2 配置,我们需要特别注意上下文路径。首先,应该定义在AuthorizationServer
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.prefix("/api/v1") //here
.tokenStore(tokenStore())
.accessTokenConverter(accessTokenConverter())
.authenticationManager(authenticationManager)
.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
}
然后,上下文必须像这样添加到permitAll()
路径
@Override
public void configure(final HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/v1/signup").permitAll() //context path here
.anyRequest().authenticated();
}
到目前为止,注册请求仍然需要传递一个访问令牌。要从注册中删除 OAuth 安全性,我们需要在 WebSecurity
处删除安全性,这可以使用 WebSecurityConfigurerAdapter
来完成
@EnableWebSecurity
@EnableGlobalMethodSecurity
@ComponentScan(basePackages = { "com.sample.rest.security" })
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity webSecurity) throws Exception {
webSecurity.ignoring().antMatchers("/signup");
}
//////////// OR use below method ///////////
/* @Override
protected void configure(HttpSecurity http) throws Exception {
http.
authorizeRequests().antMatchers("/signup/**").permitAll();
}
*/
}
注意,将上下文路径添加到 WebSecurityConfigurerAdapter
配置是没有用的。
我有一个使用 OAuth2.0 保护的 REST API
我可以使用 http://localhost:8085/auth/token?grant_type=password&username=22@gmail.com&password=mypass(连同用户名传递基本身份验证)获取访问令牌。
但是当我尝试访问 http://localhost:8085/api/v1/signup 时,API returns 出现 401 unauthorized
错误。
虽然我使用了 antMatchers("/signup").permitAll()
,但为什么 API 期望 access-token
来访问此资源?将 access-token
与此请求一起传递将注册一个用户。
这是我的资源服务器配置
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
//require beans and methods here
@Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth) {
auth.authenticationProvider(authProvider());
}
@Override
public void configure(final HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/signup").permitAll()
.anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.csrf().disable();
}
}
更新:正如this 线程所建议的那样,我在`` 处忽略了/signup
,但这也没有用。
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
@ComponentScan(basePackages = { "com.sample.rest.security" })
@Order(2)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//other Beans & methods
@Override
protected void configure(HttpSecurity http) throws Exception {
List<RequestMatcher> requestMatchers = new ArrayList<RequestMatcher>();
requestMatchers.add(new AntPathRequestMatcher("/signup/**"));
http.
requestMatcher(new OrRequestMatcher(requestMatchers)).
authorizeRequests().antMatchers("/signup/**")
.permitAll();
}
}
我认为顺序是问题和匹配器**。
@Override
public void configure(final HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/signup**")
.permitAll()
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .csrf().disable();
}
我知道了。这是导致问题的上下文路径。我有一个用映射 URL /api/v1/*
定义的调度程序 servlet,并且可以看到我的 signup
请求,它包含一个上下文路径,即 http://localhost:8085/api/v1/signup
对于 Spring 中的 OAuth2 配置,我们需要特别注意上下文路径。首先,应该定义在AuthorizationServer
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.prefix("/api/v1") //here
.tokenStore(tokenStore())
.accessTokenConverter(accessTokenConverter())
.authenticationManager(authenticationManager)
.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
}
然后,上下文必须像这样添加到permitAll()
路径
@Override
public void configure(final HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/v1/signup").permitAll() //context path here
.anyRequest().authenticated();
}
到目前为止,注册请求仍然需要传递一个访问令牌。要从注册中删除 OAuth 安全性,我们需要在 WebSecurity
处删除安全性,这可以使用 WebSecurityConfigurerAdapter
@EnableWebSecurity
@EnableGlobalMethodSecurity
@ComponentScan(basePackages = { "com.sample.rest.security" })
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity webSecurity) throws Exception {
webSecurity.ignoring().antMatchers("/signup");
}
//////////// OR use below method ///////////
/* @Override
protected void configure(HttpSecurity http) throws Exception {
http.
authorizeRequests().antMatchers("/signup/**").permitAll();
}
*/
}
注意,将上下文路径添加到 WebSecurityConfigurerAdapter
配置是没有用的。