Spring Security 관련 문의
- 작성자 :
- 박*은
- 작성일 :
- 2012-05-21 10:35:20
- 조회수 :
- 2,364
- 구분 :
- 실행환경
- 진행상태 :
- 완료
Q
GPKI 로그인 인증 후, Spring Security 를 호출하는 부분에 대해 문의를 드립니다.
현재, 전자정부 프레임워크(1.0)를 적용하여 운영중에 있습니다.
인증관련 부분에서 보안성 문제가 발생했습니다.
GPKI 로그인 후에,
return "redirect:/j_spring_security_check?j_username=" + resultVO.getUserSe() + resultVO.getId() + "&j_password=" + resultVO.getUniqId();
를 호출하고 있습니다.
GPKI 인증후에 spring security를 호출하다 보니,
보안에 취약한 거 같습니다. 현재는 GET 방식으로 호출하는데,
브라우져의 History 에 정보가 남습니다. 그러다 보니, 다른 사람이 그 히스토리를 통해서 접근이 가능합니다. 매번 움직일때마다 브라우져 접근 정보를 삭제하기도 애매합니다.
또한 POST 방식으로 바뀐다해도 해킹에 안전하지는 않으리라고 생각됩니다.
질문 요지는,
1. GPKI 인증후에, Spring Security 부분에 대한 보안 강화(정보 누출 방지)를 하는 방법 => id/pwd 를 누출하지 않아야 함
2. Spring Security 가 보안에 취약하다면 제거하는 방법
=> 전자정부 프레임워크에 종속적이어서 다양하게 연결되어 있음.
어떤 식으로 보안을 강화해야 하는지에 대한 답변 부탁드립니다.
현재, 전자정부 프레임워크(1.0)를 적용하여 운영중에 있습니다.
인증관련 부분에서 보안성 문제가 발생했습니다.
GPKI 로그인 후에,
return "redirect:/j_spring_security_check?j_username=" + resultVO.getUserSe() + resultVO.getId() + "&j_password=" + resultVO.getUniqId();
를 호출하고 있습니다.
GPKI 인증후에 spring security를 호출하다 보니,
보안에 취약한 거 같습니다. 현재는 GET 방식으로 호출하는데,
브라우져의 History 에 정보가 남습니다. 그러다 보니, 다른 사람이 그 히스토리를 통해서 접근이 가능합니다. 매번 움직일때마다 브라우져 접근 정보를 삭제하기도 애매합니다.
또한 POST 방식으로 바뀐다해도 해킹에 안전하지는 않으리라고 생각됩니다.
질문 요지는,
1. GPKI 인증후에, Spring Security 부분에 대한 보안 강화(정보 누출 방지)를 하는 방법 => id/pwd 를 누출하지 않아야 함
2. Spring Security 가 보안에 취약하다면 제거하는 방법
=> 전자정부 프레임워크에 종속적이어서 다양하게 연결되어 있음.
어떤 식으로 보안을 강화해야 하는지에 대한 답변 부탁드립니다.
A
안녕하세요.. 박노은님...
서버 사이드 처리인 forward가 적용이 되면.. 클라이언트 상에 URL 정보가 남지 않기 때문에.. 문제가 되지 않습니다.
그러나 이 경우 filter 방식에 의한 spring security가 호출되지 않기 때문에.. 다음과 같이 redirect가 아닌 spring security의 filter를 직접 호출하는 방식으로 변경하셔야 합니다..
1. 기존 메소드에 파라미터 HttpServletRequest (request) 및 HttpServletResponse (response) 추가 또는 확인
2. RequestWrapperForSecurity class 정의 (public이 아니기 때문에.. 기존 EgovLoginController 아래에 추가하시면 됩니다.)
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);
}
}
3. 다음과 같이 redirect 호출 부분 변경
// 2. spring security 연동
//return "redirect:/j_spring_security_check?j_username=" + resultVO.getUserSe() + resultVO.getId() + "&j_password=" + resultVO.getUniqId();
AuthenticationProcessingFilter springSecurity = null;
ApplicationContext act = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getSession().getServletContext());
@SuppressWarnings("rawtypes")
Map beans = act.getBeansOfType(AuthenticationProcessingFilter.class);
if (beans.size() > 0) {
springSecurity = (AuthenticationProcessingFilter)beans.values().toArray()[0];
} else {
LOG.error("No AuthenticationProcessingFilter");
throw new IllegalStateException("No AuthenticationProcessingFilter");
}
LOG.debug("before security filter call....");
springSecurity.doFilter(
new RequestWrapperForSecurity(request, loginVO.getUserSe() + loginVO.getId(), loginVO.getUniqId()),
response, null);
LOG.debug("after security filter call....");
return "";
그럼.. 즐거운 하루되십시오.
감사합니다.
서버 사이드 처리인 forward가 적용이 되면.. 클라이언트 상에 URL 정보가 남지 않기 때문에.. 문제가 되지 않습니다.
그러나 이 경우 filter 방식에 의한 spring security가 호출되지 않기 때문에.. 다음과 같이 redirect가 아닌 spring security의 filter를 직접 호출하는 방식으로 변경하셔야 합니다..
1. 기존 메소드에 파라미터 HttpServletRequest (request) 및 HttpServletResponse (response) 추가 또는 확인
2. RequestWrapperForSecurity class 정의 (public이 아니기 때문에.. 기존 EgovLoginController 아래에 추가하시면 됩니다.)
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);
}
}
3. 다음과 같이 redirect 호출 부분 변경
// 2. spring security 연동
//return "redirect:/j_spring_security_check?j_username=" + resultVO.getUserSe() + resultVO.getId() + "&j_password=" + resultVO.getUniqId();
AuthenticationProcessingFilter springSecurity = null;
ApplicationContext act = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getSession().getServletContext());
@SuppressWarnings("rawtypes")
Map beans = act.getBeansOfType(AuthenticationProcessingFilter.class);
if (beans.size() > 0) {
springSecurity = (AuthenticationProcessingFilter)beans.values().toArray()[0];
} else {
LOG.error("No AuthenticationProcessingFilter");
throw new IllegalStateException("No AuthenticationProcessingFilter");
}
LOG.debug("before security filter call....");
springSecurity.doFilter(
new RequestWrapperForSecurity(request, loginVO.getUserSe() + loginVO.getId(), loginVO.getUniqId()),
response, null);
LOG.debug("after security filter call....");
return "";
그럼.. 즐거운 하루되십시오.
감사합니다.