Spring 安全 OAuth2 | InsufficientAuthenticationException异常
Spring Security OAuth2 | InsufficientAuthenticationException
我正在尝试使用 Spring Security OAuth2 (2.0.6.RELEASE) 构建 OAuth2 授权服务器。
这是我的相关配置的样子:-
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationConfig extends
AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
/*
* (non-Javadoc)
*
* @see
* org.springframework.security.oauth2.config.annotation.web.configuration
* .AuthorizationServerConfigurerAdapter
* #configure(org.springframework.security
* .oauth2.config.annotation.web.configurers
* .AuthorizationServerEndpointsConfigurer)
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.authenticationManager(authenticationManager);
}
/*
* (non-Javadoc)
*
* @see
* org.springframework.security.oauth2.config.annotation.web.configuration
* .AuthorizationServerConfigurerAdapter
* #configure(org.springframework.security
* .oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer)
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients)
throws Exception {
// OAuth2 CLIENT CONFIGURATION !!!!!
clients.inMemory().withClient("sambhav").secret("sambhav")
.authorizedGrantTypes("authorization_code")
.scopes("openid", "all").redirectUris("http:localhost:9001");
}
/*
* (non-Javadoc)
*
* @see
* org.springframework.security.oauth2.config.annotation.web.configuration
* .AuthorizationServerConfigurerAdapter
* #configure(org.springframework.security
* .oauth2.config.annotation.web.configurers
* .AuthorizationServerSecurityConfigurer)
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security)
throws Exception {
super.configure(security);
}
}
使用 Spring 引导嵌入式码头,在启动过程中,我看到 OAuth2 端点确实在我的日志中注册。
尝试使用 client_id=sambhav,response_type=code,redirect_uri=http://localhost:9001,scope=all,
访问(使用 Postman)/oauth/authorize POST 端点时,我收到 500 错误响应并出现以下错误:-
{"timestamp":1423055109697,"status":500,"error":"Internal Server Error","exception":"org.springframework.security.authentication.InsufficientAuthenticationException","message":"User must be authenticated with Spring Security before authorization can be completed.","path":"/oauth/authorize"}
查看日志,我可以看到在 class org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint
的方法 authorize
:-
中检查身份验证
@RequestMapping(value = "/oauth/authorize")
public ModelAndView authorize(Map<String, Object> model, @RequestParam Map<String, String> parameters,
SessionStatus sessionStatus, Principal principal) {
// Pull out the authorization request first, using the OAuth2RequestFactory. All further logic should
// query off of the authorization request instead of referring back to the parameters map. The contents of the
// parameters map will be stored without change in the AuthorizationRequest object once it is created.
AuthorizationRequest authorizationRequest = getOAuth2RequestFactory().createAuthorizationRequest(parameters);
Set<String> responseTypes = authorizationRequest.getResponseTypes();
if (!responseTypes.contains("token") && !responseTypes.contains("code")) {
throw new UnsupportedResponseTypeException("Unsupported response types: " + responseTypes);
}
if (authorizationRequest.getClientId() == null) {
throw new InvalidClientException("A client id must be provided");
}
try {
// THIS check causes the problem
if (!(principal instanceof Authentication) || !((Authentication) principal).isAuthenticated()) {
throw new InsufficientAuthenticationException(
"User must be authenticated with Spring Security before authorization can be completed.");
}
问题
为什么授权步骤需要已经建立的身份验证?
需要谁的授权(用户或客户端)?我怎么做?使用 client_id/client_secret 组合?
如果用户(又名资源所有者)允许,authorization_code
授予客户端访问资源服务器的权限。
您正在尝试访问用户可以向客户端授予授权的页面,但您没有以用户身份登录,因此 Spring 安全无法知道 谁 应该在您的示例中授权客户端 (sambhav)。
我正在尝试使用 Spring Security OAuth2 (2.0.6.RELEASE) 构建 OAuth2 授权服务器。
这是我的相关配置的样子:-
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationConfig extends
AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
/*
* (non-Javadoc)
*
* @see
* org.springframework.security.oauth2.config.annotation.web.configuration
* .AuthorizationServerConfigurerAdapter
* #configure(org.springframework.security
* .oauth2.config.annotation.web.configurers
* .AuthorizationServerEndpointsConfigurer)
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.authenticationManager(authenticationManager);
}
/*
* (non-Javadoc)
*
* @see
* org.springframework.security.oauth2.config.annotation.web.configuration
* .AuthorizationServerConfigurerAdapter
* #configure(org.springframework.security
* .oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer)
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients)
throws Exception {
// OAuth2 CLIENT CONFIGURATION !!!!!
clients.inMemory().withClient("sambhav").secret("sambhav")
.authorizedGrantTypes("authorization_code")
.scopes("openid", "all").redirectUris("http:localhost:9001");
}
/*
* (non-Javadoc)
*
* @see
* org.springframework.security.oauth2.config.annotation.web.configuration
* .AuthorizationServerConfigurerAdapter
* #configure(org.springframework.security
* .oauth2.config.annotation.web.configurers
* .AuthorizationServerSecurityConfigurer)
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security)
throws Exception {
super.configure(security);
}
}
使用 Spring 引导嵌入式码头,在启动过程中,我看到 OAuth2 端点确实在我的日志中注册。
尝试使用 client_id=sambhav,response_type=code,redirect_uri=http://localhost:9001,scope=all,
访问(使用 Postman)/oauth/authorize POST 端点时,我收到 500 错误响应并出现以下错误:-
{"timestamp":1423055109697,"status":500,"error":"Internal Server Error","exception":"org.springframework.security.authentication.InsufficientAuthenticationException","message":"User must be authenticated with Spring Security before authorization can be completed.","path":"/oauth/authorize"}
查看日志,我可以看到在 class org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint
的方法 authorize
:-
@RequestMapping(value = "/oauth/authorize")
public ModelAndView authorize(Map<String, Object> model, @RequestParam Map<String, String> parameters,
SessionStatus sessionStatus, Principal principal) {
// Pull out the authorization request first, using the OAuth2RequestFactory. All further logic should
// query off of the authorization request instead of referring back to the parameters map. The contents of the
// parameters map will be stored without change in the AuthorizationRequest object once it is created.
AuthorizationRequest authorizationRequest = getOAuth2RequestFactory().createAuthorizationRequest(parameters);
Set<String> responseTypes = authorizationRequest.getResponseTypes();
if (!responseTypes.contains("token") && !responseTypes.contains("code")) {
throw new UnsupportedResponseTypeException("Unsupported response types: " + responseTypes);
}
if (authorizationRequest.getClientId() == null) {
throw new InvalidClientException("A client id must be provided");
}
try {
// THIS check causes the problem
if (!(principal instanceof Authentication) || !((Authentication) principal).isAuthenticated()) {
throw new InsufficientAuthenticationException(
"User must be authenticated with Spring Security before authorization can be completed.");
}
问题
为什么授权步骤需要已经建立的身份验证?
需要谁的授权(用户或客户端)?我怎么做?使用 client_id/client_secret 组合?
如果用户(又名资源所有者)允许,authorization_code
授予客户端访问资源服务器的权限。
您正在尝试访问用户可以向客户端授予授权的页面,但您没有以用户身份登录,因此 Spring 安全无法知道 谁 应该在您的示例中授权客户端 (sambhav)。