OAuth2 Redirect 주소 문제 해결

작성: 2022.06.20

수정: 2022.06.20

읽는시간: 00 분

Development/Daily Error

반응형

Intro

특정 사이트의 OAuth 로그인이 정상적으로 이루어지지 않고 있는 이슈가 접수되었습니다.

등록된 리다이렉트 URI와 일치하지 않다는 에러가 발생하고 있었고, 확인을 해 보니 등록된 리다이렉트 URL도, 실제 사용 중인 프로토콜도 https 인데, 리다이렉트 uri가 자꾸 http 로 시작하는 주소가 넘어가고 있었습니다.

문제

현 설정은 아래와 같습니다.

application.yaml

oauth2:
    clientA:
        clientId: ${clientA_CLIENTID}
        clientSecret: ${clientA_SECRET}
        accessTokenUri: ${clientA_URI}
        userAuthorizationUri: ${clientA_AUTHURI}
        redirectUri: "${BASE}/oauth/client_a"
        scope: /authenticate

OAuthConfig.clientA()

@Bean
@ConfigurationProperties("oauth2.clientA")
public AuthorizationCodeResourceDetails clientA() {
    AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails();
    return details;
}

OAuthConfig.clientAFilter()

@Bean("clientAFilter")
public OAuth2ClientAuthenticationProcessingFilter clientAFilter() {
    OAuth2ClientAuthenticationProcessingFilter filter = new OAuth2ClientAuthenticationProcessingFilter("/clientA");
    OAuth2RestTemplate template = new OAuth2RestTemplate(clientA(), oauth2ClientContext);
    filter.setRestTemplate(template);
... 중략 ...
    return filter;
}

application.yaml 에서 redirectUri 설정을 해 두었기 때문에 당연히 {BASE} 에 환경 변수로 걸어둔 주소로 시작하는 uri가 전달될 것이고, 코드를 봐서는 문제를 찾기 힘들었습니다.

해결 과정

RedirectUri 변경

일단 제일 먼저 redirectUri 변경을 통해 해결을 시도해 보았습니다. 환경 변수로 받은 ${BASE}에 혹시나 문제가 있을까 싶어서였는데 해결에 실패했습니다.

다만 여기서 redirectUri 를 이것 저것으로 다 변경 해 보아도 실제 OAuth를 담당하는 사이트에서 받은 RedirectUri가 변경하지 않은 것이 확인 되었습니다.

redirect-uri로 변경

image-20220620144126379

https://docs.spring.io/spring-security/site/docs/5.2.12.RELEASE/reference/html/oauth2.html#oauth2Client-auth-code-redirect-uri

스프링 문서를 찾아 보던 중, redirect-uri 로 적혀 있는 것을 확인 하였고, 그래서 거기에 따라서 redirectUri로 작성되어 있던 속성명을 변경 해 보았습니다.

oauth2:
    clientA:
        clientId: ${clientA_CLIENTID}
        clientSecret: ${clientA_SECRET}
        accessTokenUri: ${clientA_URI}
        userAuthorizationUri: ${clientA_AUTHURI}
        redirect-uri: "${BASE}/oauth/client_a"
        scope: /authenticate

하지만 여전히 redirectUri는 변경이 되지 않았습니다.

redirectUri, redirect-uri, redirect_uri 등 이것저것 다 넣어보았지만 전혀 읽히지 않았습니다.

그래서, redirectUri가 어디서 어떻게 생성이 되는지를 확인해보기 위해 필터 등록시 입력하는 defaultFilterProcessesURl 을 변경 해 보았습니다.

image-20220620144320842

org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter.java

그랬더니, 변경한 필터 주소대로 OAuth 서버에서 리다이렉트 해주는 주소도 따라 변경되었습니다.

요청시의 URI 를 토대로 자동으로 생성 하는 것 같습니다.

해결

AuthorizationCodeResourceDetails 에서 사용 가능한 메서드들을 체크 해 보기로 했습니다.

사실 스프링부트 2.x로 넘어 오며 생긴 에러로 추정되기 때문에 설정값이 가장 유력한 용의자라고 봤었고, 또한 AuthorizationCodeResourceDetails 를 확인 해 보니 spring-security-oauth2-2.2.1.RELEASE 에 포함된 코드인데

image-20220620145552914

https://mvnrepository.com/artifact/org.springframework.security.oauth.boot/spring-security-oauth2-autoconfigure/2.0.0.RELEASE

버전이 변경되지 않은 spring-security-oauth2-autoconfigure 가 여전히 같은 버전을 의존하고 있기에 문제가 없을 거라 생각했는데 사실 여기 문제가 있었습니다.

image-20220620145805100

clientA()

AuthorizationCodeResourceDetails 의 메서드 목록을 확인해보니 setUseCurrentUri 가 눈에 띄었고, 바로 false로 설정한 후 애플리케이션을 재 실행 해 보니, OAuth 사이트에서는 드디어 redirect uri가 넘어오지 않았다며 오류를 발생했습니다.

image-20220620145958985

setPreEstablishedRedirectUri()

이번에는 uri를 설정할 수 있는 메서드를 찾다 보니 setPreEstablishedRedirectUri가 눈에 띕니다.

아! redirect-uri 라고 쓸 게 아니고, preEstablishedRedirectUri 라고 쓰면 될 것 같습니다.

변경

OAuthConfig.clientA()

@Bean
@ConfigurationProperties("oauth2.clientA")
public AuthorizationCodeResourceDetails clientA() {
    AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails();
    details.setUseCurrentUri(false);
    return details;
}

일단 위에서 확인 한 것처럼 setUseCurrentUri를 false로 지정 해 주고

application.yaml

oauth2:
    clientA:
        clientId: ${clientA_CLIENTID}
        clientSecret: ${clientA_SECRET}
        accessTokenUri: ${clientA_URI}
        userAuthorizationUri: ${clientA_AUTHURI}
        preEstablishedRedirectUri: "${BASE}/oauth/client_a"
        scope: /authenticate

redirectUrl 대신 preEstablishedRedirectUri 를 입력 해 줍니다.

그러고 나서는 정상적으로 rediret Uri 가 원하는 대로 전달 되는 것이 확인 되었습니다.
image-20220620150547462

위에 보이는 것 처럼 redirectUri 가 null 일 때만 useCurrentUri 나 getPreEstablishedRedirectUri를 활용 하게 끔 되어 있는데 AccessTokenRequest가 전달 받는 파라미터를 확인 해 보면 전혀 넘어 오는 게 없더라고요.

일단 preEstablishedRedirectUri 설정을 통해 해결하는 것이 가장 좋아 보입니다.

이상입니다.

반응형