스프링 시큐리티는 메모리나 데이터베이스를 사용하여 처리한다.
기능을 구현하기 위해 security:remember-me 태그를 이용하여 시큐리티 설정 파일을 수정한다.
create table persistent_logins(
username varchar2(64) not null,
series varchar2(64) not null,
token varchar2(64) not null,
last_used date not null,
constraint pk_persistent_logins primary key(series)
);
스프링 시큐리티 설정
→ security-context.xml 설정
<security:remember-me data-source-ref="dataSource" token-validity-seconds="604800"/> 태그 설정
<security:logout logout-url="/logout" invalidate-session="true" delete-cookies="JSESSION_ID, remember-me"/> 태그설정
<?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/beans> <http://www.springframework.org/schema/beans/spring-beans.xsd>
<http://www.springframework.org/schema/security> <http://www.springframework.org/schema/security/spring-security.xsd>">
<bean id="customAccessDenied" class="kr.or.ddit.security.CustomAccessDeniedhandler"></bean>
<bean id="customLoginSuccess" class="kr.or.ddit.security.CustomLoginSuccessHandler"></bean>
<!-- 사용자가 정의한 비밀번호 암호화 처리기를 빈으로 등록 -->
<!-- <bean id="customPasswordEncoder" class="kr.or.ddit.security.CustomNoOpPasswordEncoder"></bean> -->
<!-- 스프링 시큐리티에서 제공하는 BCryptPasswordEncoder 클래스를 자바빈으로 등록 -->
<bean id="bcryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"></bean>
<!-- 사용자 정의 사용자 상세 기능 ***** 중요!! -->
<bean id="customUserDetailsService" class="kr.or.ddit.security.CustomUserDetailsService"></bean>
<security:http>
<security:intercept-url pattern="/board/list" access="permitAll"/>
<security:intercept-url pattern="/board/register" access="hasRole('ROLE_MEMBER')"/>
<security:intercept-url pattern="/notice/list" access="permitAll"/>
<security:intercept-url pattern="/notice/register" access="hasRole('ROLE_ADMIN')"/>
<!-- 로그인 성공 후 처리를 담당하는 처리자로 지정한다. -->
<security:form-login login-page="/login" authentication-success-handler-ref="customLoginSuccess"/>
**<!--
자동 로그인
- 데이터 소스를 지정하고 테이을 이용해서 기존 로그인 정보를 기록
- 쿠키의 유효시간을 짖어한다. (604800 : 7일)
-->
<security:remember-me data-source-ref="dataSource" token-validity-seconds="604800"/>**
<!-- 로그아웃 처리를 위한 URI를 지정하고, 로그아웃 한 후에 세션을 무효화하기 위한 설정을 true로 한다. -->
**<!-- 로그아웃을 하면 자동 로그인에 사용하는 쿠키도 삭제해 주도록 설정(delete-cookies) -->**
<security:logout logout-url="/logout" invalidate-session="true" **delete-cookies="remember-me, JSESSION_ID"**/>
<!--
로그인이 된 회원 중에 권한이 없을 때, 접근 access 거부 denined 처리자 handler의 URI를 지정합니다.
-->
<!-- <security:access-denied-handler error-page="/accessError"/> -->
<!-- 등록한 CustomAccessDeniedHandler클래스를 활용한 거부 처리자로 지정한다. -->
<security:access-denied-handler ref="customAccessDenied"/>
</security:http>
<!-- 지정된 아이디와 패스워드로 로그인이 가능하도록 설정한다. -->
<security:authentication-manager>
<security:authentication-provider user-service-ref="customUserDetailsService">
<security:password-encoder ref="bcryptPasswordEncoder"/>
</security:authentication-provider>
</security:authentication-manager>
</beans>
로그인 상태 유지 체크박스 추가
→ loginForm.jsp 수정
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="<http://java.sun.com/jsp/jstl/core>" prefix="c" %>
<%@ taglib uri="<http://www.springframework.org/security/tags>" prefix="sec"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>LoginForm</h1>
<h2><c:out value="${error }"/></h2> <!-- 에러 발생 시, 출력할 메시지 -->
<h2><c:out value="${logout }"/></h2> <!-- 로그아웃 시, 출력할 메시지 -->
<form method="post" action="/login">
username : <input type="text" name="username" value="admin"><br>
password : <input type="text" name="password" value="admin"><br>
**<!-- 로그인 상태 유지 체크박스 -->
<input type="checkbox" name="remember-me">Remember me**
<input type="submit" value="로그인">
<sec:csrfInput/>
</form>
</body>
</html>
💡 자동 로그인 시, 만들어지는 쿠키정보들
JSESSIONID와 remember-me 쿠키가 만들어진다.
JSESSIONID를 삭제 후, 다시 로그인을 진행하더라도 로그인 후 진행될 페이지가 정상적으로 나타나는걸 확인할 수있습니다.
→ 자동 로그인이 remember-me에 의해 실행 됨을 확인할 수 있습니다.
