pom.xml 에 dependency 추가
<!-- spring-security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.2.15.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.2.15.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>5.2.15.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>5.2.15.RELEASE</version>
</dependency>
web.xml
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/root-context.xml
/WEB-INF/spring/security-context.xml <!-- 이거 추가 -->
</param-value>
</context-param>
<!-- Security filter -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<servlet-name>/*</servlet-name>
</filter-mapping>
security-context.xml 생성 (beans, security 체크)
<?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-5.2.xsd>">
<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')"/>
<security:form-login/> <!-- login-page="/customLogin" : 로그인 페이지 설정 속성 -->
<!-- 접근 불가 메시지 페이지 설정 -->
<security:access-denied-handler error-page="/accessDenied"/>
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="member" password="{noop}1111" authorities="ROLE_MEMBER"/>
<security:user name="admin" password="{noop}1111" authorities="ROLE_ADMIN, ROLE_MEMBER"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans>
접근 불가 메시지 핸들러와 연결
<!-- 핸들러 빈으로 등록 -->
<bean id="customAccessDenied" class="edu.springz.security.CustomAccessDeniedHandler"/>
<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')"/>
<security:form-login/>
<!-- 접근 불가 메시지 설정 -->
<security:access-denied-handler ref="/customAccessDenied"/>
</security:http>
로그인 페이지 지정 (컨트롤러 매핑 필요)
<security:form-login login-page="/customLogin"/>
컨트롤러 매핑 예시
@GetMapping("/customLogin")
public void customLogin(String error, String logout, Model model) {
log.info("customLogin()");
log.info("error : " + error);
log.info("logout" + logout);
if (error != null) {
model.addAttribute("error", "로그인 에러 - 계정을 확인해 주세요.");
}
if (logout != null) {
model.addAttribute("logout", "로그아웃이 완료되었습니다.");
}
}
JSP form 설정
action="/login"
method="post”
name=”username” / “password”
폼데이터 전송 시 고려할 사항들
히든 인풋 태그로 추가
<input type="hidden" name="${ _csrf.parameterName }" value="${ _csrf.token }">
로그인 성공 핸들러 연결
<bean id="customLoginSuccess" class="edu.springz.security.CustomLoginSuccessHandler"/>
<security:http>
<!-- 로그인 페이지 지정 / 로그인 성공 핸들러 지정 -->
<security:form-login login-page="/customLogin" authentication-success-handler-ref="customLoginSuccess"/>
</security:http>
로그아웃
<!-- 로그아웃 페이지 지정 및 로그아웃 처리 -->
<security:logout logout-url="/customLogout" invalidate-session="true"/>
jsp
<form action="/customLogout" method="post">
<input type="hidden" name="${ _csrf.parameterName }" value="${ _csrf.token }">
<button>로그 아웃</button>
</form>
<security:authentication-manager><security:authentication-provider>
<!-- dataSource빈이 등록돼있어야 함 -->
<security:jdbc-user-service data-source-ref="dataSource"/>
</security:authentication-provider></security:authentication-manager>
security-context.xml
<!-- 빈 등록 -->
<bean id="customPasswordEncoder" class="edu.springz.security.CustomNoOpPasswordEncoder"/>
<security:authentication-manager>
<security:authentication-provider>
<security:jdbc-user-service data-source-ref="dataSource"/>
<security:password-encoder ref="customPasswordEncoder"/> <!-- 이거 등록 -->
</security:authentication-provider>
</security:authentication-manager>
이전에 in-memory 유저를 생성하여 인증과 인가를 구현했었다.실제 서비스에는 유저의 데이터를 데이터베이스에 저장해야하니 JDBC를 이용해 인증과 인가를 처리해야 한다.
일단 MyBatis나 기타 프레임워크 없이 사용하는 방법을 익혀보자.