使用spring security验证oauth2访问令牌

时间:2017-03-13 11:58:59

标签: spring-boot spring-security

我有一个以下设置,所有进程都在不同的机器上运行,它们之间没有共同的数据库。

1.Resource server(my protected resources)
2.authorization server(WS02--> for Issuing OAuth tokens)
3.client Application(trying to access the resource server)

ClientApp联系授权服务器并获取访问令牌,并使用此令牌联系资源服务器。如何验证访问令牌@resource服务器?

我的授权服务器提供REST API,我可以在其中提供访问令牌作为输入并检查令牌的有效性。

我是Spring的新手,所以如果在提供资源内容之前有任何内置的API /回调来验证令牌,那么我就不会这样做。有关如何验证令牌@resource服务器的任何指示都会有所帮助。

1 个答案:

答案 0 :(得分:0)

client App尝试访问resource server时,资源服务器会咨询Auth server并验证访问令牌。

资源服务器上的配置:

<bean id="tokenServices"  class="org.springframework.security.oauth2.provider.token.RemoteTokenServices">
    <property name="checkTokenEndpointUrl" value="http://localhost:8181/OUTPOST/oauth/check_token"/>
    <property name="clientId" value="atlas"/>
    <property name="clientSecret" value="atlas"/>
</bean>

在资源服务器上使用RemoteTokenService代替DefaultTokenService oauth / check_token 是连接资源服务器和auth-server的端点。

在auth服务器上配置

@EnableAuthorizationServer
@Configuration
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

private static String REALM = "OUTPOST_API";

private ClientDetailsService clientService;

@Autowired
public AuthorizationServerConfig(AuthenticationManager authenticationManager,
        RedisConnectionFactory redisConnectionFactory, ClientDetailsService clientService) {
    this.authenticationManager = authenticationManager;
    this.redisTokenStore = new RedisTokenStore(redisConnectionFactory);
    this.clientService = clientService;
}

private AuthenticationManager authenticationManager;

private TokenStore redisTokenStore;

@Autowired
private UserApprovalHandler userApprovalHandler;

@Autowired
private RedisConnectionFactory redisConnectionFactory;

@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {

    security.tokenKeyAccess("isAuthenticated()").checkTokenAccess("isAuthenticated()")
            .allowFormAuthenticationForClients().realm(REALM + "/client");
}

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {        
    clients.withClientDetails(clientService);
}

@Bean
@Autowired
public TokenStore tokenStore(RedisConnectionFactory redisConnectionFactory) {
    this.redisTokenStore = new RedisTokenStore(redisConnectionFactory);
    return this.redisTokenStore;
}

@Bean
public WebResponseExceptionTranslator loggingExceptionTranslator() {
    return new DefaultWebResponseExceptionTranslator() {
        @Override
        public ResponseEntity<OAuth2Exception> translate(Exception e) throws Exception {
            // This is the line that prints the stack trace to the log. You can customise
            // this to format the trace etc if you like
            e.printStackTrace();

            // Carry on handling the exception
            ResponseEntity<OAuth2Exception> responseEntity = super.translate(e);
            HttpHeaders headers = new HttpHeaders();
            headers.setAll(responseEntity.getHeaders().toSingleValueMap());
            OAuth2Exception excBody = responseEntity.getBody();
            return new ResponseEntity<>(excBody, headers, responseEntity.getStatusCode());
        }
    };
}

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    endpoints.tokenStore(redisTokenStore).userApprovalHandler(userApprovalHandler)
            .authenticationManager(authenticationManager).exceptionTranslator(loggingExceptionTranslator());
}

public void setRedisConnectionFactory(RedisConnectionFactory redisConnectionFactory) {
    this.redisConnectionFactory = redisConnectionFactory;
}

@Bean
public TokenStoreUserApprovalHandler userApprovalHandler() {
    TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
    handler.setTokenStore(redisTokenStore);
    handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientService));
    handler.setClientDetailsService(clientService);
    return handler;
}

@Bean
@Autowired
public ApprovalStore approvalStore() throws Exception {
    TokenApprovalStore store = new TokenApprovalStore();
    store.setTokenStore(redisTokenStore);
    return store;
}

@Bean
@Primary
@Autowired
public DefaultTokenServices tokenServices() {
    DefaultTokenServices tokenServices = new DefaultTokenServices();
    tokenServices.setSupportRefreshToken(true);
    tokenServices.setTokenStore(redisTokenStore);
    return tokenServices;
}

}

@Component
class MyOAuth2AuthenticationEntryPoint extends OAuth2AuthenticationEntryPoint {
}
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

private MyOAuth2AuthenticationEntryPoint authenticationEntryPoint;

private AccessDecisionManager accessDecisionManager;

private MongoDBAuthenticationProvider authenticationProvider;

@Autowired
public SecurityConfiguration( MyOAuth2AuthenticationEntryPoint authenticationEntryPoint,AccessDecisionManager accessDecisionManager, MongoDBAuthenticationProvider authenticationProvider) {
    this.authenticationEntryPoint = authenticationEntryPoint; 
    this.accessDecisionManager = accessDecisionManager;
    this.authenticationProvider = authenticationProvider;
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
    /*.addFilterAfter(
              new CustomFilter(), BasicAuthenticationFilter.class)*/
    .csrf().disable()
    .anonymous().disable()
    .authorizeRequests()
    .antMatchers("/oauth/token").fullyAuthenticated()
    .and()
    .httpBasic()
    .authenticationEntryPoint(authenticationEntryPoint)
    .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());

    http
    /*.addFilterAfter(
              new CustomFilter(), BasicAuthenticationFilter.class)*/
    .csrf().disable()
    .anonymous().disable()
    .authorizeRequests()
    .antMatchers("/oauth/check_token").fullyAuthenticated()
    .and()
    .httpBasic()
    .authenticationEntryPoint(authenticationEntryPoint)
    .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler())
    .and()
    .authorizeRequests()
    .anyRequest()
    .authenticated()
    .accessDecisionManager(accessDecisionManager);
}

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(authenticationProvider)
    /*.inMemoryAuthentication()
    .withUser("javabycode").password("123456").roles("USER")
    .and()
    .withUser("admin").password("admin123").roles("ADMIN");*/;
}     
}