无法使用正确的访问令牌访问OAuth2 secred资源

时间:2015-07-03 16:46:11

标签: spring-security oauth-2.0 spring-security-oauth2

我正在使用Spring 4.1.5.RELEASE,Spring Security 3.2.5.RELEASE和OAuth2 2.0.7.RELEASE。我正在使用JdbcTokenStore并在我的oauth_client_details表中使用它...

client_id = dave
resource_ids = /dashboard
scope = read,write,delete
authorized_grant_types = implicit,password,client_credentials
web_server_redirect_uri = /redirect
authorities = ROLE1,ROLE2,ROLE3
access_token_validity = 3600
refresh_token_validity = 3600

但是我无法访问我的安全资源/仪表板。下面我发出获取访问令牌的请求......

Daves-MacBook-Pro:biv2 davea$ curl -v -d grant_type=password \
        -d username=ROLE3 \
        -d password=dave \
        -u dave:davesecret \
        http://localhost:8080/mycontext-path/oauth/token
*   Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
* Server auth using Basic with user 'dave'
> POST /mycontext-path/oauth/token HTTP/1.1
> Authorization: Basic YmltOmJpbXNlY3JldA==
> User-Agent: curl/7.40.0
> Host: localhost:8080
> Accept: */*
> Content-Length: 50
> Content-Type: application/x-www-form-urlencoded
> 
* upload completely sent off: 50 out of 50 bytes
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Cache-Control: no-store
< Pragma: no-cache
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Fri, 03 Jul 2015 16:33:39 GMT
< 
* Connection #0 to host localhost left intact
{"access_token":"2648069d-607d-449d-af10-cb38d5fd7614","token_type":"bearer","expires_in":470,"scope":"delete read write"}

然后我尝试使用该访问令牌来获取我的资源/仪表板,但我正在重定向到我的登录页面......

Daves-MacBook-Pro:biv2 daveacurl -v -H 'Authorization: Bearer 2648069d-607d-449d-af10-cb38d5fd7614' http://localhost:8080/mycontext-path/dashboard
*   Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
> GET /mycontext-path/dashboard HTTP/1.1
> User-Agent: curl/7.40.0
> Host: localhost:8080
> Accept: */*
> Authorization: Bearer 2648069d-607d-449d-af10-cb38d5fd7614
> 
< HTTP/1.1 302 Found
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Set-Cookie: JSESSIONID=1EF45E8864F5A03CA0D2895E8E851E87; Path=/mycontext-path/; HttpOnly
< Location: http://localhost:8080/mycontext-path/login
< Content-Length: 0
< Date: Fri, 03 Jul 2015 16:34:06 GMT
< 
* Connection #0 to host localhost left intact

我错过了什么?以下是我配置OAuth2Config以及Spring安全配置的方法。

@Configuration
@ComponentScan
@EnableAutoConfiguration
@RestController
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Configuration
    @EnableAuthorizationServer
    // [1]
    protected static class OAuth2Config extends
            AuthorizationServerConfigurerAdapter {

        @Autowired
        private AuthenticationManager authenticationManager;
        @Autowired
        private DataSource dataSource;
        @Autowired
        private PasswordEncoder passwordEncoder;
        @Autowired
        private ClientDetailsService clientDetailsService;
        @Autowired
        private TokenStore tokenStore;

        @Override
        // [2]
        public void configure(AuthorizationServerEndpointsConfigurer endpoints)
                throws Exception {
            endpoints.tokenStore(tokenStore)
            .userApprovalHandler(userApprovalHandler())
            .authenticationManager(authenticationManager);
        }

        @Override
        // [3]
        public void configure(ClientDetailsServiceConfigurer clients)
                throws Exception {
            // @formatter:off
            clients.jdbc(dataSource);
        }

        @Bean
        public TokenStore tokenStore() {
            return new JdbcTokenStore(dataSource);
        }

        @Bean
        public TokenApprovalStore tokenApprovalStore() {
            TokenApprovalStore tokenApprovalStore = new TokenApprovalStore();
            tokenApprovalStore.setTokenStore(tokenStore);
            return tokenApprovalStore;
        }

        @Bean
        public OAuth2RequestFactory getOauth2RequestFactory()
        {
            return new DefaultOAuth2RequestFactory(clientDetailsService);
        }   // getOauth2RequestFactory

        @Bean
        public UserApprovalHandler userApprovalHandler() {
            final TokenStoreUserApprovalHandler userApprovalHandler = new TokenStoreUserApprovalHandler();
            userApprovalHandler.setRequestFactory(getOauth2RequestFactory());
            userApprovalHandler.setTokenStore(tokenStore);
            return userApprovalHandler;
        }   // userApprovalHandler

        @Override
        public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
            oauthServer.realm("abcdefgh/client");
        }       
    }
}

Spring安全配置:

@Configuration
@EnableWebSecurity
@ComponentScan(basePackages="com.myproject", excludeFilters=@ComponentScan.Filter(Controller.class))
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private static final String ROLE1 = "ROLE1";
    private static final String ROLE2 = "ROLE2";
    private static final String ROLE3 = "ROLE3";

    @Resource(name="userDetailsService")
    private UserDetailsService userDetailsService;

    @Resource(name="jsonAuthenticationSuccessHandler")
    private daveAuthenticationSuccessHandler authSuccessHandler;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.addFilterBefore(authenticationFilter(), JSONUsernamePasswordAuthenticationFilter.class);
        http
            .authorizeRequests()
                .antMatchers("/403").permitAll()
                .antMatchers("/login/**").permitAll()
                .antMatchers("/resources/**").permitAll()
                // TODO: Add secured patterns
                .antMatchers("/ROLE3/**").hasRole(ROLE3)
                .antMatchers("/common/**").hasAnyRole(ROLE3, ROLE2, ROLE1)
                .antMatchers("/ROLE1/**").hasAnyRole(ROLE3, ROLE2, ROLE1)
                .antMatchers("/ROLE2/**").hasAnyRole(ROLE3, ROLE2)
                // Allow access to all other resources only if authenticated
                .antMatchers("/*/**").fullyAuthenticated()
            .and().formLogin()
                .loginPage("/login")
                .failureUrl("/login?error")
                .usernameParameter("username")
                .passwordParameter("password")
                .successHandler(authSuccessHandler)
            .and().logout().logoutSuccessUrl("/login?logout")
            .and().exceptionHandling().accessDeniedPage("/403")
            .and().csrf().disable();
    }

    @Bean(name="passwordEncoder")
    public PasswordEncoder passwordEncoder() {
        return new StandardPasswordEncoder();
    }

    @Bean
    public JSONUsernamePasswordAuthenticationFilter authenticationFilter() throws Exception {
        final JSONUsernamePasswordAuthenticationFilter authFilter = new JSONUsernamePasswordAuthenticationFilter();
        //authFilter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/login","POST"));
        authFilter.setAuthenticationManager(authenticationManagerBean());
        authFilter.setAuthenticationSuccessHandler(authSuccessHandler);
        authFilter.setUsernameParameter("username");
        authFilter.setPasswordParameter("password");
        return authFilter;
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

}

1 个答案:

答案 0 :(得分:0)

在OAuth2中受保护的资源是ResourceServer的一部分。

spring-security-oauth2使用OAuth2AuthenticationProcessingFilter来处理OAuth2身份验证。

您的@EnableWebSecurity课程中

SecurityConfig是不够的。

您需要使用@EnableResourceServer对其进行注释,并且扩展ResourceServerConfigurerAdapter可以更轻松地配置相应的http安全性。

请参阅Reference documentation