Java Spring Security OAuth - 访问此资源需要完全身份验证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38279753/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Security OAuth - Full authentication is required to access this resource
提问by Pavan Andhukuri
Following is my Authorization server configuration:
以下是我的授权服务器配置:
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
@Configuration
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("acme").secret("acmesecret")
.authorizedGrantTypes("authorization_code", "refresh_token", "password").scopes("openid")
.autoApprove(true);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
}
}
And the Web security configuration:
以及 Web 安全配置:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@Order(-20) // Very important
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.parentAuthenticationManager(authenticationManager);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin().loginPage("/login.html").permitAll().and().requestMatchers()
.antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access").and().authorizeRequests()
.anyRequest().authenticated();
}
}
Now, from the client application, when I try to access a secure resource, it redirects to the authorization server but I get the following error:
现在,从客户端应用程序,当我尝试访问安全资源时,它重定向到授权服务器,但出现以下错误:
<oauth>
<error_description>
Full authentication is required to access this resource
</error_description>
<error>unauthorized</error>
</oauth>
The same setup is working well in case of basic authentication. I am facing problems when I switch to form login.
在基本身份验证的情况下,相同的设置运行良好。当我切换到表单登录时,我遇到了问题。
Update
更新
The following web security setting worked.
以下网络安全设置有效。
http.formLogin().loginPage("/login.html").loginProcessingUrl("/login").permitAll().and().authorizeRequests()
.antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access","/oauth/token").permitAll().anyRequest()
.authenticated().and().csrf().disable();
Now, I am able to see the login page and I am able to login as well, but post login, the client is not able to get an oauth token.
现在,我可以看到登录页面,也可以登录,但是登录后,客户端无法获得 oauth 令牌。
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Mon Jul 11 17:39:46 IST 2016
There was an unexpected error (type=Unauthorized, status=401).
Authentication Failed: Could not obtain access token
I am able to see the following server log
我能够看到以下服务器日志
2016-07-11 17:39:46.119 DEBUG 12502 --- [nio-9999-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/oauth/token'; against '/css/**'
2016-07-11 17:39:46.119 DEBUG 12502 --- [nio-9999-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/oauth/token'; against '/js/**'
2016-07-11 17:39:46.119 DEBUG 12502 --- [nio-9999-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/oauth/token'; against '/images/**'
2016-07-11 17:39:46.120 DEBUG 12502 --- [nio-9999-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/oauth/token'; against '/**/favicon.ico'
2016-07-11 17:39:46.120 DEBUG 12502 --- [nio-9999-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/oauth/token'; against '/error'
2016-07-11 17:39:46.120 DEBUG 12502 --- [nio-9999-exec-2] o.s.security.web.FilterChainProxy : /oauth/token at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-07-11 17:39:46.120 DEBUG 12502 --- [nio-9999-exec-2] o.s.security.web.FilterChainProxy : /oauth/token at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-07-11 17:39:46.120 DEBUG 12502 --- [nio-9999-exec-2] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
2016-07-11 17:39:46.120 DEBUG 12502 --- [nio-9999-exec-2] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.
2016-07-11 17:39:46.120 DEBUG 12502 --- [nio-9999-exec-2] o.s.security.web.FilterChainProxy : /oauth/token at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-07-11 17:39:46.120 DEBUG 12502 --- [nio-9999-exec-2] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@13bb1f26
2016-07-11 17:39:46.120 DEBUG 12502 --- [nio-9999-exec-2] o.s.security.web.FilterChainProxy : /oauth/token at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
2016-07-11 17:39:46.120 DEBUG 12502 --- [nio-9999-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/oauth/token'; against '/logout'
2016-07-11 17:39:46.120 DEBUG 12502 --- [nio-9999-exec-2] o.s.security.web.FilterChainProxy : /oauth/token at position 5 of 11 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2016-07-11 17:39:46.120 DEBUG 12502 --- [nio-9999-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/oauth/token'; against '/login'
2016-07-11 17:39:46.120 DEBUG 12502 --- [nio-9999-exec-2] o.s.security.web.FilterChainProxy : /oauth/token at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2016-07-11 17:39:46.120 DEBUG 12502 --- [nio-9999-exec-2] o.s.security.web.FilterChainProxy : /oauth/token at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2016-07-11 17:39:46.120 DEBUG 12502 --- [nio-9999-exec-2] o.s.security.web.FilterChainProxy : /oauth/token at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2016-07-11 17:39:46.120 DEBUG 12502 --- [nio-9999-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
2016-07-11 17:39:46.120 DEBUG 12502 --- [nio-9999-exec-2] o.s.security.web.FilterChainProxy : /oauth/token at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter'
2016-07-11 17:39:46.121 DEBUG 12502 --- [nio-9999-exec-2] o.s.security.web.FilterChainProxy : /oauth/token at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2016-07-11 17:39:46.121 DEBUG 12502 --- [nio-9999-exec-2] o.s.security.web.FilterChainProxy : /oauth/token at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2016-07-11 17:39:46.121 DEBUG 12502 --- [nio-9999-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/oauth/token'; against '/login'
2016-07-11 17:39:46.121 DEBUG 12502 --- [nio-9999-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/oauth/token'; against '/oauth/authorize'
2016-07-11 17:39:46.121 DEBUG 12502 --- [nio-9999-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/oauth/token'; against '/oauth/confirm_access'
2016-07-11 17:39:46.121 DEBUG 12502 --- [nio-9999-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/oauth/token'; against '/oauth/token'
2016-07-11 17:39:46.121 DEBUG 12502 --- [nio-9999-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /oauth/token; Attributes: [permitAll]
2016-07-11 17:39:46.121 DEBUG 12502 --- [nio-9999-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
2016-07-11 17:39:46.121 DEBUG 12502 --- [nio-9999-exec-2] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@6780c4c7, returned: 1
2016-07-11 17:39:46.121 DEBUG 12502 --- [nio-9999-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor : Authorization successful
2016-07-11 17:39:46.121 DEBUG 12502 --- [nio-9999-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor : RunAsManager did not change Authentication object
2016-07-11 17:39:46.121 DEBUG 12502 --- [nio-9999-exec-2] o.s.security.web.FilterChainProxy : /oauth/token reached end of additional filter chain; proceeding with original chain
2016-07-11 17:39:46.122 DEBUG 12502 --- [nio-9999-exec-2] .s.o.p.e.FrameworkEndpointHandlerMapping : Looking up handler method for path /oauth/token
2016-07-11 17:39:46.122 DEBUG 12502 --- [nio-9999-exec-2] .s.o.p.e.FrameworkEndpointHandlerMapping : Returning handler method [public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException]
2016-07-11 17:39:46.123 INFO 12502 --- [nio-9999-exec-2] o.s.s.o.provider.endpoint.TokenEndpoint : Handling error: InsufficientAuthenticationException, There is no client authentication. Try adding an appropriate authentication filter.
2016-07-11 17:39:46.125 DEBUG 12502 --- [nio-9999-exec-2] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2016-07-11 17:39:46.126 DEBUG 12502 --- [nio-9999-exec-2] o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally
2016-07-11 17:39:46.126 DEBUG 12502 --- [nio-9999-exec-2] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
Update 2
更新 2
Following is my client configuration.
以下是我的客户端配置。
security:
oauth2:
client:
accessTokenUri: http://localhost:9999/uaa/oauth/token
userAuthorizationUri: http://localhost:9999/uaa/oauth/authorize
clientId: acme
clientSecret: acmesecret
resource:
userInfoUri: http://localhost:9999/uaa/user
logging:
level:
org.springframework.security: DEBUG
Update 3
更新 3
The code is available in the following repo
代码在以下 repo 中可用
采纳答案by Pavan Andhukuri
I think I figured out what the problem was.
我想我想出了问题所在。
I went through the following example available on github where form based authentication mechanism was used (which is what I was looking for).
我浏览了 github 上提供的以下示例,其中使用了基于表单的身份验证机制(这是我正在寻找的)。
https://github.com/spring-guides/tut-spring-security-and-angular-js/
https://github.com/spring-guides/tut-spring-security-and-angular-js/
The exact code is working fine if I use a non HTML page as my login page. For example, JSP or FTL. The example uses Freemarker. Everything is working fine with my settings if I use ftl pages. But the same are not working in case of .html pages.
如果我使用非 HTML 页面作为我的登录页面,则确切的代码工作正常。例如,JSP 或 FTL。该示例使用 Freemarker。如果我使用 ftl 页面,我的设置一切正常。但同样不适用于 .html 页面。
回答by FrontierPsychiatrist
You need to make the /login
endpoints publicly available (not authorized), users need to be able to login without being already logged in.
您需要/login
公开端点(未授权),用户需要能够在未登录的情况下登录。
The /oauth
endpoints mustbe secured.
该/oauth
端点必须是安全的。
Try the following
尝试以下
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login.html", "/logout.do").permitAll()
.antMatchers("/**").authenticated()
.and()
.formLogin()
.loginProcessingUrl("/login")
.loginPage("/login.html");
}
I have a spring-security-oauth example project on github, you can check it out here https://github.com/FrontierPsychiatrist/spring-oauth-example/.
我在 github 上有一个 spring-security-oauth 示例项目,你可以在这里查看https://github.com/FrontierPsychiatrist/spring-oauth-example/。
回答by Макс Н?к?т?н
First of all I was trying impl. OAuth Authorize with grand_type=implicit
首先,我正在尝试 impl。OAuth 授权,grand_type=implicit
I offer you to try follow steps for fix problems related with OAuth2 in Spring:
我建议您尝试按照以下步骤修复 Spring 中与 OAuth2 相关的问题:
- Necessary try to specify existing redirect_uri param; in OAuth2 specs it isn't required param but in spring app it should be present;
- Opened OAuth2 access for Spring Secure login page in WebSecurityConfigurerAdapter (you have already done this) is required:
- Try to make forvard ordering: @Order(-1)for extender of WebSecurityConfigurerAdapter. It fixed most of my problems in this question;
- 必要时尝试指定现有的 redirect_uri 参数;在 OAuth2 规范中,它不是必需的参数,但在 spring 应用程序中它应该存在;
- 需要在 WebSecurityConfigurerAdapter 中打开 Spring Secure 登录页面的 OAuth2 访问(您已经这样做了):
- 尽量让forvard排序:@Order(-1)为扩展WebSecurityConfigurerAdapter。它解决了我在这个问题中的大部分问题;
Ovveriden methods in the WebSecurityConfigurerAdapterextender:
WebSecurityConfigurerAdapter扩展器中的Oververiden方法:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.formLogin()
.permitAll()
.loginPage("/common/login.html")
.loginProcessingUrl("/login")
.failureUrl("/common/error.html")
.defaultSuccessUrl("/oauth/authorize")
.usernameParameter("j_username")
.passwordParameter("j_password")
.and()
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and().httpBasic().disable();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/common/**", "/v2/api-docs", "/configuration/ui", "/swagger-resources",
"/configuration/security", "/swagger-ui.html", "/webjars/**");
}