이전 포스팅에서 사용자가 정의한 로그인 페이지로 로그인 하는 방법을 익혔으니 이번에는
spring security에서 인증절차를 거친 후 커스텀 프로세서를 통해 인증된 사용자를 관리하는 방법과 spring security에서 css와js파일등 인증이 필요없는 리소스 파일들을 security필터를 거치지 않게하는 방법도 알아보겠다.
1.우선 STS에서 생성한 Spring MVC프로젝트의 폴더구조를 보면 아래와 같다.
webapp - resources 폴더가 웹의 정적리소스 파일들 (이미지,css,js등)을 포함시키는 폴더이다.
그래서 프로젝트 생성시 만들어진 spring 기본설정 appServlet폴더의 servlet-context.xml을 보면
<resources mapping="/resources/**" location="/resources/" /> 라고 resources로 들어오는 요청은 스프링에서 관리하지 않겠다는 선언을 한다. security에서도 이처럼 resources요청에 대해 처리하지 않겠다는 선언을 해야하는데 security-context.xml에 아래부분을 추가해주면 된다.
<http pattern="/resources/**" security="none"></http>
아니면 기존의 http설정에 <intercept-url pattern="/resources/**" access="permitAll" /> 를 추가해 모든 사용자의 접근이 가능하게 하면 된다.
2-1.security에서 인증 성공 or 인증 실패 후 프로세스 처리
security에서 인증 성공 후 지정한 페이지로 이동하기 전에 사용자에 관해 처리할 일이 있을경우가 있는데 인증 성공 후 처리를 위한 클레스에는 AuthenticationSuccessHandler 인터페이스 를 상속받고
인증 실패 후 처리는 AuthenticationFailureHandler 인터페이스를 상속받아 구현하면 된다.
ex)인증 성공 후 프로세스
public class UserLoginSuccessHandler implements AuthenticationSuccessHandler{ private static final Logger logger = LoggerFactory.getLogger(UserLoginSuccessHandler.class); @Override public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse res, Authentication auth) throws IOException, ServletException { // TODO Auto-generated method stub logger.info(auth.getName()); logger.info(auth.getAuthorities().toString()); logger.info(auth.getDetails().toString()); logger.info(auth.getPrincipal().toString()); for(GrantedAuthority a : auth.getAuthorities()){ logger.info(a.getAuthority()); } UserDetails u = (UserDetails) auth.getPrincipal(); logger.info(String.valueOf(u.isAccountNonExpired())); logger.info(String.valueOf(u.isAccountNonLocked())); logger.info(String.valueOf(u.isCredentialsNonExpired())); logger.info(String.valueOf(u.isEnabled())); res.sendRedirect(req.getContextPath()+"/"); } }
ex)인증 실패 후 프로세스
public class UserLoginFailureHandler implements AuthenticationFailureHandler{ private static final Logger logger = LoggerFactory.getLogger(UserLoginFailureHandler.class); @Override public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse res, AuthenticationException auth) throws IOException, ServletException { // TODO Auto-generated method stub logger.info(auth.getLocalizedMessage()); logger.info(auth.getMessage()); for(StackTraceElement s : auth.getStackTrace()){ logger.info(s.getClassName()); logger.info(s.getFileName()); logger.info(s.getMethodName()); logger.info(s.getLineNumber()+""); logger.info(s.isNativeMethod()+""); } req.setAttribute("errMsg",auth.getMessage()); req.getRequestDispatcher("/WEB-INF/views/user/loginPage.jsp").forward(req, res); } }
2-2. security-context.xml의 <http><form-login>에 인증 속성 추가
authentication-success-handler-ref="userLoginSuccessHandler" authentication-failure-handler-ref="userLoginFailureHandler"
속성 값을 지정하면 된다.
authentication-success-handler-ref 는 인증 성공 후 이루어지는 프로세스
authentication-failure-handler-ref 는 인증 실패 후 이루어지는 프로세스 이다.
authentication-failure-url="/user/loginPage" 를 지정하여 인증 실패 후 이동할 페이지를 지정 할 수도있다.
2-3. security-context.xml에 bean정의
<beans:bean id="userLoginSuccessHandler" class="com.min.study.user.service.UserLoginSuccessHandler"></beans:bean> <beans:bean id="userLoginFailureHandler" class="com.min.study.user.service.UserLoginFailureHandler"></beans:bean>
이러한 인증프로세스를 직접 처리하게 되면 기존에 지정한 authentication-failure-url이나 default-target-url 등의 속성은 무시되며 인증 프로세스에서 직접 이동할 페이지를 지정해야 한다.
소스 확인 : https://github.com/ParkMinKyu/security