====== 업그레이드 ======
===== 개요 =====
표준프레임워크 3.0(Spring Security 3.2.3)에서 3.7(Spring Security 4.0.3)로 업그레이드 Server security의 경우 설정 변경뿐만 아니라 소스 상의 변경 작업이 필요하다.
===== 주요 변경내용 (Spring Security 부분) =====
==== dependencies 및 패키지 변경 ====
* spring-security-core (org.springframework.security.core, org.springframework.security.access, etc.)
* spring-security-web (org.springframework.security.web)
* spring-security-config (org.springframework.security.config)
==== API 변경 ====
* MethodSecurityInterceptor 설정 방식 변경
* accessDecisionManager 설정 방식 변경
* ConcurrentSessionFilter 선언 방식 변경
==== 기타 ====
* sniff 설정 지원
* xss protection 설정 지원
* csrf 설정 지원
* hasRole prefix 설정 지원
* 등등
===== 실행환경 부분 업그레이드 절차 =====
==== 1. dependency 수정 ====
egovframework.rte
egovframework.rte.fdl.security
4.0.3
* 적용 버전은 최신 버전 확인 후 적용(patch 버전 등)
==== 3. Spring Security 설정 수정 ====
다음 설정을 참조하여 관련 설정을 변경한다. \\
보안 옵션 추가(sniff, xframeOptions, xssProtection, csrf)
==== 4. LoginFilter 변경 ====
spring security 로그인 필터 처리시 경로 및 파리미터 적용 \\
* 기존 :
Map beans = act.getBeansOfType(UsernamePasswordAuthenticationFilter.class);
if (beans.size() > 0) {
springSecurity = (UsernamePasswordAuthenticationFilter) beans.values().toArray()[0];
} else {
LOGGER.error("No AuthenticationProcessingFilter");
throw new IllegalStateException("No AuthenticationProcessingFilter");
}
...
class RequestWrapperForSecurity extends HttpServletRequestWrapper {
private String username = null;
private String password = null;
public RequestWrapperForSecurity(HttpServletRequest request, String username, String password) {
super(request);
this.username = username;
this.password = password;
}
@Override
public String getRequestURI() {
return ((HttpServletRequest) super.getRequest()).getContextPath() + "/j_spring_security_check";
}
@Override
public String getParameter(String name) {
if (name.equals("j_username")) {
return username;
}
if (name.equals("j_password")) {
return password;
}
return super.getParameter(name);
}
}
* 변경 :
Map beans = act.getBeansOfType(UsernamePasswordAuthenticationFilter.class);
if (beans.size() > 0) {
springSecurity = (UsernamePasswordAuthenticationFilter) beans.values().toArray()[0];
springSecurity.setUsernameParameter("egov_security_username");
springSecurity.setPasswordParameter("egov_security_password");
springSecurity.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher(request.getServletContext().getContextPath() +"/egov_security_login", "POST"));
} else {
LOGGER.error("No AuthenticationProcessingFilter");
throw new IllegalStateException("No AuthenticationProcessingFilter");
}
...
class RequestWrapperForSecurity extends HttpServletRequestWrapper {
private String username = null;
private String password = null;
public RequestWrapperForSecurity(HttpServletRequest request, String username, String password) {
super(request);
this.username = username;
this.password = password;
}
@Override
public String getServletPath() {
return ((HttpServletRequest) super.getRequest()).getContextPath() + "/egov_security_login";
}
@Override
public String getRequestURI() {
return ((HttpServletRequest) super.getRequest()).getContextPath() + "/egov_security_login";
}
@Override
public String getParameter(String name) {
if (name.equals("egov_security_username")) {
return username;
}
if (name.equals("egov_security_password")) {
return password;
}
return super.getParameter(name);
}
}
==== 5. LogoutFilter 변경 ====
spring security 로그아웃 필터 처리시 egov_security_logout 적용 \\
* 기존 :
((HttpServletResponse)response).sendRedirect(((HttpServletRequest)request).getContextPath() + "/j_spring_security_logout");
\\
* 변경 :
((HttpServletResponse)response).sendRedirect(((HttpServletRequest)request).getContextPath() + "/egov_security_logout");