[Spring Boot Tutorial] 7. JavaConfig 설정으로 Spring Security 커스터마이징

2019. 11. 29. 14:36Spring/Spring Boot Tutorial

반응형
  1. url 접근 권한 설정
  2. 로그인 페이지 설정
  3. 정적파일 인증/인가 처리 무시

1. url 접근 권한 설정

Spring security 맛보기 과정에서 Spring Security에서 기본으로 제공해주는 로그인 폼을 이용했었습니다.(아래의 그림 참고)

32

기본 로그인 form을 사용하지 않고 다른 디자인을 사용하고 싶다면, 구성설정의 일부를 수정해야 합니다.

로그인 form을 직접 구성하는 것 뿐만 아니라, 로그인 한 user의 보유권한에 따라 접근할 수 있는 url을 별도로 설정할 것입니다.(지난 시간에서 오류로 설명했던 부분 중 하나)

  1. 로그인 form 페이지 설정
    • 로그인 성공시 이동할 페이지
    • form에서 이용할 로그인 관련 파라미터 명 설정
  2. url별 접근권한 설정
  3. csrf 방지 설정

spring security의 세세한 설정을 위해서는 JavaConfig 또는 xml파일에 설정관련 코드를 작성해야 합니다. 이 중, 이 포스팅에서는 JavaConfig를 이용한 설정방법을 이용합니다.


먼저, WebSecurityConfigurerAdapter를 상속받는 JavaConfig 파일을 생성합니다.

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig  extends WebSecurityConfigurerAdapter {

}

WebSecurityConfigurerAdapter에서 spring security 상세 기능을 설정하는 메서드는 총 3가지입니다.

  • configure(AuthenticationManagerBuilder auth)
    • 이전 시간에 프로퍼티에 설정했던 보안 관련 설정을 인메모리에 설정할 수 있도록 함
  • configure(HttpSecurity http)
    • Spring Security Filter chain에 접근하여 url 인증 및 인가 처리 시행
  • confiugre(WebSecurity web)
    • 인증 및 인가절차 무시
    • 주로 정적파일(js, css, image) 경로 설정에 이용됩니다.

@Override
protected void configure(HttpSecurity http) throws Exception {
  http.authorizeRequests()    
    .antMatchers("/", "/users", "/users/**").permitAll()
    .antMatchers("/v", "/v/**").access("hasRole('ROLE_VIEW')")
    .anyRequest().authenticated()
  .and()
    .formLogin().loginPage("/login").defaultSuccessUrl("/v").permitAll()
    .usernameParameter("username").passwordParameter("password")
  .and()
    .logout().permitAll()		
  .and()
    .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}

void configure(HttpSecurity http) 메서드를 override하여 security 기능을 커스터마이징 합니다.

ln 4: /, 와 users api 관련 url은 모든 사용자가 사용할 수 있습니다.
ln 5: /v, /v/** url은 ROLE_VIEW 권한을 가진 사용자만 접근할 수 있습니다.
ln 6: 설정되지 않은 모든 url request는 인가된 사용자만 이용할 수 있도록 합니다.
ln 8: loginPage("/login") 으로 로그인폼페이지 url을 작성합니다. 로그인이 성공했을 시엔 "/v" 로 이동됩니다.
ln 9: 로그인폼에서 사용자 검증을 할 username, password input name을 설정하는 것입니다. (만일 사용자이름의 파라미터값이 email이라면 email을 설정해주면 됩니다.)
ln 13: csrf 공격 방지를 위해 설정해줍니다. (이 속성을 설정했을 시엔, post 요청시 반드시 _csrf token값을 넣어줘야 합니다.)


csrf 공격 방지 설정으로 인해 기존에 작동되던 users api 중 POST, PUT, PATCH, DELETE method request가 작동되지 않게 됩니다.

csrf 쿠키를 활성화 했을 경우, request 전송시 X-XSRF-TOKEN 헤더를 필수적으로 설정해야 합니다.
postman에서 X-XSRF-TOKEN 헤더를 설정하여 request를 보내는 방법은 postman에서 csrf token 이용하기를 참고해주세요.


2. 로그인 페이지 설정

<div class="login_wrapper">
  <section>
    <h1>
      <img th:src="@{/static/img/like.png}" width="50" height="auto" alt="demo" id="btn_loginHome">
    </h1>
    <form method="post" th:action="@{/login}">
      <div>
        <input type="text" name="username" class="form-control" placeholder="username" autocomplete="off" required/>
      </div>
      <div style="margin-bottom: 50px;">
        <input type="password" name="password" class="form-control" placeholder="Password" autocomplete="off" required/>
      </div>
      <div>
        <button type="button" class="btn btn-info btn-large form-control" id="btn_login">로그인</button>
      </div>
    </form>
    <hr class="separator"/>
    <div>
      <h1>DEMO</h1>
      <p>©2019 All Rights Reserved.</p>
    </div>
  </section>
</div>

ln 8, 11: JavaConfig에서 설정했던 usernameParameter, passwordParameter 이름과 동일하게 input name을 설정합니다.


3. 정적파일 인증/인가 처리 무시

JavaConfig 설정을 모두 마치고, Spring Boot 앱을 가동시켜봅시다.

47

로그인 페이지에 접속했더니. 이런! 이미지 파일이 깨집니다
favicon과 title 이미지가 열리지 않았는데, 원인이 뭘까요?

바로, JavaConfig 파일에 설정했었던 http.authorizeRequests() .anyRequest().authenticated() 명령에 의해 모든 url 인가는 로그인한 유저를 대상으로 설정되었기 때문입니다.

따라서 정적파일 역시 열리지 않게 된것입니다.
여기에 쓰인 정적파일의 url은 http://localhost:8989/static/img/gift.png 와 같이 /static/ 으로 시작되는 url로, 우리가 Config 파일에 설정해 주지 않았습니다.


물론, 위의 HttpSecurity의 permitAll에 설정을 해도 동작은 원활히 되지만,
특정 url로 접속할 때 인증/인가 처리를 무시하고 싶은 경우에는 WebSecurity에 설정을 추가하는 것이 기능적으로도 더 효율적입니다.

@Override
public void configure(WebSecurity web) throws Exception {
  web.ignoring().antMatchers("/static/**");
}

정적 파일의 경우, 인증/인가 절차를 무시하도록 설정합니다.

그리고 서버를 재시작한 후, 로그인 페이지에 접속하면 이미지 파일이 정상적으로 출력됩니다.

48


++ tip

루트 접속시, 로그인한 유저일 경우에는 /v 페이지로 이동되고 로그인하지 않은 경우에는 /login 페이지로 이동하도록 설정합니다.

@Controller
public class LoginController {

  ...

  @GetMapping(value = "/login")
  public String login(@AuthenticationPrincipal User user){
    if(user != null) {
      if(user.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_VIEW"))) {
        return "redirect:/v";
      }
    }
    return "login/login";
  }
}

이번 포스팅에서는 WebSecurityConfigurerAdapter를 상속받은 JavaConfig 파일의 configure 메서드 override를 이용하여 Spring security url별 인증/인가 처리와 직접 만든 로그인 페이지를 설정하는 방법을 배웠습니다.

다음에 다룰 spring security 관련 내용은 접근 권한 없는 페이지 접속에 관한 처리 (exceptionHandling)DB를 이용한 security 로그인이 있습니다.


GitHub에서 demo 프로젝트를 다운받아 볼 수 있습니다.

728x90
반응형