7월 27일
1.기존프로젝트에 시큐리티 접목하기
(1)로그인 페이지 처리
페이지 처리시 가장 신경써야 하는 항목은 'form'태그 내의'input'태그들의 name속성이다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>로그인 페이지</title>
<!-- Bootstrap Core CSS -->
<link href="/resources/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<!-- MetisMenu CSS -->
<link href="/resources/vendor/metisMenu/metisMenu.min.css" rel="stylesheet">
<!-- Custom CSS -->
<link href="/resources/dist/css/sb-admin-2.css" rel="stylesheet">
<!-- Custom Fonts -->
<link href="/resources/vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="login-panel panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Please Sign In</h3>
</div>
<div class="panel-body">
<form role="form" method='post' action="/login">
<fieldset>
<div class="form-group">
<input class="form-control" placeholder="userid" name="username" type="text" autofocus>
</div>
<div class="form-group">
<input class="form-control" placeholder="Password" name="password" type="password" value="">
</div>
<div class="checkbox">
<label>
<input name="remember-me" type="checkbox">Remember Me
</label>
</div>
<!-- Change this to a button or input when using this as a form -->
<a href="index.html" class="btn btn-lg btn-success btn-block">Login</a>
</fieldset>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
</div>
</div>
</div>
</div>
</div>
<!-- jQuery -->
<script src="/resources/vendor/jquery/jquery.min.js"></script>
<!-- Bootstrap Core JavaScript -->
<script src="/resources/vendor/bootstrap/js/bootstrap.min.js"></script>
<!-- Metis Menu Plugin JavaScript -->
<script src="/resources/vendor/metisMenu/metisMenu.min.js"></script>
<!-- Custom Theme JavaScript -->
<script src="/resources/dist/js/sb-admin-2.js"></script>
<script>
$(".btn-success").on("click",function(e){
e.preventDefault();
$("form").submit();
});
</script>
</body>
</html>
이전 예제에서는 CustomLoginSuccessHandler를 이용해서 사용자의 권한에 따라 페이지이동을 했는데, 스프링 시큐리티에서는 로그인후 처리는 SavedRequestAwareAuthenticationSuccessHandler라는 클래스를 이용함.
해당 클래스는 사용자가 원래 보려고 했던 페이지의 정보를 유지해서 로그인후에 다시 원했던 페이지로 이동하는 방식
(2)security-context.xml 설정
SavedRequestAwareAuthenticationSuccessHandler를 이용하는 설정은 기존에 xml설정을 이용하면 된다.
<!-- <bean id="customLoginSuccess" class="com.keduit.security.CustomLoginSuccessHandler"></bean> -->
<security:form-login login-page="/customLogin"/>
(3)BoardController 수정
@PreAuthorize를 이용할 때의 표현식은 isAuthenticated()로 어떠한 사용자든
로그인이 성공한 사용자만 해당 기능을 사용할수 있도록 처리함.
@GetMapping("/register")
@PreAuthorize("isAuthenticated()")
public void registerGET() {
}
@PostMapping("/register")
@PreAuthorize("isAuthenticated()")
public String register(BoardVO board, RedirectAttributes rttr) {
log.info("register..........");
log.info("board====>"+board);
Long bno=service.selectInsertKey(board);
log.info("bno:"+bno);
rttr.addFlashAttribute("result",bno);
return "redirect:/board/list";
}
(4)register.jsp 수정
스프링 시큐리티의 영향을 받는 jsp파일에는 반드시 시큐리티 관련 태그 라이브러리를 설정하도록 신경써야함.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib uri="http://www.springframework.org/security/tags" prefix="sec" %>
<%@include file="../includes/header.jsp"%>
<div class="row">
<div class="col-lg-12">
<h1 class="page-header">Board Register</h1>
</div>
<!-- /.col-lg-12 -->
</div>
<!-- /.row -->
<div class="row">
<div class="col-lg-12">
<div class="panel panel-default">
<div class="panel-heading">
Board Register
</div>
<!-- /.panel-heading -->
<div class="panel-body">
<form role="form" action="/board/register" method="post">
<div class="form-group" >
<label>title</label>
<input class="form-control" name="title">
</div>
<div class="form-group">
<label>content</label>
<textarea rows="5" cols="50" name="content" class="form-control"></textarea>
</div>
<div class="form-group">
<label>writer</label>
<input class="form-control" name="writer" value='<sec:authentication property="principal.username"/>' readonly="readonly">
</div>
<button type="submit" class="btn btn-default">글올리기</button>
<button type="reset" class="btn btn-default">다시작성하기</button>
</form>
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
</div>
<!-- /.col-lg-12 -->
</div>
<!-- /.row -->
<%@include file="../includes/footer.jsp"%>
(5)CSRF 토큰 설정
스프링 시큐리티를 사용할때 post 방식의 전송은 반드시 CSRF토큰을 사용하도록 추가해야만 함.
register.jsp 를 아래와 같이 수정.
<form role="form" action="/board/register" method="post">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
(6)스프링 시큐리티 한글처리
스프링 시큐리티 적용 이후에 한글이 깨지는 문제가 발생할 수 있다.
한글처리는 web.xml을 이용해서 스프링의 'CharacterEncodingFilter'를 이용해서 처리하지만, 시큐리티 필터로 적용 할때 필터의 순서를 주의해서 설정.
*인코딩 설정을 먼저 적용하고, 스프링 시큐리티 적용
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- 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</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<servlet-name>appServlet</servlet-name>
</filter-mapping>
<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>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>