2019/03/28 - [SW개발] - Kotlin + Spring boot security + thymeleaf 로그인 구현(1)
2019/04/01 - [SW개발] - Kotlin + Spring boot security + thymeleaf 로그인 구현(2)
이전 글까지, 따라왔다면 여기까지 만들어졌을겁니다.
이번 글에서는 Spring Security를 통해, 이전 글에서 만든 Provider를 빈으로 등록하고, 이를 통해 인증을 처리하는 config를 구현하겠습니다
1. WebSeurityConfigurerAdpater 구현
이 인터페이스는, 스프링 시큐리티에서 가장 핵심 적인 역할을 합니다.
- AuthenticationManagerBuilder : AuthenticationProvider 설정
- WebSecurity : 전역 보안에 영향을 주는 구성 설정
- HttpSecurity : 어떠한 URL 경로를 보호해야하는지에 대한 정의, 자신만의 인증 매커니즘 정의
위의 세가지를, configure에 저장함으로서, 보안을 설정할 수 있습니다.
@Configuration
@EnableWebSecurity
class SecurityConfig : WebSecurityConfigurerAdapter() {
@Autowired
fun provider() = MyAuthenticationProvider()
override fun configure(auth: AuthenticationManagerBuilder) {
auth.authenticationProvider(provider())
}
override fun configure(web: WebSecurity) {
web.ignoring().antMatchers("/resource/**", "/static/**", "/favicon.ico")
}
override fun configure(http: HttpSecurity) {
http.csrf().disable().httpBasic()
http.headers().frameOptions().disable()
http.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login").loginProcessingUrl("/auth")
.defaultSuccessUrl("/index", true)
.failureUrl("/login?error")
.and()
.logout()
.logoutSuccessUrl("/login?logout")
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
http.sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(true)
}
}
- 1행 : @Cofiguration 어노테이션을 통해, configuration으로 등록합니다
- 2행 : WebSecurityConfigurerAdapter와 함께 사용되며, 스프링 시큐리티를 사용할 때 사용합니다
- 6행 : 이전에 만든 AuthenticationProvider를 빈으로 등록해줍니다
- 10행 : AuthenticationManageBuilder를 provider를 통해, 실질적 인증절차를 진행하게 해줍니다
- 14행 : 해당 접근에 대해, 무시를 해주는 코드를 넣습니다(전역)
- 18행 : csrf를 꺼줍니다 (Csrf를 사용할 때에는 필요 없는 코드입니다)
- 21행 : authorize에 관한 동작입니다
- 22행, 23행 : "/login"은 전체에게 공개, 이외에는 authentication을 통해 권한을 얻은 사람만 접근하게 합니다
- 25행 - 28행 : login에 관한 내용입니다
- 30행 - 33행 : logout에 관한 내용입니다
- 35행 : 세션 관리입니다. 현재 맥시멈을 1개로 두어, 동시로그인이 불가능하게 했습니다
2. login page, index page 구현
Spring security는 기본 로그인 페이지를 지원하지만, 보통은 커스텀 로그인 페이지를 만들고자 할 것입니다. 저는 타임리프 템플릿 엔진을 통해 로그인페이지를 간단히 구현하겠습니다.
- 타임리프는 기본적으로 resource 밑에, templates에 html파일을 통해 구현할 수 있습니다
- 로그인 페이지인 login.html과 , 로그인에 성공했을 때 들어가는 index.html을 만들었습니다
login.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<title>Login page</title>
</head>
<body>
<script type="text/javascript" sec:authorize="isAuthenticated()">
location.href = "/index"
</script>
<h1>Login page</h1>
<div th:if="${param.error}">
계정과 비밀번호 확인
</div>
<div th:if="${param.logout}">
로그아웃
</div>
<form th:action="@{/auth}" method="post">
<input type="text" id="username" name="username" autofocus="autofocus" placeholder="id"/> <br />
<input type="password" id="password" name="password" placeholder="pw"/> <br />
<input type="submit" value="Log in" />
</form>
<h3>Admin : admin/123 </h3>
<h3>User : user/456 </h3>
<script src="//code.jquery.com/jquery-2.2.4.min.js"></script>
</body>
</html>
- 2행 : 타임리프 엔진을 사용한다는 것을 명시합니다 - sec의 경우 1번글에서 보이는 spring security5용을 따로 의존성 추가를 해줘야합니다 (스프링 부트 기본 설정에서 빠짐)
- 7행 - 9행 : isAutenticated() - 현재 인증이 완료된 상태이면 login페이지가 아닌 index페이지로 연결
- 12행, 15행 : 각각 get으로 파라미터가 error, logout이 들어오면 아래의 내용을 출력해줍니다
- 19행 : authentication을 진행할 url ( 위에 configure(httpsecurity)에 지정해준 loginProcessingUrl과 동일해야 합니다)
Index.html
<!DOCTYPE html>
<html xmlns:sec="http://www.thymeleaf.org/extras/spring-security" >
<head>
<meta charset="UTF-8">
<title>Example</title>
</head>
<body>
<span sec:authorize="hasRole('ROLE_ADMIN')">
<button>
<a href="/logout"><h2>ADMIN Logout</h2></a>
</button>
</span>
<span sec:authorize="hasRole('ROLE_USER')">
<button>
<a href="/logout"><h2>USER Logout</h2></a>
</button>
</span>
</body>
</html>
- 8행, 13행 : sec:auhtorize="hasRole('~~')" : ~~라는 권한을 가질 경우, 동작하게 하는 함수입니다
- 10행, 14행 : "/logout" - httpsecurity에 정해놓은, logout url로 가게 해줍니다
3. WebMvcConfigurer 구현
index페이지와, login페이지를 연결해줄 Configuerer를 구현합니다
@Configuration
class MvcConfig : WebMvcConfigurer{
override fun addViewControllers(registry: ViewControllerRegistry) {
registry.addViewController("/login").setViewName("/login")
registry.addViewController("/index").setViewName("/index")
}
}
- 기본적으로 resource/templates 가 기본으로 설정돼 있습니다
- 3행 : ViewControllerRegistry에 /login url(controller)에, login.html(view)를 등록해줍니다
- 4행 : 3행과 마찬가지로 index를 등록합니다
- 여기까지 따라오셨다면 기본적인 로그인 구현은 끝이났습니다.
4. 실행 결과
- 스프링 부트를 실행 시켜준 뒤, localhost:8080(기본호스트)로 연결해준 화면입니다
- admin, 123으로 Login했을 때의 화면입니다. role이 ROLE_ADMIN이기 때문에, ADMIN_Logout버튼이 나옵니다.
- Logout을 누르면 다시 loginpage로 돌아갑니다
- 로그아웃을 했기 때문에, logout파라미터가 붙었기 때문에, 로그아웃을 출력해줬습니다
- user로 로그인을 했을 때의 페이지입니다.
지금까지 Spring Security를 이용하여, 간단한 로그인 페이지를 구현해보았습니다.
궁금한 점이 있다면 댓글 달아주세요
https://github.com/bobfull/spring-kotlin-security-study
- 예제 코드가 있는 github 주소입니다.
'SW개발' 카테고리의 다른 글
젠킨스 파이프라인(Jenkins pipeline) - 빌드 파라미터 넣기 (0) | 2019.05.17 |
---|---|
젠킨스 파이프라인 ( Jenkins pipeline ) - 병렬로 Job 실행하기 (1) | 2019.05.08 |
Kotlin + Spring boot security + thymeleaf 로그인 구현(2) (0) | 2019.04.01 |
Kotlin + Spring boot security + thymeleaf 로그인 구현(1) (0) | 2019.03.28 |
Spring Boot Security (2) | 2019.03.28 |