본문으로 바로가기

Spring Security 3.x 버전에서 Spring Security 4.x 버전으로 올라가면서 변경된 것들이 있다. 스프링 시큐리티 3 버전으로 공부를 하다가 까먹기전에 정리글을 쓰면서 공부하자는 생각에 새로운 프로젝트를 만들었다. 근데 왜인지 모르겠지만 새 프로젝트에는 스프링 시큐리티 4 버전을 적용했다. 그래서 공부할 때와 똑같이 따라가는데 자꾸 안되서 물음표만 백만개 띄웠다 ㅎㅎ 보다보니 버전이 다른 게 문제가 되는 건가 싶었고, 찾아보니 스프링 시큐리티 3버전에 4버전으로 갈 때 XML 속성들의 기본값이 변경되었다고 한다.. 에잇! 그래서 영문서를 읽었다 ㅠ 과거의 나 덕분에 더 공부했네 (ㅎㅁㅎ) 사족은 이쯤하고, 변경된 것들을 확인하자.



우선 스프링 시큐리티 4 부터는 CSRF 방지 기능이 디폴트로 작동한다. 스프링 시큐리티 3은 선택이였다. 그래서 CSRF 태그를 명시하지 않으면 적용되지 않았다. 하지만, 스프링 시큐리티 4는 디폴트이기때문에 필수로 적용된다. 만약 CSRF를 사용하고 싶지 않다면, CSRF 태그에 disabled="true" 를 명시하면 된다. 


1
<input type="hidden" name="${_csrf.parameterName}" value="${_crsf.token}" />
cs

또한 PATCH, POST, PUT, DELETE 요청에 CSRF 토큰을 반드시 포함해야 한다. 로그인, 로그아웃 설정과 화면을 커스터마이징 한다면, CSRF를 설정하고 폼(form)에 다음을 추가해야 한다.



다음으로 스프링 시큐리티 4 부터 http 자식 요소들 속성의 기본값이 변경되었다. 스프링 시큐리티 3에서 스프링 시큐리티 4로 버전을 변경한다면 여기를 눈여겨 봐야 한다. 커스터마이징을 완전히 다 했다면 상관하지 않아도 될 지 모르겠지만, 혹시라도 기본 속성을 그대로 쓸려고 생략까지 했다면 반드시 확인해야한다. 바뀐 속성값들을 확인하고 명시해야할 것은 반드시 명시해야한다. 그래야 이유를 알 수 있는 에러를 확인하여 고칠 수 있기 때문이다.



1) use-expressions

1
2
3
4
<http auto-config="true">
    <intercept-url pattern="/member/**" access="hasAnyRole('ROLE_MEMBER','ROLE_ADMIN')"/>
    <intercept-url pattern="/**" access="permitAll"/>
</http>
cs

SpEL 문법을 사용할 수 있게 해주는 use-expressions 속성이 false 에서 true로 변경되었다.  따라서 <http> 태그에 use-expressions 속성을 생략하고 SpEL 문법을 사용해도 된다. 만약에 스프링 시큐리티 3에서 use-expressions을 사용하지 않았다면, use-experssions 속성을 false로 설정하여 사용해야 한다.



2) <form-login />

1
2
3
4
5
6
<form-login
    login-processing-url="/login"
    username-parameter="username"
    password-parameter="password"
    authentication-failure-url="/login?error=1"
/>
cs

login-processing-url 속성의 기본값이 /j_spring_security_check 에서 POST /login 으로 변경되었다.

username-parameter 속성의 기본값이 j_username 에서 username 으로 변경되었다.

password-parameter 속성의 기본값이 j_password 에서 password 로 변경되었다.

authentication-failure-url 속성의 기본값이 /j_spring_security_login/login_error 에서 /login?error=1 로 변경되었다.


스프링 시큐리티 4 기본 로그인 HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<body onload="document.f.username.focus();">
    <h3>Login with Username and Password</h3>
    <form name="f" action="/login" method="POST">
        <table>
            <tbody>
                <tr>
                    <td>User:</td>
                    <td><input type="text" name="username" value=""></td>
                </tr>
                <tr>
                    <td>Password:</td>
                    <td><input type="password" name="password"></td>
                </tr>
                <tr>
                    <td colspan="2"><input name="submit" type="submit" value="Login"></td>
                </tr>
                <input name="${_csrf.parameterName}" type="hidden" value="${_crsf.token}">
            </tbody>
        </table>
    </form>
</body>
cs



스프링 시큐리티 4의 <form-logn/> 태그 자식 요소들의 기본값 속성들이 변경된 것을 확인할 수 있다. form 태그의 action 속성의 값이 /login 으로 변경되었고, input 태그의 name과 password의 name 속성이 각각 username, password로 변경되었다. 그리도 또 하나의 큰 변화는 17행에 CSRF 토큰이 추가된 것을 확인할 수 있다. 스프링 시큐리티 3에서는 CSRF를 선택적으로 할 수 있었지만, 스프링 스큐리티 4에서는 CSRF가 기본으로 규정했기 때문에 CSRF 토큰이 추가되었다.



3) <logout />

1
2
3
<logout
    logout-url="/logout"
/>
cs

logout-url 속성의 기본값이 /j_spring_security_logout 에서 POST /logout 으로 변경되었다.


스프링 시큐리티 4 기본 로그아웃 HTML

1
2
3
4
<form action="/logout" method="POST">
    <input type="submit" value="LOGOUT"/>
    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
cs

이전에는 로그아웃 url이 링크 형태여도 상관없었다. 하지만 스프링 시큐리티 4에서는 POST형식의 /logout 으로 변경되었기에 링크 형태는 사용하지 못한다. 따라서 로그아웃이 반드시 form 태그의 POST 형식이여야 한다. 그리고 또 한가지, 3행처럼 CSRF 토큰을 반드시 추가해야한다.



4) <remember-me />

1
2
3
4
<remember-me
    remember-me-parameter="remember-me" 
    remember-me-cookie="remember-me"
/>
cs

remember-me-parameter 속성의 기본값이 _spring_security_remember_me 에서 remember-me 로 변경되었다.

remember-me-cookie 속성의 기본값이 SPRING_SECURITY_REMEMBER_ME_COOKIE 에서 remember-me 로 변경되었다.


스프링 시큐리티 4 기본 remember-me HTML

1
2
3
4
5
6
7
<form name="f" action="/login" method="POST">
    ...
    <p><label for="remember-me">Remember Me</label></p>
    <input type="checkbox" id="remember-me" name="remember-me"/>
    <input type="hidden" name="${_csrf.parameterName}" value="${_crsf.token}"/>
    ...
</form>
cs

마찬가지로 parameter를 커스텀했다면 수정하지 않아도 되지만, 커스텀을 하지 않았다면 바뀐 기본 속성으로 명시해주어야 한다.



스프링 시큐리티 3 버전에서 스프링 시큐리티 4 버전으로 업그레이드될 때 변경된 점들을 몇가지 확인해보았다. 사실 이 외에도 변경된 부분들이 있다. 내가 공부하면서 사용한 부분에서만 찾은 것이기 때문에 다른 것들도 자세히 보고 싶다면 해당 문서를 직접 확인해보면 된다. 쫄지말고 구글 번역기의 힘을 빌리자(ㅎㅁㅎ) 공부하다가 또 영문서를 맞이할 거 같은 기분이다..