如何在Spring安全性中自定义OAuth服务提供程序?

时间:2016-04-06 13:47:16

标签: java spring spring-mvc oauth spring-security

我正在使用Spring启动应用程序,我有其他控制器。我刚开始在春天使用OAuth 2.0来保护我的API。以下是我的配置类。

@Configuration
@EnableResourceServer
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter  {

    private static final String HU_REST_RESOURCE_ID = "rest_api";

    @Autowired
    DataSource dataSource;

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


    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.resourceId(HU_REST_RESOURCE_ID).stateless(false);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {

    //define URL patterns to enable OAuth2 security 

        http.
        requestMatchers().antMatchers("/user/**").and().
        authorizeRequests().antMatchers("/user/**").access("#oauth2.hasScope('read') or (!#oauth2.isOAuth() and hasRole('ROLE_USER'))");
    }

}

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter  {


    @Autowired
    DataSource dataSource;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {


    clients.inMemory()
              .withClient("my-trusted-client")
                .authorizedGrantTypes("password","refresh_token")
                .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
                .scopes("read", "write", "trust")
                .accessTokenValiditySeconds(60)
                .refreshTokenValiditySeconds(600)
        .and()
              .withClient("my-trusted-client-with-secret")
                .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
                .authorities("ROLE_USER")
                .scopes("read", "write", "trust")
                .accessTokenValiditySeconds(60)
                .refreshTokenValiditySeconds(600);
    }


    @Bean
    public TokenStore tokenStore() {
        return new JdbcTokenStore(dataSource); // access and refresh tokens will be maintain in database
    }

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

    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer.allowFormAuthenticationForClients();
    }

}


@Configuration
public class GlobalAuthenticationConfig extends GlobalAuthenticationConfigurerAdapter {

    @Override
    public void init(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("user1").password("user1123").roles("USER");
         auth.inMemoryAuthentication().withUser("user2").password("user2123").roles("ADMIN");
    }
}

现在,当我点击网址http://localhost:8080/oauth/token?grant_type=password&client_id=my-trusted-client-with-secret&username=user1&password=user1123时,我会获得以下访问令牌并刷新令牌,

{
    "access_token": "87379d65-6012-4484-ba6f-e4c61766ede3",
    "token_type": "bearer",
    "refresh_token": "8b0d0ae3-0855-4465-9d89-a1c31c031b8a",
    "expires_in": 59,
    "scope": "read write trust"
}

我的问题是为什么有人会将凭据作为查询参数传递?我们可以发出一个帖子请求并将一个对象中的必需参数作为POST请求发送吗?如果是,我该怎么办? 我的第二个问题是,我在这里使用内存认证,即两个用户在代码中被硬编码。如何从数据库中检查用户凭据?

1 个答案:

答案 0 :(得分:0)

当您使用https(您应该)时,完整查询在通过网络发送之前会被加密,如下所述: Are querystring parameters secure in HTTPS (HTTP + SSL)?

关于第二个问题,如果您希望Spring从数据库中检查授权用户,则必须创建一个继承自UserDetailsManager http://docs.spring.io/autorepo/docs/spring-security/4.0.3.RELEASE/apidocs/org/springframework/security/provisioning/UserDetailsManager.html

的类。

然后,您可以实现其不同的方法,特别是loadUserByUsername(String username)UserDetailsService(由Spring身份验证管理器使用)实现的方法,以及向数据库查询相关数据的代码。

这个问题描述了如何将该管理器添加到Spring应用程序How to make a UserDetailsManager available as a bean