Springfox Swagger 3.x에서 Spring Security로 JWT 인증하기

CHEESE·2022년 7월 19일
0

삽질하다가 얼떨결에 성공했는데 왜 되는지 모르겠어서 정리해본다. 그러므로 이 글은 나의 삽질과 해결한 과정을 정리한 글이다. 의존성 추가부터 ~ 설정 클래스를 만드는 등의 전체 과정은 이미 잘 정리된 포스트들이 많기 때문에... 이 글에서는 생략한다.
버전별로, 특히 최신 버전의 경우 deprecated된 메소드들이 많아서 꽤 헤맸다. 나처럼 헤매는 사람들이 없기를 바라며 내가 사용한 버전을 먼저 기록해본다.

  • Spring boot 2.6.4
  • jjwt 0.11.5
  • Swagger 3.0.0

Swagger에서 request header에 인증 토큰을 넣고 싶어!

Swagger에서는 기본적으로 request header값을 설정하는 부분이 없다. @configuration이 달린 Swagger 설정 클래스에서 이를 설정해주어야 한다.
중심이 되는 설정 부분은 다음과 같다.

@Configuration
public class SwaggerConfig {

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.OAS_30)
                .securityContexts(Arrays.asList(securityContext()))
                .securitySchemes(Arrays.asList(apiKey()))
               ...(생략);
    }

    // 인증 방식 설정
    private SecurityContext securityContext(){
        return SecurityContext.builder()
                .securityReferences(defaultAuth())
                .build();
    }

    private List<SecurityReference> defaultAuth(){
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        return Arrays.asList(new SecurityReference("Authorization", authorizationScopes));
    }

    // 버튼 클릭 시 입력 값 설정
    private ApiKey apiKey(){
        return new ApiKey("Authorization", "Bearer", "header");
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                ...(생략)
                .build();
    }
}

위처럼 설정 파일을 예쁘게 셋팅하고 나면 Swagger API 전역에 request header에 값을 넣을 수 있게 Authorize 버튼이 활성화되고, 이를 클릭하면 아래와 같은 팝업이 표시된다.

문제

인증 값은 잘 들어가는 것 같은데 api를 execute했을 때 curl이 날아가는 걸 보면? 다른 사람들과 다르게 header 부분이 포함되어있지 않았다. 왜 이러지?
postman이나 테스트 코드를 돌려보면 내 코드에 이상이 있는 건 아니었다. Swagger에 문제가 있을 것이라고 확신하고 찾아본 결과 내 Swagger가 다른 사람들과 다른 부분을 찾아냈다.

다른 사람들과 다르게 내 api 각각의 자물쇠들이 활짝 열려있었다 ... 자물쇠들을 클릭해봐도 Available authorizations이라는 타이틀을 가진 빈 팝업만 표시될 뿐이었다.

해결

위에 작성한 내 코드를 그대로 복사했다면 문제가 없었을 것이다.

나는 위에 표시한 두 파라미터의 값을 동일하게 맞추고 나서 이를 해결했다.
메소드 하나하나가 무슨 행위를 하는지도 모르고 여기저기서 코드를 짜깁기해 온 내 탓이다...

아! 또 나한테는 문제되는 내용은 아니었지만 저 값은 Spring Security에서 사용하는 JWT 인증 필터에서도 동일한 문제를 일으킬 수 있다.
어찌보면 당연하지만 request.getHeader(파라미터)에서 사용하는 header의 이름과도 동일해야한다.

Swagger 전역에서 jwt 토큰 값을 설정할 때 Bearer jwt토큰값과 같이 토큰 값 앞에 Bearer를 붙여줘야 하는 점도 주의하자.

1개의 댓글

comment-user-thumbnail
2022년 8월 27일

진짜 너무 감사합니다 ㅠㅠ
keyname과 reference 가 일치해야하는줄알고 2시간넘게 핸들링하고있었네요...
덕분에 바로 해결하였습니다! 너무감사해요!

답글 달기