개발/Spring

🌱Spring:: Spring Security로 Spring Rest Docs에 로그인 붙이기

hyuunii 2023. 6. 14. 19:53

현재 근무중인 회사는 API 명세서로 Spring Rest Docs를 이용하고 있습니다.

배포할 때 아예 Public ip로 배포되어 누구든지 언제 어디서든 볼 수 있었죠.

 

 

Spring Rest Docs

'너무 공개된건 아닌가?'

하는 생각을 하던 와중,

 

해당 페이지에 OAuth2.0으로 Naver 로그인을 붙이라는 업무가 주어집니다.

 

그래서 처음에 OAuth를 붙이려 여러 방법을 시도해봤어요.

근데 안 되더란겁니다....

 

애당초 OAuth를 붙일 로직이 없는데 어디에다가 어떻게 붙인단 말임...

Spring Rest Docs는 API의 테스트 코드를 작성하면 그걸 기반으로 snippets을 만들고,

결국엔 만들어진 snippets을 갖고 API Docs를 자동으로 만들어주는 라이브러리입니다.

OAuth는 애초에 붙일 수 없던거였슴.

 

 

 

그래서 아니 도대체 어떻게 해야할지... 고민을 많이 했는데요,

로컬 환경에서 해당 문서에 접근하는 페이지의 url은 localhost:8080/docs/*.html이고,

배포 환경은 (public ip)/docs/*.html인 것에서 힌트를 얻었습니다.

 

 

 

결론적으로 Spring Security를 이용해서 오어쓰는 아니지만 로그인 페이지를 붙일 수 있었습니다.

아래 이미지는 /docs/* 페이지에 접근하려 할 시 이동되는 로그인 페이지입니다.

(templates에 만듦)

 

스프링 시큐리티의 이용을 개략적으로 설명하자면, 

 

.antMatchers("/docs/**").hasRole("ADMIN")

위의 코드로 /docs/*인 페이지는 전부 ADMIN 권한의 유저만 접근이 가능하게 하고

 

.loginPage("/user/login")
.defaultSuccessUrl("/docs/main.html");

위 코드 첫번째줄에서 기본적으로 로그인 페이지(/user/login)를 따로 만들어 주고(비즈니스 로직과는 상관 없는, 오로지 Spring Security로 API 명세서에 접근할 용도의 로그인 페이지입니다), 

두번째줄에서 ADMIN 권한의 유저가 로그인에 성공하면 /docs/main.html로 API 명세서의 메인 페이지로 이동하게 했습니다.

 

 

 

 

 

* 스프링 시큐리티 의존성 추가(Maven, pom.xml)

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

 

 

* src/java/com.~/congit/SecurityConfig

 @Bean  //스프링 시큐리티의 세부 설정은 SecurityFilterChain 빈을 생성을 통해 설정할 수 있다.
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.cors()  //CORS는 HttpSecurity의 cors() 메소드로 설정할 수 있다. 그리고 아래의 CorsConfigurationSource를 통해 CORS의 속성을 정의해 줄 수 있다.
                .and()
                .csrf().disable()  //@EnableWebSecurity 어노테이션을 지정할 경우 자동으로 CSRF 보호 기능이 활성화가 됩니다. 따라서 CSRF 비활성화가 필요할 경우 아래와 같이 csrf().disable() 설정을 추가합니다.
                .authorizeRequests()
                .antMatchers("/docs/**").hasRole("ADMIN")//ADMIN 권한 확인되어야 docs 페이지 접근 가능
                .antMatchers("/**").permitAll()  //모든 인증되지 않은 요청을 허락한다는 의미이다. 따라서 로그인을 하지 않더라도 모든 페이지에 접근할 수 있다.
                .and()
                .formLogin()
                .loginPage("/user/login")
                .defaultSuccessUrl("/docs/main.html");
        return http.build();
    }

 

 

* 회원가입, 로그인 로직은 아래 출처의 점프 투 스프링 부트에서 거의 대부분 그대로 가져왔습니다.

 

단, 회원가입은 따로 페이지를 만들어두지 않았습니다.

ADMIN 권한의 계정 하나만 생성해서 회사 내부 사람들만 이용하고자 만든 로그인 기능이니까요.

그래서 그냥 postman 이용해서 계정 생성해주고, 디비에서 바로 객체 수정해서 ADMIN 권한 줬습니다.

 

 

 

 

 

 

참고::
1. https://wikidocs.net/162150, 점프 투 스프링부트 3-05 스프링 시큐리티
2. https://wikidocs.net/162141#siteuser, 점프 투 스프링부트 3-06 회원가입
3. https://wikidocs.net/162255#userrepository, 점프 투 스프링부트 3-07 로그인과 로그아웃
4. https://catsbi.oopy.io/c0a4f395-24b2-44e5-8eeb-275d19e2a536, 스프링 시큐리티 기본 API및 Filter 이해
5. https://mangkyu.tistory.com/77, [SpringBoot] Spring Security 처리 과정 및 구현 예제