7월 26일
1.자동로그인
로그인을 하면 일정시간동안 다시 로그인을 하지 않아도 되는 기능을 가지고 있다.
이 기능은 쿠키를 활용하여 구현됨.
security-context.xml에는 '<security:remember-me> 태그를 이용해서 기능구현이 가능하다. 아래와 같이 여러 속성값을 지정할수 있다.
key:쿠키에 사용되는 값을 암호화하기 위한 키(key)값
data-source-ref:DataSource를 지정하고 테이블을 이용해서 기존 로그인 정보를 기록
remember-me-cookie:브라우저에 보관되는 쿠키의 이름을 지정합니다. 기본값은'remember-me' 임
remember-me-parameter:웹 화면에서 로그인 할때 remember-me는 대부분 체크박스를 이용해서 처리합니다. 이때 체크박스 태그는 name속성을 의미합니다.
token-validity-second:쿠키유효시간을 지정합니다.
2.데이터베이스를 이용하는 자동 로그인
로그인 되었던 정보를 데이터베이스를 이용해서 기록해 두었다가 사용자의 재방문시 세션에 정보가 없으면 데이터베이스를 조회해서 사용하는 방식이다.
(1)테이블 만들기
테이블 이름과 칼럼명을 꼭 맞춰줘야한다.
왜? 그래야 스프링시큐리티가 활용할수 있다.
create table persistent_login(
username VARCHAR2(64) not null,
series VARCHAR2(64) primary key,
token VARCHAR2(64) not null,
last_used timestamp not null
);
(2)security-context.xml 설정
자동 로그인에서 데이터베이스를 이용하는 설정은 별도의 설정없이 data-source-ref
만을 지정하면 됨.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="customAccessDenied" class="com.keduit.security.CustomAccessDeniedHandler"></bean>
<bean id="customLoginSuccess" class="com.keduit.security.CustomLoginSuccessHandler"></bean>
<bean id="bcryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"></bean>
<bean id="customUserDetailsService" class="com.keduit.security.CustomUserDetailsService"></bean>
<security:http>
<security:intercept-url pattern="/sample/all" access="permitAll"/>
<security:intercept-url pattern="/sample/member" access="hasRole('ROLE_MEMBER')"/>
<security:intercept-url pattern="/sample/admin" access="hasRole('ROLE_ADMIN')"/>
<!--/accessError 라는 uri로 접근제한 시 보이는 화면을 처리합니다-->
<security:access-denied-handler ref="customAccessDenied"/>
<!-- 로그인페이지 따로 URI 설정하기 -->
<security:form-login login-page="/customLogin" authentication-success-handler-ref="customLoginSuccess" />
<!-- 로그아웃 페이지 URI 설정하기 -->
<security:logout logout-url="/customLogout" invalidate-session="true"/>
<!-- 자동로그인 설정 -->
<security:remember-me data-source-ref="dataSource" token-validity-seconds="604800"/>
</security:http>
<security:authentication-manager>
<security:authentication-provider user-service-ref="customUserDetailsService">
<security:password-encoder ref="bcryptPasswordEncoder"/>
</security:authentication-provider>
</security:authentication-manager>
</beans>
(3)customLogin.jsp 수정
체크박스에 remember-me를 체크하면 스프링시큐리티가 security-context.xml을 참고하여 자동로그인 기능을 수행한다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>Custom Login Page!!!!!!!!</h1>
<h2><c:out value="${error}"/></h2>
<h2><c:out value="${logout}"/></h2>
<form method="post" action="/login" >
<div>
<input type="text" name="username" value="admin90">
</div>
<div>
<input type="password" name="password" value="pw90">
</div>
<div>
<input type="checkbox" name="remember-me">자동로그인
</div>
<div>
<input type="submit">
</div>
<!-- EL의 값은 실제 브라우져에서는 '_csrf'라는 이름으로 처리됩니다. -->
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
</body>
</html>
3.로그아웃시 쿠키 삭제
로그아웃을 하면 자동로그인에서 사용하는 쿠키도 삭제해 주어야한다.
(1)security-context.xml 수정
쿠키의 이름은 'remember-me'이고, Tomcat을 통해서 실행되고 있었다면 WAS가 발행하는 쿠키의 이름은 JSESSION_ID이며, Tomcat에서 발행한 쿠키도 같이 삭제해주게 좋다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="customAccessDenied" class="com.keduit.security.CustomAccessDeniedHandler"></bean>
<bean id="customLoginSuccess" class="com.keduit.security.CustomLoginSuccessHandler"></bean>
<bean id="bcryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"></bean>
<bean id="customUserDetailsService" class="com.keduit.security.CustomUserDetailsService"></bean>
<security:http>
<security:intercept-url pattern="/sample/all" access="permitAll"/>
<security:intercept-url pattern="/sample/member" access="hasRole('ROLE_MEMBER')"/>
<security:intercept-url pattern="/sample/admin" access="hasRole('ROLE_ADMIN')"/>
<!--/accessError 라는 uri로 접근제한 시 보이는 화면을 처리합니다-->
<security:access-denied-handler ref="customAccessDenied"/>
<!-- 로그인페이지 따로 URI 설정하기 -->
<security:form-login login-page="/customLogin" authentication-success-handler-ref="customLoginSuccess" />
<!-- 로그아웃 페이지 URI 설정하기 -->
<security:logout logout-url="/customLogout" invalidate-session="true"/>
<!-- 자동로그인 설정 -->
<security:remember-me data-source-ref="dataSource" token-validity-seconds="604800"/>
<!-- 로그아웃시 쿠키삭제 -->
<security:logout logout-url="/customLogout" invalidate-session="true" delete-cookies="remember-me,JSESSION_ID"/>
</security:http>
<security:authentication-manager>
<security:authentication-provider user-service-ref="customUserDetailsService">
<security:password-encoder ref="bcryptPasswordEncoder"/>
</security:authentication-provider>
</security:authentication-manager>
</beans>