我在使用OAuth2的Spring Security中进行了以下配置:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
//@EnableOAuth2Sso
public class FVSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user")
.password("secret")
.roles("USER", "ROLE1")
.and()
.withUser("admin")
.password("password")
.roles("ADMIN","USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.anonymous().disable()
.authorizeRequests()
.antMatchers("/api/admin/**").hasRole("ADMIN")
.antMatchers("/api/**").hasRole("USER")
.anyRequest().authenticated()
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler())
.and()
.formLogin();
}
资源服务器配置:
@Configuration
@EnableAuthorizationServer
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(ClientDetailsServiceConfigurer clients)
throws Exception {
clients.inMemory()
.withClient("sampleClient")
.authorizedGrantTypes("implicit")
.scopes("read")
.autoApprove(true)
.accessTokenValiditySeconds(30)
.and()
.withClient("user")
.secret("secret")
.scopes("read", "write")
.autoApprove(true)
.authorizedGrantTypes(
"password","authorization_code", "refresh_token")
.and()
.withClient("admin")
.secret("password")
.scopes("read", "write", "custom")
.autoApprove(true)
.authorizedGrantTypes(
"password","authorization_code", "refresh_token");
}
以下Rest Controller
@RestController
public class OAuthTestController {
@PreAuthorize("hasRole('ROLE_ROLE1') and #oauth2.hasScope('read')")
@RequestMapping(value="/api/user/test1", method = RequestMethod.GET)
public String testGETWithRole() {
return "[GET] Needs role ROLE1";
}
@RequestMapping(value="/api/admin/test1", method = RequestMethod.GET)
public String testWithAdminRole() {
return "[GET] Needs Admin role";
}
资源服务器:
@Configuration
@EnableResourceServer
public class ResourceServer extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "my_rest_api";
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID).stateless(false);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.
anonymous().disable()
.requestMatchers().antMatchers("/api/**")
.and().authorizeRequests()
.antMatchers("/api/**").access("hasRole('USER')")
.antMatchers("/api/admin/**").access("hasRole('ADMIN')")
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}
基本上我期望Spring使用OAuth2进行身份验证,并使用spring安全角色来允许资源访问。 我生成并管理令牌,然后是用户令牌。我期望在使用管理令牌时能够访问/ api / admin资源以及何时使用用户令牌无法使用。 我只是注意到表单登录并不总是提示,所以我想Spring会记住经过身份验证的用户。
当我使用管理令牌时,我获得了拒绝访问权限。在Spring源代码中进行调试时,我注意到身份验证是UserNamePasswordAuthenticationPassword的一个实例,其中包含用户详细信息,而不是预期的admin。我想是因为上次我在登录表单中使用了这些凭据。 这是一种强制spring使用凭据来获取相应令牌的方法,还是每次都强制使用Spring show登录表单?
P.S。我使用Postman来测试API。
感谢。