[Spring Security] Form Authentication - Spring Boot (7)

반응형

이번 글에서는 Spring Boot App에 Form Authentication을 적용하는 방법에 대해 알아보도록 하겠습니다.

1. Form Authentication

이번에는 이전글에서 생성한 spring boot app에 Form Authentication을 적용해보겠습니다.

이전까지는 사용자가 로그인할때 위와 같이 브라우저에서 직접 로그인창을 띄워 아이디와 비밀번호를 입력했습니다.

이러한 인증 방법을 Http Basic Authentication이라고하며, 이를 사용하기위해 위와 같이 SecurityConfiguration에 httpBasic( )을 정의했습니다.

이번에는 이를 개선해 Thymeleaf로 Login Page를 직접 만들어서 인증을 구현해보겠습니다.

2. Form Login Page

먼저 아래와 같이 로그인 페이지를 생성합니다.

2-1) html

login.html

<html xmlns:th="http://www.thymeleaf.org">
<head th:insert="fragments.html :: headerfiles">
    <title>Log in</title>
</head>
<body>
<div class="container">
    <div style="width:600px;margin-left: auto;margin-right: auto;margin-top:24px;padding: 24px;">
        <div class="card">
            <div class="card-header">
                <i class="fa fa-user"></i> Please Login
            </div>
            <div class="card-block" style="padding: 24px;">
                <form name="f" th:action="@{/login}" method="post">
                    <fieldset>
                        <!-- Thymeleaf + Spring Security error display -->
                        <div th:if="${param.error}" class="alert alert-danger">
                            Invalid username and password.
                        </div>

                        <div th:if="${param.logout}" class="alert alert-success">
                            You have been logged out.
                        </div>

                        <!-- Login Controls -->
                        <div class="form-group">
                            <label for="username">Username</label>
                            <input type="text" class="form-control" id="username" name="username"
                                   placeholder="Username">
                        </div>

                        <div class="form-group">
                            <label for="password">Password</label>
                            <input type="password" class="form-control" id="password" name="password"
                                   placeholder="Password">
                        </div>
                        <!-- Login Button -->
                        <div class="form-actions" style="margin-top: 12px;">
                            <button type="submit" class="btn btn-success">Log in</button>
                        </div>
                    </fieldset>
                </form>
            </div>
        </div>
    </div>
</div>
</body>
</html>

• username과 password를 POST하는 Form을 생성합니다.

• POST를 보내는 url은 /login이며 이는 Spring Security의 기본 로그인 url 입니다.

• /login POST method를 수행하는 Controller는 사용자가 직접 구현할 필요가없습니다. 이는 Spring Security 내부에 이미 구현되어 있으며 사용자는 해당 url로 login User 정보만 전달하면됩니다.

• username과 password는 Spring Security에서 기본으로 요구하는 로그인 파라미터입니다.

• submit 버튼으로 Form data가 POST method를 통해 전달되도록 합니다.

2-2) controller

다음으로 login 페이지를 return하는 @GeMapping(/login)을 생성합니다.

HomeController

@Controller
@RequestMapping("/")
public class HomeController {
    @GetMapping("index")
    public String index(){
        return "index";
    }

    @GetMapping("login")
    public String login(){
        return "login";
    }
}

3. Integrate Spring Security

이제 위에서 생성한 Login Form을 Spring Security에 연결하도록 하겠습니다.

아래와 같이 SecurityConfiguration을 변경합니다.

• formLogin( )을 선언해 Form Authentication을 사용합니다.

• loginPage는 앞서 생성한 login.html을 return하는 @GetMapping url을 입력합니다.

• /login url은 permitAll( )을 선언해 모든 사용자가 접근할 수 있도록 합니다.

4. Test

테스트 해보겠습니다. 😎

/login으로 접근하면 위와 같이 정상적으로 로그인 페이지가 나옵니다.

username과 password를 정상적으로 입력하면 로그인이 성공하고 /index 페이지로 redirect 됩니다.

만약 로그인이 제대로 되지 않을 경우 사이트에서 Cookie를 허용하고 있는지 확인합니다. Form Authentication의 경우 Login Session 값이 Cookie 형태로 Client에 전달되기 때문에, Cookie를 허용하지 않으면 로그인 할 수 없습니다.

5. Logout

이번에는 logout 기능을 구현해보겠습니다.

5-1) logout button

먼저 아래와 같이 Header에 Logout 버튼을 추가합니다.

fragments.html


<form class="form-inline my-2 my-lg-0" form-method="post" th:action="@{/logout}">
    <button  class="btn btn-outline-danger my-2 my-sm-0 btn-sm" type="submit">Logout</button>
</form>

• login과 동일하게 logout도 form으로 생성합니다.

• Spirng Security의 default logout url인 /logout으로 submit을 날리면 됩니다.

5-2) add logout configure

다음으로 SecurityConfiguration에 logout 설정을 추가합니다.

• logout Request Url을 /logout으로 설정합니다.

• logout 성공시 /login으로 redirect합니다.

6. Remember Me

이번에는 Remember Me를 적용해보도록 하겠습니다.

6-1) remember me checkbox

아래의 내용을 login.html에 추가합니다.

login.html

<div class="form-check">
    <input type="checkbox" class="form-check-input" id="remember-me" name="remember-me">
    <label class="form-check-label" for="remember-me">Remember me?</label>
</div>

• remember-me 변수는 Spring Security의 default 변수입니다.

• remember me를 check하고 login을 진행하면 매번 login을 수행하지 않아도 됩니다.

6-2) add remember me configure

다음으로 SecurityConfiguration에 remember me 설정을 추가합니다.

• rememberMe( )를 선언합니다.

• rememberMe token의 validation 기간을 정의합니다.

• rememberMe token 생성시 사용할 secret key를 정의합니다.

6-3) test

remember me 설정후 login 해보겠습니다.

로그인 성공시 Client를 확인해보면 아래와 같이 Cookie가 2개가 생성되어 있는것을 확인할 수 있습니다.

• JESSEIONID는 로그인 성공시 발급되는 Session Cookie 입니다.

• remember-me는 user 정보가 담겨있는 Token으로, server로 request 요청시 JESSIONID와 함께 header에 전달됩니다.

• server에서 session이 expire되면, server는 remember-me token으로 authenticated된 사용자임을 확인할 수 있습니다.

• remember-me token에는 사용자의 정보 및 expiration date가 hash되 담겨있습니다.

• server는 remember-me token이 expiration되지 않았다면, 사용자에게 authentication process를 재수행하도록 요구하지 않습니다. remember-me token이 사용자의 authentication을 증명하기 때문입니다.

모든 설정을 완료하였습니다. 이제 Spring Boot App에 Form Authenticaiton을 적용할 수 있게되었습니다. 👏👏👏


참고 자료 : https://www.youtube.com/playlist?list=PLVApX3evDwJ1d0lKKHssPQvzv2Ao3e__Q


추천서적

 

스프링5 레시피:스프링 애플리케이션 개발에 유용한 161가지 문제 해결 기법

COUPANG

www.coupang.com

파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있음


반응형

댓글

Designed by JB FACTORY