복붙노트

[SPRING] Spring 보안 OAuth2 자원 서버 항상 잘못된 토큰 반환

SPRING

Spring 보안 OAuth2 자원 서버 항상 잘못된 토큰 반환

스프링 라이브러리를 사용하여 기본 메모리 내 OAuth2 서버를 실행하려고합니다. 나는 sparklr 예제를 따라왔다.

현재 서버를 구성했으며 거의 ​​모든 것이 작동하지만 리소스 서버에서 제한된 리소스에 액세스 할 수 없습니다.

내 테스트 워크 플로 :

나는 정말로 내가 뭘 잘못하고 있는지 확실하지 않지만, 제한된 URI에 접근하는 것 이외의 모든 것이 작동하고있는 것 같습니다. 여기 내 구성은 다음과 같습니다.

@Configuration
public class Oauth2ServerConfiguration {

    private static final String SERVER_RESOURCE_ID = "oauth2-server";

    @Configuration
    @EnableResourceServer
    protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

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

        @Override
        public void configure(HttpSecurity http) throws Exception {
            http
                .sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                .and().requestMatchers()
                    .antMatchers("/me")
                .and().authorizeRequests()
                    .antMatchers("/me").access("#oauth2.clientHasRole('ROLE_CLIENT')")
            ;
        }
    }

    @Configuration
    @EnableAuthorizationServer
    protected static class AuthotizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

        @Autowired
        private ClientDetailsService clientDetailsService;

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

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            clients.inMemory()
                .withClient("client")
                    .resourceIds(SERVER_RESOURCE_ID)
                    .secret("secret")
                    .authorizedGrantTypes("authorization_code", "refresh_token")
                    .authorities("ROLE_CLIENT")
                    .scopes("read","write")
                    .redirectUris("http://localhost:8080/client")
                    .accessTokenValiditySeconds(300)
                    .autoApprove(true)
            ;
        }

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

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

        @Override
        public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
            oauthServer.realm("oauth");
        }

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

        @Bean
        public UserApprovalHandler userApprovalHandler() throws Exception {
            TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
            handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
            handler.setClientDetailsService(clientDetailsService);
            handler.setTokenStore(tokenStore());

            return handler;
        }
    }
}

내가 누락 된 것이 있거나 잘못 접근하고 있습니까? 어떤 도움이라도 대단히 감사하겠습니다.

해결법

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

    1.문제는 리소스 서버와 권한 서버가 동일한 토큰 저장소 참조를 가져 오지 못하는 것입니다. 배선이 제대로 작동하지 않았는지 확실하지 않지만 구성 클래스의 고정 된 개체를 사용하는 것이 매력처럼 작동했습니다. 궁극적으로, 나는 지장없는 토큰 저장소로 옮길 것이다. 토큰 저장소는 아무런 문제가 없을 것이다.

    문제는 리소스 서버와 권한 서버가 동일한 토큰 저장소 참조를 가져 오지 못하는 것입니다. 배선이 제대로 작동하지 않았는지 확실하지 않지만 구성 클래스의 고정 된 개체를 사용하는 것이 매력처럼 작동했습니다. 궁극적으로, 나는 지장없는 토큰 저장소로 옮길 것이다. 토큰 저장소는 아무런 문제가 없을 것이다.

    @OhadR에게 감사의 말을 전합니다!

    궁극적으로 구성을 단순화하고 동일한 워크 플로를 거치며 해결했습니다.

    @Configuration
    public class Oauth2ServerConfiguration {
    
        private static final String SERVER_RESOURCE_ID = "oauth2-server";
    
        private static InMemoryTokenStore tokenStore = new InMemoryTokenStore();
    
    
        @Configuration
        @EnableResourceServer
        protected static class ResourceServer extends ResourceServerConfigurerAdapter {
    
            @Override
            public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
                resources.tokenStore(tokenStore).resourceId(SERVER_RESOURCE_ID);
            }
    
            @Override
            public void configure(HttpSecurity http) throws Exception {
                http.requestMatchers().antMatchers("/me").and().authorizeRequests().antMatchers("/me").access("#oauth2.hasScope('read')");
            }
        }
    
        @Configuration
        @EnableAuthorizationServer
        protected static class AuthConfig extends AuthorizationServerConfigurerAdapter {
    
            @Autowired
            private AuthenticationManager authenticationManager;
    
    
            @Override
            public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
                endpoints.authenticationManager(authenticationManager).tokenStore(tokenStore).approvalStoreDisabled();
            }
    
            @Override
            public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
                clients.inMemory()
                    .withClient("client")
                        .authorizedGrantTypes("authorization_code","refresh_token")
                        .authorities("ROLE_CLIENT")
                        .scopes("read")
                        .resourceIds(SERVER_RESOURCE_ID)
                        .secret("secret")
                ;
            }
        }
    }
    

    이 게시물에 걸린 사람이라면 필자는 필연적으로 시작하지 않아도되는 추가 구성이 많기 때문에 예를 들어 단위 테스트를 더 많이 보길 권장합니다.

  2. ==============================

    2.6 단계가 잘못되었습니다. 액세스 토큰은 URL에서 전송되지 않아야합니다. 취약성이 있기 때문입니다. GET보다는 rathen, POST를 사용하십시오.

    6 단계가 잘못되었습니다. 액세스 토큰은 URL에서 전송되지 않아야합니다. 취약성이 있기 때문입니다. GET보다는 rathen, POST를 사용하십시오.

    게다가, 나는 당신의 1 단계를 이해하지 못합니다 - 왜 당신은 / oauth / authorize를 부를까요? 보호 된 리소스를 얻으려고하면 암시 적으로 수행해야합니다. 내 말은, 당신의 흐름은 다음과 같이 시작해야합니다.

    그러면 협상은 "뒤에서"시작됩니다 : "/ oauth / authorize"로 리다이렉트

    또한 # 8 단계에서 "다른 액세스 토큰"을 묻지 않고 "새로 고침 토큰"을 요청합니다. 마치 액세스 토큰이 만료 된 것 같습니다.

    참고 : ID 공급자와 리소스 서버는 토큰 저장소를 공유해야합니다. 여기서 읽기 : 스프링 보안 OAuth2 순수 리소스 서버

    HTH

  3. ==============================

    3.이 작품은 나를 위해 :

    이 작품은 나를 위해 :

    @Configuration
    public class Oauth2ServerConfiguration {
    
        private static final String SERVER_RESOURCE_ID = "oauth2-server";
    
        @Autowired
        private TokenStore tokenStore;
    
        @Bean
        public TokenStore tokenStore() {
            return new InMemoryTokenStore();
        }
    
        @Configuration
        @EnableResourceServer
        protected static class ResourceServer extends ResourceServerConfigurerAdapter {
    
            @Override
            public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
                resources.tokenStore(tokenStore).resourceId(SERVER_RESOURCE_ID);
            }
    
            @Override
            public void configure(HttpSecurity http) throws Exception {
                // ... Not important at this stage
            }
        }
    
        @Configuration
        @EnableAuthorizationServer
        protected static class AuthConfig extends AuthorizationServerConfigurerAdapter {
    
            @Autowired
            private AuthenticationManager authenticationManager;
    
    
            @Override
            public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
                endpoints.authenticationManager(authenticationManager).tokenStore(tokenStore).approvalStoreDisabled();
            }
    
            @Override
            public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
                //... Not important at this stage
            }
        }
    }
    
  4. from https://stackoverflow.com/questions/29596036/spring-security-oauth2-resource-server-always-returning-invalid-token by cc-by-sa and MIT license