[출처 : http://zgundam.tistory.com/m/post/51]
이 화면은 로그인 화면에서 로그인이 정상적으로 이루어진 뒤에 자동으로 메인화면으로 이동했을때 로그인 폼이 그대로 나타나고 있기 때문에 로그인이 정상적으로 되었는지 알 수가 없다. 이 부분을 이제 바꾸어보도록 하겠다.
1. Custom Tag를 등록한다.
-Spring Security에서는 jsp 페이지에서 사용할 수 있는 Custom Tag를 제공한다.
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
=> 공통 include 파일이든 또는 Spring Security의 기능을 jsp 페이지에서 써야 하는 곳에서든 저 코드를 넣어서 Spring Security가 제공하는 tag를 사용할 수 있게해준다.
먼저 Spring Security에서 로그인 정보를 가져오는 방법에 대해 설명하도록 하겠다. 2가지의 방법이 있는데 Spring Security가 자체적으로 제공하는 방법과 HttpServletRequest 객체에서 가져오는 방법이렇게 2가지가 있다.
Servlet Spec 2.5에서는 인증 과정을 마치고 난 뒤의 로그인 정보를 가져오는 기능만 있었으나 Servlet Spec 3.0 이상에서는 Spring Security가 제공하는 인증 기능을 이용해 로그인 하거나 로그아웃 하는 기능도 사용할 수 있다.
Servlet Spec 3.0 이상을 사용하는 WAS는 Tomcat 7.0 이상을 사용하면 된다.
Spring Security가 자체적으로 제공하는 방법
<%@
page import="org.springframework.security.core.context.SecurityContextHolder" %> <%@ page import="org.springframework.security.core.Authentication" %> <%@ page import="com.terry.springsecurity.vo.MemberInfo" %> <% Authentication auth = SecurityContextHolder.getContext().getAuthentication(); Object principal = auth.getPrincipal(); String name = ""; if(principal != null && principal instanceof MemberInfo){ name = ((MemberInfo)principal).getName(); } %>
위의 코드에서 보듯이 HttpServletRequest 클래스의 getUserPrincipal() 메소드를 이용해서 인증 정보를 가져오고 있다.
로그인이 성공했을 경우엔 두 방법 모두 org.springframework.security.authentication.UsernamePasswordAuthenticationToken 객체를 받아온다.
그러나 로그인을 하지 않은, 즉 Anonymous 사용자인 경우엔 두 가지 방법에 차이점이 존재한다.Anonymous 사용자인 경우 Spring Security를 이용하는 방법에서는 org.springframework.security.authentication.AnonymousAuthenticationToken 객체가 return 되지만 HttpServletRequest를 이용하는 방법에서는 null이 return 되기 때문이다. 그래서 Spring Security를 이용하는 방법에서는 인증 정보를 받는 변수인 auth에 대한 null 체크를 하지 않지만 HttpServletRequest를 이용하는 방법에서는 인증 정보를 받는 변수인 auth에 대한 null 체크를 하게 되는 것이다.
<div style="width:200px;float:left;">
<sec:authorize access="isAnonymous()"> <form id="loginfrm" name="loginfrm" method="POST"
action="${ctx}/j_spring_security_check"> <table> <tr> <td style="width:50px;">id</td> <td style="width:150px;"> <input style="width:145px;" type="text" id="loginid" name="loginid" value=""/> </td> </tr> <tr> <td>pwd</td> <td> <input style="width:145px;" type="text" id="loginpw" name="loginpw" value=""/> </td> </tr> <tr> <td colspan="2"> <input type="submit" id="loginbtn" value="로그인" /> </td> </tr> </table> </form> </sec:authorize> <sec:authorize access="isAuthenticated()"> <%=name%>님 반갑습니다<br/> <a href="${ctx}/j_spring_security_logout">로그아웃</a> </sec:authorize> <ul> <sec:authorize access="hasRole('ROLE_ADMIN')"> <li>관리자 화면</li> </sec:authorize> <sec:authorize access="permitAll"> <li>비회원 게시판</li> </sec:authorize> <sec:authorize access="isAuthenticated()"> <li>준회원 게시판</li> </sec:authorize> <sec:authorize access="hasAnyRole('ROLE_MEMBER2', 'ROLE_ADMIN')"> <li>정회원 게시판</li> </sec:authorize> </ul> </div>
로그인 id test1에 준회원 권한을 DB에서 설정해 둔 뒤에 로그인을 한 모습이다.
로그인 한 사람의 이름(테스트1)을 보여주고 있고 로그아웃 링크를 보여주고 있다. 또 준회원 권한(ROLE_MEMBER1)을 가지고 있기 때문에 비회원 게시판과 준회원 게시판 메뉴를 보여주고 있다. 관리자 권한(ROLE_ADMIN)을 주면 정회원 게시판과 관리자 화면 메뉴도 나타날 것이다. 이렇게 권한을 이용한 동적 메뉴 화면 모습을 보여주고 있다. 잘 이해가 안되면 <sec:authorize> 태그 설명한 부분을 다시 한번 읽어보면서 화면과 매핑을 시켜보면 이해가 될 것이라고 생각한다.
이제는 로그아웃을 설명할 차례이다. 지금까지 블로그에서 설명하면서 화면상에서 로그아웃을 보여주는 부분이 없어서 로그아웃에 대한 설정을 설명할 일이 없었으나 이제는 로그아웃이 언급되다보니 로그아웃 설정에 대한 설명을 할 시점이 되었다. 로그아웃을 실행시킬려면 j_spring_security_logout 으로 링크를 걸면 로그아웃 기능을 수행한다(j_spring_security_logout 이란 문자열이 길어서 거부감이 있다면 이것도 바꿀수 있다. 곧 이어 설명할 logout 태그의 logout-url 속성에 원하는 값을 지정해주면 된다. 이 속성의 default 값이 j_spring_security_logout 이다). 또한 로그아웃에 대한 설정을 <http> 태그 안에 다음과 같은 내용으로 넣도록 한다.
<logout
logout-success-url="/main.do" delete-cookies="JSESSIONID" />
logout-success-url 속성은 로그아웃 작업을 마친 뒤에 보여지는 화면 URL을 설정한다.
delete-cookies는 로그아웃을 진행하면서 지워야 할 쿠키를 지정하는 속성이다. ,를 구분자로 하여 여러개의 쿠키 이름을 지정하면 된다. WAS를 통해 웹브라우저로 웹페이지를 보면 JSESSIONID란 이름의 쿠키가 내려오는데 로그아웃을 하면서 이 쿠키도 같이 정리하기 위해 delete-cookies 속성에 지정하는 것이다. 만약 다른 이름의 쿠키가 내려오거나 또는 사이트에서 로그인을 하면 내부적으로 특정 쿠키를 생성해서 작업하고 있다면 이 delete-cookies 속성을 이용해서 그런 부류의 쿠키를 지울수가 있는 것이다.