복붙노트

[SPRING] 봄 부팅 + Oauth2 클라이언트 자격 증명

SPRING

봄 부팅 + Oauth2 클라이언트 자격 증명

클라이언트 인증서 흐름 Oauth2 사용하여 스프링 부팅 내 마이크로 서비스를 보호하기 위해 노력하고 있습니다.

그건 그렇고, 그 microservices는 미들웨어 레이어를 통해 서로 이야기 할 것입니다, 나는 사용자 자격 증명이 승인 (페이스 북과 같은 사용자 로그인 프로세스)을 허용하는 데 필요하다는 것을 의미합니다.

필자는이 통신을 관리 할 수있는 권한 및 리소스 서버를 만드는 방법을 보여주는 인터넷 샘플을 모색했습니다. 그러나 나는 사용자 자격 증명 (세 다리)을 사용하여이를 수행하는 방법을 설명하는 예제를 발견했습니다.

누구든지 봄 부팅 및 Oauth2에서 수행하는 샘플을 가지고 있습니까? 가능한 범위에서 사용 된 범위에 대한 자세한 내용을 제공하면 토큰 교환이 감사하게 여겨집니다.

해결법

  1. ==============================

    1.Oauth2 클라이언트 자격 증명 체계로 보호 된 REST 서비스가 있습니다. 리소스 및 권한 부여 서비스는 동일한 응용 프로그램에서 실행되지만 다른 응용 프로그램으로 분할 될 수 있습니다.

    Oauth2 클라이언트 자격 증명 체계로 보호 된 REST 서비스가 있습니다. 리소스 및 권한 부여 서비스는 동일한 응용 프로그램에서 실행되지만 다른 응용 프로그램으로 분할 될 수 있습니다.

    @Configuration
    public class SecurityConfig {
    
    @Configuration
    @EnableResourceServer
    protected static class ResourceServer extends ResourceServerConfigurerAdapter {
    
        // Identifies this resource server. Usefull if the AuthorisationServer authorises multiple Resource servers
        private static final String RESOURCE_ID = "*****";
    
        @Resource(name = "OAuth")
        @Autowired
        DataSource dataSource;
    
        @Override
        public void configure(HttpSecurity http) throws Exception {
            // @formatter:off
            http    
                    .authorizeRequests().anyRequest().authenticated();
            // @formatter:on
        }
    
        @Override
        public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
            resources.resourceId(RESOURCE_ID);
            resources.tokenStore(tokenStore());
        }
    
        @Bean
        public TokenStore tokenStore() {
            return new JdbcTokenStore(dataSource);
        }
    }
    
    @Configuration
    @EnableAuthorizationServer
    protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
    
        @Resource(name = "OAuth")
        @Autowired
        DataSource dataSource;
    
        @Bean
        public TokenStore tokenStore() {
            return new JdbcTokenStore(dataSource);
        }
    
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            endpoints.tokenStore(tokenStore());
        }
    
        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            clients.jdbc(dataSource);
        }
    }
    }
    

    Oauth2 테이블에 대한 데이터 소스 구성 :

    @Bean(name = "OAuth")
    @ConfigurationProperties(prefix="datasource.oauth")
    public DataSource secondaryDataSource() {
        return DataSourceBuilder.create().build();
    }
    

    인증 및 리소스 서버와의 통신은 다음과 같이 진행됩니다.

    curl -H "Accept: application/json" user:password@localhost:8080/oauth/token -d grant_type=client_credentials
    curl -H "Authorization: Bearer token" localhost:8080/...
    

    다음 레코드는 Oauth2 데이터베이스에 있습니다.

    client_id  resource_ids  client_secret  scope  authorized_grant_types   web_server_redirect_uri  authorities  access_token_validity refresh_token_validity  additional_information  autoapprove
    user  ****  password  NULL  client_credentials  NULL  X  NULL  NULL  NULL  NULL
    

    클라이언트 응용 프로그램에서 Resttemplate 구성

    @Configuration
    @EnableOAuth2Client
    public class OAuthConfig {
    
    @Value("${OAuth2ClientId}")
    private String oAuth2ClientId;
    
    @Value("${OAuth2ClientSecret}")
    private String oAuth2ClientSecret;
    
    @Value("${Oauth2AccesTokenUri}")
    private String accessTokenUri;
    
    @Bean
    public RestTemplate oAuthRestTemplate() {
        ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails();
        resourceDetails.setId("1");
        resourceDetails.setClientId(oAuth2ClientId);
        resourceDetails.setClientSecret(oAuth2ClientSecret);
        resourceDetails.setAccessTokenUri(accessTokenUri);
    
        /*
    
        When using @EnableOAuth2Client spring creates a OAuth2ClientContext for us:
    
        "The OAuth2ClientContext is placed (for you) in session scope to keep the state for different users separate.
        Without that you would have to manage the equivalent data structure yourself on the server,
        mapping incoming requests to users, and associating each user with a separate instance of the OAuth2ClientContext."
        (http://projects.spring.io/spring-security-oauth/docs/oauth2.html#client-configuration)
    
        Internally the SessionScope works with a threadlocal to store variables, hence a new thread cannot access those.
        Therefore we can not use @Async
    
        Solution: create a new OAuth2ClientContext that has no scope.
        *Note: this is only safe when using client_credentials as OAuth grant type!
    
         */
    
    //        OAuth2RestTemplate restTemplate = new      OAuth2RestTemplate(resourceDetails, oauth2ClientContext);
        OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails, new DefaultOAuth2ClientContext());
    
        return restTemplate;
    }
    }
    

    restTemplate을 주입하여 Oauth2 보안 서비스와 (비동기 적으로) 대화 할 수 있습니다. 우리는 현재 범위를 사용하지 않습니다.

  2. from https://stackoverflow.com/questions/37534073/spring-boot-oauth2-client-credentials by cc-by-sa and MIT license