복붙노트

[SPRING] Spring Security OAuth 2.0 - 인증 코드 부여에는 항상 클라이언트 비밀이 필요합니다.

SPRING

Spring Security OAuth 2.0 - 인증 코드 부여에는 항상 클라이언트 비밀이 필요합니다.

이 스펙에 따르면, 인증 코드 부여를 사용하는 토큰에 대한 요청은 client_id가 요청에 포함되어 있고 client_id가 코드를 생성하는 데 사용 된 것과 동일한 것이라면 인증 될 필요가 없습니다. 하지만 Spring Security OAuth 2.0 구현에서는 클라이언트가 비밀을 할당받지 않은 경우에도 기본 인증은 항상 / oauth / token 엔드 포인트에서 필요합니다.

ClientDetails 인터페이스에서 isSecretRequired () 메소드로 인해 비밀이없는 클라이언트를 허용하는 지원이있는 것처럼 보입니다. / oauth / token URL에서 비밀 번호없이 클라이언트를 인증하려면 어떻게해야합니까?

해결법

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

    1.기본 인증 대신 양식 매개 변수를 사용하여 클라이언트를 인증하는 것은 아래 코드 샘플에서와 같이 allowFormAuthenticationForClients () 메소드를 사용하여 활성화됩니다.

    기본 인증 대신 양식 매개 변수를 사용하여 클라이언트를 인증하는 것은 아래 코드 샘플에서와 같이 allowFormAuthenticationForClients () 메소드를 사용하여 활성화됩니다.

    class AuthorizationServerConfigurer extends AuthorizationServerConfigurerAdapter {
    
        @Override
        void configure(AuthorizationServerSecurityConfigurer security) {
            security
                    .tokenKeyAccess("permitAll()")
                    .checkTokenAccess("isAuthenticated()")
                    .allowFormAuthenticationForClients()
        }
    }
    

    allowFormAuthenticationForClients () 메서드는 폼 매개 변수를 통한 인증을 허용하는 ClientCredentialsTokenEndpointFilter를 추가로 트리거합니다.

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

    2.Spring은 빈 비밀로 OAuth2 클라이언트를 정의 할 수있게 해준다. 이들은 "공개"클라이언트 또는 비밀을 유지할 수없는 클라이언트로 간주 될 수 있습니다. Javascript 앱, 모바일 앱 등을 생각해보십시오. 일반적으로 클라이언트 비밀번호를 저장하고 싶지는 않습니다.

    Spring은 빈 비밀로 OAuth2 클라이언트를 정의 할 수있게 해준다. 이들은 "공개"클라이언트 또는 비밀을 유지할 수없는 클라이언트로 간주 될 수 있습니다. Javascript 앱, 모바일 앱 등을 생각해보십시오. 일반적으로 클라이언트 비밀번호를 저장하고 싶지는 않습니다.

    OAuth2 스펙에 따르면, 토큰 엔드 포인트는 이러한 공용 클라이언트에 대한 암호가 필요하지 않도록 선택할 수 있습니다.

    따라서 봄에는 빈 비밀을 가진 OAuth2 클라이언트를 정의하고 제한된 권한 유형 (authorization_code 및 refresh_token)에 맞게 구성하십시오.

    스프링 보안 구현 토큰 url은 특정 OAuth2 클라이언트에 대한 클라이언트 비밀이없는 토큰 교환을 허용합니다.

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

    3.처음에는 필자가 수락 한 대답과 비슷한 설정을 사용했는데, 이는 분명히이 작업을 수행하기위한 전제 조건입니다. 하지만 누락 된 점은 단순히 암호를 null로 설정할 수 없다는 것입니다. 다음과 같이 빈 암호로 설정해야합니다.

    처음에는 필자가 수락 한 대답과 비슷한 설정을 사용했는데, 이는 분명히이 작업을 수행하기위한 전제 조건입니다. 하지만 누락 된 점은 단순히 암호를 null로 설정할 수 없다는 것입니다. 다음과 같이 빈 암호로 설정해야합니다.

    String secret = PasswordEncoderFactories.createDelegatingPasswordEncoder().encode("");
    clientDetails.setClientSecret(secret);
    

    당신이 이것을하지 않으면, 당신은 여전히 ​​401을 얻을 것이다!

  4. ==============================

    4.이렇게 :

    이렇게 :

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("client").secret(PasswordEncoderFactories.createDelegatingPasswordEncoder().encode("")) //empty
                .authorizedGrantTypes("authorization_code", "refresh_token")
                .redirectUris("http://www.dev.com")
                .scopes("all")
                .autoApprove(true);
    } @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer)
            throws Exception {
        oauthServer.tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()")
                .allowFormAuthenticationForClients();
    }
    

    괜찮아요.

  5. from https://stackoverflow.com/questions/35785628/spring-security-oauth-2-0-client-secret-always-required-for-authorization-code by cc-by-sa and MIT license