이 글은 스프링 공식 문서를 번역한 글입니다.
번역에 오류가 많을 수 있으니 주의 바랍니다.
출처 : https://docs.spring.io/spring-security/site/docs/4.2.20.RELEASE/guides/html5/form-javaconfig.html
이 가이드는 Hello Spring MVC Security Java Config 의 추가적인 가이드다.
우리가 Hello Spring MVC Security Java Config에서 본 것처럼,
스프링 시큐리티의 WebSecurityConfigurerAdapter 클래스는 우리의
애플리케이션을 빠르게 설정하고 구동시킬 수 있도록 해주는 편리한 기본 메서드들을 제공한다. 하지만 우리의 로그인 폼은 애플리케이션의 다른 것들이랑은
달라보인다. 이제 우리만의 커스텀 form을 만들기 위해 configuration을
어떻게 바꿀지 보자.
configure(HttpSecurity)의 기본 설정은 아래와 같다.
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated() //1
.and()
.formLogin() //2
.and()
.httpBasic(); //3
}
SecurityConfig.java 에 아래와 같이 configure 메서드를 넣는다.
// ...
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login");
}
// ...
}
formLogin().permitAll() 메서드는 스프링 시큐리티에게
formLogin()과 관련된 특정 URL(여기서는
/login 과 /login?error)에 모든 사용자의 접근을 허용하도록 지시한다.
formLogin() URL들의 접근 권한 부여는 기본적으로 구현되지 않는다.
왜냐하면 스프링 시큐리티는 어떤게 허용됐고 어떤게 허용되지 않았는지에 대한
가정(assumption)을 만들어야 하기 때문이다.
안전을 위해서라면 자원들의 접근 권한을 확실히 하는게 가장 좋다.
우리의 configuration의 변경을 확인하기 위해 서버를 시작해서 http://localhost:8080/sample/ 에 접근해보자.
이제는 Error resolving template "login" 이라는 500 에러를 받을 것이다.
스프링 MVC 로 우리의 로그인 페이지를 만드는 과정은 두개로 나눌 수 있다.
1.컨트롤러 만들기
2.뷰 만들기
첫번째 단계는 우리의 view 를 가리키는 컨트롤러를 만드는 것이다.
우리의 프로젝트는 javaconfig/messages 프로젝트 의존성을 추가했었다.
이것은 /login 을 위한 뷰 컨트롤러를 이미 포함하고 있기 때문에
따로 컨트롤러를 만들 필요가 없다.
참고를 위해 아래 configuration 이 있다.
// ...
@EnableWebMvc
@ComponentScan("org.springframework.security.samples.mvc")
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
// ...
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
}
우리가 만든 설정에 따르면 우리는 login.html만 만들면 된다.
아래는 그 코드다.
<html xmlns:th="https://www.thymeleaf.org">
<head th:include="layout :: head(title=~{::title},links=~{})">
<title>Please Login</title>
</head>
<body th:include="layout :: body" th:with="content=~{::content}">
<div th:fragment="content">
<form name="f" th:action="@{/login}" method="post"> //1
<fieldset>
<legend>Please Login</legend>
<div th:if="${param.error}" class="alert alert-error"> //2
Invalid username and password.
</div>
<div th:if="${param.logout}" class="alert alert-success"> //3
You have been logged out.
</div>
<label for="username">Username</label>
<input type="text" id="username" name="username"/> //4
<label for="password">Password</label>
<input type="password" id="password" name="password"/> //5
<div class="form-actions">
<button type="submit" class="btn">Log in</button>
</div>
</fieldset>
</form>
</div>
</body>
</html>
인증이 실패한 자세한 이유는 화면에 보여주지 말자. 예를 들어, 우리는
유저가 존재하지 않는다는 것을 화면에 보여주면 안된다. 공격자에게
다른 usename 을 시도해 볼 수 있다는 것을 알려주는 것이다.
우리는 CSRF 토큰을 자동으로 form에 추가하기 위해 Thymeleaf를 사용했다.
만약 Thymeleaf나 Spring MVC의 taglib을 사용하지 않는다면
CSRF 토큰을 직접 추가할 수 있다.
서버를 기작하고 http://localhost:8080/sample/ 에 접속해보자.
로그인 페이지가 보이지만 별로 예쁘진 않을 것이다. 문제는
우리가 css 파일들에 접근 권한 설정을 하지 않았기 때문이다.
우리는 우리의 자원들과 로그아웃 페이지에 대해 모든 사람들의 접근을 허용하도록
configuration을 수정해야 한다.
아래처럼 수정해라.
// ...
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**").permitAll() //1
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout() //2
.permitAll();
}
// ...
}
서버를 재시작 해서 http://localhost:8080/sample/ 에 접속해보자.
우리는 이제 애플리케이션의 다른 페이지들과 같이 꾸며진
우리의 커스텀 로그인 페이지를 볼 수 있다.
당신은 이제 스프링 시큐리티의 자바 설정을 통해 커스텀 로그인 폼을
추가 할 수 있을 것이다. 더 많은 것을 배우고 싶다면 아래 링크로 가보자.
Spring Security Guides index page.