spring rest security oauth不支持授权类型

时间:2015-08-07 12:42:56

标签: spring rest oauth

我正在努力尝试配置弹簧安全和oauth。有人可能会说我不需要oauth这个简单的项目,但我想练习它。

我想从端点获取刷新和访问令牌,但是我收到错误: 不受支持的授权类型:密码。 我在网上搜索但找不到解决我特定问题的方法。

curl -u client:123456 http://localhost:8080/artwork/oauth/token -d 'grant_type=password&username=rest&password=rest' -X POST -H "Content-Type:application/x-www-form-urlencoded" -v

但是当我使用grant类型调用它时:client_credentials它会返回访问令牌,但正如我所提到的,我也需要刷新令牌。

这是我完全不了解整个oauth的az选项,但我正在阅读它。

@Autowired
private CustomUsersDetailService userDetailsService;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
    .withUser("rest")  
        .password("rest")
        .roles("REST")
        .and()
    .withUser("historian") 
        .password("historian")
        .roles("HIS");
}

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

private static final String RESOURCE_ID = "restservice";

@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends
        ResourceServerConfigurerAdapter {

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {         
        resources
            .resourceId(RESOURCE_ID);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {         
        http
        .authorizeRequests().antMatchers("/oauth/token").permitAll()
        .and()
        .authorizeRequests().antMatchers("/**").access("hasRole('ROLE_HIS') or hasRole('ROLE_REST')");                          
    }

}

@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends
        AuthorizationServerConfigurerAdapter {

    private TokenStore tokenStore = new InMemoryTokenStore();

    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Autowired
    private CustomUsersDetailService userDetailsService;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints)
            throws Exception {
        endpoints
            .tokenStore(this.tokenStore);

    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients
            .inMemory()
                .withClient("client")
                    .authorizedGrantTypes("password","refresh_token","client_credentials","authorization_code")
                    .authorities("ROLE_REST")
                    .scopes("read", "write")
                    .resourceIds(RESOURCE_ID)
                    .secret("123456");
    }

来自前端的代码,只是post方法:

 $scope.post = function() {

        var config = {
                 method: 'POST',
                 url: 'http://localhost:8080/artwork/oauth/token',
                 headers: {
                     'Content-Type': 'application/x-www-form-urlencoded',
                     'Authorization' : "Basic " + Base64.encode("client:123456")
                 },
                 params: {                      
                     grant_type: "password",
                     username: "rest",
                     password: "rest"
                 }
        }

        $http(config).success(onsuc).error(error);
    };

如果你看到任何东西,请告诉我。 谢谢!

2 个答案:

答案 0 :(得分:2)

您可以定义应包含RefreshTokenGranter的复合标记格式程序。此示例可以为您提供帮助。

@Configuration
@EnableAuthorizationServer
public class SecurityOauth2Config extends AuthorizationServerConfigurerAdapter  { 

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {

        endpoints
            .tokenServices(authorizationServerTokenServices())
            .tokenStore(tokenStore())
            .tokenGranter(tokenGranter())
            .requestFactory(oAuth2RequestFactory())
            .setClientDetailsService(clientDetailsJdbcService());

    }


    @Bean
    public TokenGranter tokenGranter() {

        ClientDetailsService clientDetails = clientDetailsJdbcService();
        AuthorizationServerTokenServices tokenServices = authorizationServerTokenServices();
        AuthenticationManager authenticationManager = authenticationManagerOauth2User();

        OAuth2RequestFactory oAuth2RequestFactory = oAuth2RequestFactory();

        List<TokenGranter> tokenGranters = new ArrayList<TokenGranter>();

        tokenGranters.add(new RefreshTokenGranter(tokenServices, clientDetails, oAuth2RequestFactory));
        tokenGranters.add(new ImplicitTokenGranter(tokenServices, clientDetails, oAuth2RequestFactory));
        tokenGranters.add(new ClientCredentialsTokenGranter(tokenServices, clientDetails, oAuth2RequestFactory));

        tokenGranters.add(new ResourceOwnerPasswordTokenGranter(authenticationManager, tokenServices,
                    clientDetails, oAuth2RequestFactory));

        return new CompositeTokenGranter(tokenGranters);
    }
...

答案 1 :(得分:0)

为了获取刷新令牌,您需要为客户端配置refresh_token授予类型。

@Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            // TODO Auto-generated method stub
            clients.inMemory()
            .withClient("foo")
            .secret("{noop}bar")
            .authorizedGrantTypes("password", "authorization_code", "refresh_token","client_credentials")

            .authorities("ROLE_CLIENT","ROLE_TRUSTED_CLIENT")

            .scopes("read", "write","trust","openid")

            .accessTokenValiditySeconds(120).//Access token is only valid for 2 minutes.

            refreshTokenValiditySeconds(600);//Refresh token is only valid for 10 minutes.

        }

以上代码是从another stackoverflow question提取的