Spring Security OAuth - 访问此资源需要完全身份验证

时间:2016-07-09 08:06:27

标签: java spring spring-security oauth-2.0

以下是我的授权服务器配置:

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()");
    }

}

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();

    }
}

现在,从客户端应用程序,当我尝试访问安全资源时,它会重定向到授权服务器,但是我收到以下错误:

<oauth>
<error_description>
Full authentication is required to access this resource
</error_description>
<error>unauthorized</error>
</oauth>

在基本身份验证的情况下,相同的设置运行良好。当我切换到表单登录时,我遇到了问题。

更新

以下网络安全设置有效。

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();

现在,我能够看到登录页面,我也可以登录,但是登录后,客户端无法获得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

我能够看到以下服务器日志

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

更新2

以下是我的客户端配置。

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

更新3

该代码可在以下repo中找到

https://github.com/pavan496/insol-test

3 个答案:

答案 0 :(得分:10)

您需要公开/oauth个终端(未经授权),用户需要能够在未登录的情况下登录。

@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"); } 端点必须受到保护。

尝试以下

public static Bitmap getScaledBitmap(Bitmap b, int reqWidth, int reqHeight)
        {
            Matrix m = new Matrix();
            m.setRectToRect(new RectF(0, 0, b.getWidth(), b.getHeight()), new RectF(0, 0, reqWidth, reqHeight), Matrix.ScaleToFit.CENTER);
            return Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, true);
        }

//call this method like
    Bitmap bmp=getScaledBitmap(bm,50,50);

我在github上有一个spring-security-oauth示例项目,你可以在这里查看https://github.com/FrontierPsychiatrist/spring-oauth-example/

答案 1 :(得分:2)

我想我弄清楚问题是什么。

我在github上看到了以下示例,其中使用了基于表单的身份验证机制(这是我正在寻找的)。

https://github.com/spring-guides/tut-spring-security-and-angular-js/

如果我使用非HTML页面作为我的登录页面,确切的代码工作正常。例如,JSP或FTL。该示例使用Freemarker。如果我使用ftl页面,我的设置一切正常。但是.html页面的情况也是如此。

答案 2 :(得分:0)

首先,我正在尝试impl。 OAuth使用 grand_type = implicit

进行授权

我建议您尝试按照以下步骤解决与Spring中OAuth2相关的修复问题:

  1. 必须尝试指定现有的redirect_uri参数;在OAuth2规范中,它不是必需的参数,但在春季应用程序中它应该存在;
  2. 需要在WebSecurityConfigurerAdapter中打开Spring Secure登录页面的OAuth2访问权限(您已经这样做了):
  3. 尝试进行forvard排序: @Order(-1) ,用于 WebSecurityConfigurerAdapter 的扩展程序。它解决了我在这个问题上的大部分问题;
  4. WebSecurityConfigurerAdapter 扩展程序中的Ovveriden方法:

        @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/**");
        }