如何使用Spring Boot OAuth2保护Rest API

时间:2017-03-22 12:03:30

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

我想创建一个带有OAuth2 集成的示例 Spring Boot应用程序,该应用程序具有 CustomTokenEnhancer ,并且它应该将/ oauth / token URL暴露给客户端而不使用访问令牌但是所有只有具有有效访问令牌的其他URL才能被查询。

我可以设置CustomTokenEnhancer,通过它我可以在请求/ oauth / token时发送额外的东西。

Project Structure
Application.java - Spring Boot Application类
AuthorizationServerConfiguration.java - 授权服务器
ResourceServer.java - 资源服务器
OAuth2SecurityConfiguration.java - 扩展WebSecurityConfigurerAdapter并在内存中定义用户
CustomTokenEnhancer.java - 使用访问令牌发送其他内容,例如Cookie

在OAuth2SecurityConfiguration.java中,我正在配置3个URL,/ oauth / token可以被拥有clientId和secret的任何人查询,一旦你拥有访问令牌。客户应该能够查询我的案例/test/inventory/sku/{skuID}

中的所有其他网址
protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests().antMatchers("/oauth/token").permitAll().antMatchers("/inventory/**","/test").hasAnyRole("USER","ADMIN");

}

但是当我查询/测试或/ inventory / sku / 1100时,我正在禁用401.

我需要帮助才能使两个URL / test和/ inventory / sku / 1100只能使用访问令牌和/ oauth / token而不使用访问令牌。

OAuth2SecurityConfiguration.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.approval.ApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;

@Configuration
@EnableWebSecurity
public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {

    public OAuth2SecurityConfiguration() {
        System.out.println("OAuth2SecurityConfiguration()");
    }

    @Autowired
    private ClientDetailsService clientDetailsService;

    @Autowired
    public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {

        System.out.println("OAuth2SecurityConfiguration globalUserDetails() ,invoke BJSCustomAuthentication");

        auth.inMemoryAuthentication() // authenticationProvider(new
                                        // BJsCustomAuthentication());
                .withUser("bill").password("abc123").roles("ADMIN").and().withUser("bob").password("abc123")
                .roles("USER");
    }

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

        http.authorizeRequests().antMatchers("/oauth/token").permitAll().antMatchers("/inventory/**","/test").hasAnyRole("USER","ADMIN");
        //http.authorizeRequests().antMatchers(HttpMethod.OPTIONS).permitAll().anyRequest().authenticated().and()
            //  .httpBasic().and().csrf().disable();

    }

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

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

    @Bean
    @Autowired
    public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore) {
        TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
        handler.setTokenStore(tokenStore);
        handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
        handler.setClientDetailsService(clientDetailsService);
        return handler;
    }

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

}

AuthorizationServer.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
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.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

    public AuthorizationServerConfiguration() {

        System.out.println("AuthorizationServerConfiguration()");
    }

    @Autowired
    AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        System.out.println("AuthorizationServerConfiguration configure()");

        //endpoints.authenticationManager(authenticationManager).tokenEnhancer(tokenEnhancer()).tokenStore(tokenStore());

        endpoints.authenticationManager(authenticationManager);
    }

    /*@Bean
    public TokenEnhancer tokenEnhancer() {
        return new CustomTokenEnhancer();
    }

    @Bean
    public TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }*/

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

        System.out.println("OAUTH CLIENT CONFIGURED in AuthorizationServerConfiguration !!!");

        clients.inMemory().withClient("my-trusted-client")
        .authorizedGrantTypes("password", "authorization_code",
                "refresh_token", "implicit")
        .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
        .scopes("read", "write", "trust").resourceIds("sparklr")
        .accessTokenValiditySeconds(60).
        and()
        .withClient("my-client-with-registered-redirect")
        .authorizedGrantTypes("authorization_code").authorities("ROLE_CLIENT")
        .scopes("read", "trust").resourceIds("sparklr")
        .redirectUris("http://anywhere?key=value").
        and()
        .withClient("angular") //my-client-with-secret
        .authorizedGrantTypes("password","refresh")
        .authorities("ROLE_CLIENT").scopes("read","write").resourceIds("sparklr").accessTokenValiditySeconds(100)
        .secret("secret");
    }


}

CustomTokenEnhancer.java

import java.util.HashMap;
import java.util.Map;

import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;

public class CustomTokenEnhancer implements TokenEnhancer {

    public CustomTokenEnhancer() {
        System.out.println("CustomTokenEnhancer()");
    }

    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {

        System.out.println("Custom Token Enhancer Initialized");

        WCSResponse wcsResponse = (WCSResponse) authentication.getPrincipal();
        authentication.getOAuth2Request().getRequestParameters();

        final Map<String, Object> additionalInfo = new HashMap<>();

        additionalInfo.put("wcsResponse", wcsResponse);

        ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);

        return accessToken;
    }

}

0 个答案:

没有答案