스프링 보안의 프로그래밍 방식 사용
-
06-07-2019 - |
문제
나는 사용 중입니다 창구 프레젠테이션 계층의 개찰구 인증 프로젝트를 통해 스프링 보안과 통합했습니다. 이것은 나를 위해 인증을 위해 개찰구에 의해 호출되는 방법입니다.
@Override
public boolean authenticate(String username, String password) {
try {
Authentication request = new UsernamePasswordAuthenticationToken(
username, password);
Authentication result = authenticationManager.authenticate(request);
SecurityContextHolder.getContext().setAuthentication(result);
} catch (AuthenticationException e) {
return false;
}
return true;
}
스프링 보안 XML 구성의 내용 (내부)은 다음과 같습니다.
<http path-type="regex">
<form-login login-page="/signin"/>
<logout logout-url="/logout" />
</http>
<global-method-security secured-annotations="enabled" />
<authentication-manager alias="authenticationManager"/>
<authentication-provider user-service-ref="userService">
<password-encoder ref="bcryptpasswordencoder" />
</authentication-provider>
그 영역 2.3.6. 세션 고정 공격 보호 참조 문서의 다음과 같이 말합니다.
세션 고정 공격은 악의적 인 공격자가 사이트에 액세스하여 세션을 만들 수있는 잠재적 위험입니다. 그런 다음 다른 사용자가 같은 세션으로 로그인하도록 설득합니다 (세션 식별자가 매개 변수로 포함 된 링크를 보내십시오. 예시). 스프링 보안은 사용자가 로그인 할 때 새 세션을 만들어 자동으로 이로부터 보호합니다.이 보호가 필요하지 않거나 다른 요구 사항과 충돌하는 경우 세션 고정 보호 속성을 사용하여 동작을 제어 할 수 있습니다. 세 가지 옵션이 있습니다.
- Migratesession- 새 세션을 생성하고 기존 세션 속성을 새 세션에 복사합니다. 이것은 기본값입니다.
- 없음 - 아무것도하지 않습니다. 원래 세션은 유지됩니다.
- 뉴스 - 기존 세션 데이터를 복사하지 않고 새 "깨끗한"세션을 만듭니다.
인증은 효과가 있지만 스프링 보안을 처음 접하는 데 도움이되는 몇 가지 질문이 있습니다.
- 일반적으로 로그인하려면 인증 정보를 다음과 같이 게시합니다.
j_spring_security_check
Spring Security가 실제 인증 코드를 수행하도록하십시오. 세션 고정 공격에 대한 보호를 받고 싶습니다. 프로그램처럼 프로그래밍 방식 로그인을 수행 할 때 얻을 수 있습니까? 그렇지 않다면, 그것을 얻기 위해 무엇을해야합니까? - 프로그래밍 방식 로그 아웃을 어떻게 수행합니까?
- 프로그래밍 방식 로그인 및 로그 아웃을 사용하므로 해당 URL을 가로 채지 못하면 스프링을 어떻게 비활성화합니까?
업데이트:세션 고정 공격 보호를 위해서는 서명과 함께 세션 우틸 클래스의 메소드를 호출 해야하는 것 같습니다. startNewSessionIfRequired(HttpServletRequest request, boolean migrateAttributes, SessionRegistry sessionRegistry)
.
전달 해야하는 SessionRegistry 인스턴스를 어떻게 얻습니까? 별명 ID를 만들 수있는 방법이나 ID 또는 이름을 얻는 방법을 찾을 수 없습니다.
해결책
어쩌면 그것은 당신의 질문에 대한 완전한 답이 아니지만 도움이 될 수도 있습니다.
프로그래밍 방식 로그인을 사용하지 않을 때 호출되는 코드는 여기에서 찾을 수 있습니다.
org.springframework.security.ui.webapp.AuthenticationProcessingFilter
나는 당신이 당신의 코드에서 이것에 영감을 받았다고 생각합니다. 꽤 비슷해 보입니다.
마찬가지로 액세스 할 때 실행 된 코드가 실행되었습니다 /j_spring_security_logout
표준 접근법에서는 여기에서 찾을 수 있습니다.
org.springframework.security.ui.logout.LogoutFilter
로그 아웃 필터는 여러 처리기를 호출합니다. 우리가 사용하는 핸들러는 다음과 같습니다.org.springframework.security.ui.logout.SecurityContextLogoutHandler
, 따라서 접근 방식에서 동일한 코드를 호출 할 수 있습니다.
다른 팁
당신은 실제로 세션 고정 공격에 열려있을 것입니다. 이것을 해결하기 위해 스프링 코드에서 다시 "영감을 줄 수 있습니다. 새 세션을 만들려면 분명히 httpsession에 액세스해야하므로 리팩토링을 수행해야 할 수도 있습니다.
방법이 보이면 SessionUtils
.startNewSessionIfRequired
.
이렇게하면 인증이 새 세션으로 마이그레이션됩니다. 이 메소드를 직접 호출하거나 코드를 조금 리팩터링 할 수 있습니다.
프로그래밍 방식 로그 아웃은 단순히 전화해서 너무 잘못 갈 수 없습니다. session.invalidate()
사람을 로그 아웃해야 할 때. 이것은 일반적인 보안 관점에서 필요한 모든 것을 수행하지만 세션에서 몇 가지를 정리해야 할 수도 있지만 명심해야합니다. 필터가 매우 복잡한 세트가있는 경우 사용자가 나머지 요청에 대해 로그 아웃하는지 확인 해야하는 경우 다음을 추가 할 수 있습니다.
SecurityContextHolder.getContext().setAuthentication(null);
URL의 가로 채기에 관해서는 URL을 사용하지 않은 것으로 설정하고 무시할 수 있습니다! 구성에서 가로 채기를 해제 할 수 있는지 확실하지 않습니다. 실제로 제거하려면 AuthenticationProcessingFilter
- 당신은 이것을 사용자 정의 할 수 있습니다. 이 작업을 수행하면 Spring Security XML을 수동으로 설정하고 제공된 네임 스페이스를 사용하지 않아야합니다. 그래도 너무 어렵지는 않습니다. 오래된 문서를 살펴보면이 작업을 수행하는 방법을 볼 수 있습니다.
도움이 되었기를 바랍니다!
1) 프로그래밍 방식 로그 아웃
- httpservletrequest.getSession (false) .invalidate를 호출하십시오
- Call SecurityContexTholder.clearContext ()
2) Spring Security에 특정 URL을 가로 채지 말라고 말하면,이 종류의 종류는 응용 프로그램 URL 공간 설정 방법에 따라 다릅니다. 모든 페이지 ( /로그인 및 /로그 아웃 제외)가 Context /MyApp에 살았을 때 다음을 수행 할 수 있습니다.
<http ....>
<intercept-url pattern="/myApp/**" ..>
....
</http>
프로그래밍 방식 로그인에 문제가있었습니다. 나는 모든 것을 불렀다 authenticationManager.authenticate(...)
그리고 SecurityContextHolder.getContext().setAuthentication(...)
방법은 세션에 문제가있었습니다. 세션을 올바르게 관리하기 위해 다음 줄을 추가해야했습니다.
HttpSession session = request.getSession();
session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext());
위에 게시 된 예제 코드에서 명확하지 않았습니다. 자세한 내용은 http://forum.springsource.org/showthread.php?t=69761
프로그래밍 방식 로그 아웃을하려면 org.springframework.security.core.AuthenticationException
. 예를 들어, SessionAuthenticationException
. 이 경우 ExceptionTranslationFilter
로그 아웃을 시작하십시오.
당신은 이것을 시도 할 수 있습니다
try {
HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate();
}
SecurityContextHolder.clearContext();
} catch (Exception e) {
logger.log(LogLevel.INFO, "Problem logging out.");
}