[Spring Security] Spring Boot를 이용한 Form Authentication

dev-log·2021년 10월 10일
0

Spring Security

목록 보기
3/6

1. Form Authentication

이번에는 이전에 생성한 spring boot app에 Form Authentication을 적용해본다.(이전에 생성한 app은 여기에서 확인할 수 있다.)

이전까지는 사용자가 로그인할 때 위의 사진과 같이 브라우저에서 직접 로그인창을 띄워줬다.
이러한 인증 방법을 Http Basic Authentication이라고 하며, 이를 사용하기 위해선 spring boot에서는 securityConfiguration(Configuration)에 httpBasic()을 정의했다.

이제는 브라우저가 띄워주는 창이 아닌 Login Page를 만들어서 인증을 하려 한다.

2. Form Login Page

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

2-1) html

login.html

Thymeleaf를 이용했다.

<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>

• POST 방식으로 username과 password를 전송하는 form을 생성했다.

• 로그인하는 url은 /login이다. 이는 Spring Security의 기본 로그인 url이다.

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

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

2-2) controller

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

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

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

3.Spring Security에 연결하기

이제 위에서 생성한 Login Form을 Spring Security에 연결한다.

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

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

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

4. 실행 화면

localhost:8080/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설정을 추가한다.

	.and()
        .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login");
    

6. 실행 화면



위에 logout버튼이 생성됐다.

logout버튼을 누르면 /login으로 redirect된다.

7. Remember Me(자동 로그인)

Remember Me는 자신의 로그인을 유지해주는 자동 로그인 기능이다.

7-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을 수행하지 않아도 된다.

7-2)configure 설정 하기

SecurityConfiguration

.and()
.rememberMe().tokenValiditySeconds(360000000).key("mySecretKey");

• rememberMe( )를 선언합니다.

• rememberMe token의 validation 기간을 정의한다.

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

8. 실행 화면 (Remember me)


login 페이지에 remember버튼이 추가됐다.

remember버튼을 체크하고 로그인 하면 Cookie가 2개 생성된 것을 위의 사진에서 확인할 수 있다.
Cookie 확인하는 법 :
개발자 도구 -> Application -> Cookies

• JESSEIONID는 로그인 성공시 발급되는 Session Cookie 이다.
(remember me버튼을 체크하지 않고 로그인하면 이 쿠키만 생성된다.)

• 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이 만기되지 않았다면, 사용자에게 authentication process를 재수행하도록 요구하지 않는다. remember-me token이 사용자의 authentication을 증명하기 때문이다.

profile
배운 걸 기록하는 곳입니다.

0개의 댓글