• 지금 까지는 권한이 없는 사용자가 접근을 하게 되면 따로 설정을 하지않아 아래와 같은페이지로 이동을 했다.

img1

아마 저런 페이지로 놔둘곳은 없을 것이다. security에서 처리 방법을 보면 url을 지정하여 접근 권한이 없으면 해당 url로 이동시키는 방법이 있고, 아니면 AccessDeniedHandler 인터페이스를 구현하여 지정하는 방법이 있다.

url로 지정하는 방법을 알아보면

  • <http>access-denied-page="" 속성 추가

  • 해당 주소로 접속 할 Controller추가

@RequestMapping("/user/denied")
public String denied(Model model, Authentication auth, HttpServletRequest req){
AccessDeniedException ade = (AccessDeniedException) req.getAttribute(WebAttributes.ACCESS_DENIED_403);
logger.info("ex : {}",ade);
 model.addAttribute("auth", auth);
 model.addAttribute("errMsg", ade);
 return "/user/denied";
}
  • 이동할 jsp생성 (views/user/denied.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" %>

<link rel="stylesheet" type="text/css" href="&lt;c:url value=" resources="" css="" main.css"="">"&gt;
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>

${errMsg }
${auth }

  • 권한 없는 페이지 접속 하여 확인

여기서 확인 할 부분은

AccessDeniedException ade = (AccessDeniedException) req.getAttribute(WebAttributes.ACCESS_DENIED_403);

이다. 권한 없는 사용자가 접근을 하게 되면 security에서 해당 request​AccessDeniedException 을전달 하는데 속성명은 ​WebAttributes.ACCESS_DENIED_403 로 전달 한다.


다음으로 ​AccessDeniedHandler를 구현하여 빈을 등록 하는 방법을 살펴 보겠다.

  • AccessDeniedHandler​ 을 상속받아 구현할
  • ​UserDeniedHandler 클레스 생성
package com.min.study.user.service;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;

public class UserDeniedHandler implements AccessDeniedHandler{

private static final Logger logger = LoggerFactory.getLogger(UserDeniedHandler.class);

@Override
public void handle(HttpServletRequest req, HttpServletResponse res,
  AccessDeniedException ade) throws IOException, ServletException {
 // TODO Auto-generated method stub
 logger.info("Exceiption : {}",ade);
 logger.info("LocalizedMessage : {}",ade.getLocalizedMessage());
 logger.info("Message : {}",ade.getMessage());
 logger.info("StackTrace : {}",ade.getStackTrace());

 req.setAttribute("errMsg",ade.getMessage());
 req.getRequestDispatcher("/WEB-INF/views/user/denied.jsp").forward(req, res);
}

}
  • security-context.xml에 빈등록 & http에 해당빈 추가
<http auto-config="true" use-expressions="true" create-session="never">
 <intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
 <intercept-url pattern="/user/**" access="permitAll" />
 <intercept-url pattern="/**" access="hasAnyRole('ROLE_USER','ROLE_TEST','ROLE_ADMIN','ROLE_GUEST')" />
 <form-login login-page="/user/loginPage"
  login-processing-url="/user/login"
  authentication-success-handler-ref="userLoginSuccessHandler"
  authentication-failure-handler-ref="userLoginFailureHandler"
  username-parameter="email" password-parameter="passwd" />
 <session-management>
  <concurrency-control max-sessions="1" expired-url="/user/loginPage" error-if-maximum-exceeded="true"/>
 </session-management>
 <logout delete-cookies="true" logout-success-url="/user/loginPage" logout-url="/user/logout" invalidate-session="true"/>
 <access-denied-handler ref="userDeniedHandler"/>
</http>

<beans:bean id="userDeniedHandler"
  class="com.min.study.user.service.UserDeniedHandler"></beans:bean>
  • 이동할 jsp생성 (views/user/denied.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" %>

<link rel="stylesheet" type="text/css" href="&lt;c:url value=" resources="" css="" main.css"="">"&gt;
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>

${errMsg }
${auth }
  • 권한 없는 페이지 접속 하여 확인

AccessDeniedHandler 를 직​접 구현 하게 되면 파라메터로 AccessDeniedException이 직접 넘어오기 때문에 알아서 잘 구현하면 된다.


소스 확인 : ​https://github.com/ParkMinKyu/security