【发布时间】:2016-09-22 09:50:24
【问题描述】:
我有一个我想用 OAuth2 保护的 API。我已经使用密码 grant_type 进行了虚拟测试,一切正常。我可以请求令牌,使用它访问安全端点等。服务器充当授权和资源服务器。
后来我读到我应该使用隐式授权类型,因为客户端将是一个 javascript 应用程序。
我的客户端是这样配置的:
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {// @formatter:off
clients
.inMemory().withClient("web")
.redirectUris("http://localhost:3000")
.secret("secret")
.authorizedGrantTypes("implicit", "refresh_token").scopes("read", "write")
.accessTokenValiditySeconds(3600).refreshTokenValiditySeconds(2592000);
}
我明白了:
{
"timestamp": 1464136960414,
"status": 403,
"error": "Forbidden",
"message": "Expected CSRF token not found. Has your session expired?",
"path": "/oauth/authorize"
}
如果我是第一次调用 API,如何获得 CSRF 令牌? 如果(仅用于测试)我禁用 csrf 然后我得到这个:
{
"timestamp": 1464136840865,
"status": 403,
"error": "Forbidden",
"exception": "org.springframework.security.authentication.InsufficientAuthenticationException",
"message": "Access Denied",
"path": "/oauth/authorize"
}
使用密码 grant_type 设置客户端我可以进行此调用并且一切正常: http://localhost:8080/oauth/token?grant_type=password&username=test&password=123 并添加带有客户端 id/secret 的 Authorization Basic 标头。
澄清一下,我们的想法是拥有这个独特的受信任客户。所以用户应该只输入登录名/密码而不要求用户授予应用程序的访问权限。
抱歉,这是一个愚蠢的问题。我一直在阅读我能找到的所有内容,但似乎无法取得进展。
谢谢!
编辑:
我的 Spring 安全配置:
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MongoDBAuthenticationProvider authenticationProvider;
@Autowired
public void globalUserDetails(final AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
我的 OAuth 配置:
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Override
public void configure(final AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory().withClient("web")
.redirectUris("http://localhost:3000")
.secret("secret")
.authorizedGrantTypes("implicit", "refresh_token").scopes("read", "write")
.accessTokenValiditySeconds(3600).refreshTokenValiditySeconds(2592000);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
}
服务器异常:
2016-05-25 19:52:20.744 DEBUG 34968 --- [nio-8080-exec-5] .s.o.p.e.FrameworkEndpointHandlerMapping : Looking up handler method for path /oauth/authorize
2016-05-25 19:52:20.744 DEBUG 34968 --- [nio-8080-exec-5] .s.o.p.e.FrameworkEndpointHandlerMapping : Returning handler method [public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.authorize(java.util.Map<java.lang.String, java.lang.Object>,java.util.Map<java.lang.String, java.lang.String>,org.springframework.web.bind.support.SessionStatus,java.security.Principal)]
2016-05-25 19:52:20.746 DEBUG 34968 --- [nio-8080-exec-5] o.s.s.w.a.ExceptionTranslationFilter : Authentication exception occurred; redirecting to authentication entry point
org.springframework.security.authentication.InsufficientAuthenticationException: User must be authenticated with Spring Security before authorization can be completed.
at org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.authorize(AuthorizationEndpoint.java:138) ~[spring-security-oauth2-2.0.9.RELEASE.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_40]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_40]
....
【问题讨论】:
标签: oauth-2.0 spring-security-oauth2