Spring session 存储在 DB + Spring 安全认证,集群环境
Spring session stored over DB + Spring security authentication, clustered enviroment
我有一个超过 spring 4 的应用程序,具有 spring 身份验证安全性和 spring 会话以在集群环境中共享会话。
我从 Spring Session 中实现了 sessionRepository 以将会话存储在数据库中,所以当我进入站点 spring session 时创建一个名为 "SESSION" 的 cookie 并将其存储在数据库上。
这个会话数据库实现的想法在这里:
此刻我有一个饼干"SESSION"。
当我登录站点 spring 时,安全性会创建另一个 cookie "JSESSION" 但这并没有存储在数据库中,并且这个 cookie 具有 "authentication info".
我的问题是:这个实现对于集群环境是否正确?或者我需要再做一次修改?
提前致谢。
编辑 2:
我最近测试了我的应用程序,我在解释时犯了一个错误,当我进入网站时我有一个 cookie "SESSION" 即使我登录了 "SESSION" cookie 剧照,但是那里不是另一个 cookie,如果我清理会话 table 并刷新用户注销的站点。这是正确的行为吗?
编辑:
这是我来自 SecurityConfig 的 "configure"(从 WebSecurityConfigurerAdapter 扩展)。
@Override
protected void configure(final HttpSecurity http) throws Exception {
// @formatter:off
http
//.csrf().disable()
.authorizeRequests()
.antMatchers(
"/login*",
"/logout*",
"/forgotPassword*",
"/user/initResetPassword*",
"/user/resetPassword*",
"/admin/saveConfiguration",
"/resources/**"
).permitAll()
.antMatchers("/invalidSession*").anonymous()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/login")
.defaultSuccessUrl("/homepage.html")
.failureUrl("/login.html?error=true")
.successHandler(myAuthenticationSuccessHandler)
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.addFilterBefore(this.sessionSessionRepositoryFilter, ChannelProcessingFilter.class)
.sessionManagement()
.invalidSessionUrl("/login.html")
.sessionFixation()
.migrateSession()
.and()
.logout()
.invalidateHttpSession(false)
.logoutUrl("/vu_logout")
.logoutSuccessUrl("/logout.html?ls=true")
.deleteCookies("JSESSION")
.logoutSuccessHandler(mySimpleUrlLogoutSuccessHandler)
.permitAll();
// @formatter:on
}
这是我的登录成功处理程序:
@Component("myAuthenticationSuccessHandler")
public class MySimpleUrlAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
private final Logger LOGGER = LoggerFactory.getLogger(getClass());
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
handle(request, response, authentication);
HttpSession session = request.getSession(false);
if (session != null) {
session.setMaxInactiveInterval(60 * 10);
}
clearAuthenticationAttributes(request);
}
protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
String targetUrl = determineTargetUrl(authentication);
if (response.isCommitted()) {
return;
}
redirectStrategy.sendRedirect(request, response, targetUrl);
}
protected String determineTargetUrl(Authentication authentication) {
boolean isUser = false;
boolean isAdmin = false;
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
for (GrantedAuthority grantedAuthority : authorities) {
if (grantedAuthority.getAuthority().equals("OPER") || grantedAuthority.getAuthority().equals("AUDITOR")) {
isUser = true;
} else if (grantedAuthority.getAuthority().equals("ADMIN")) {
isAdmin = true;
isUser = false;
break;
}
}
if(isUser || isAdmin)
{
return "/home.html";
}
else
{
throw new IllegalStateException();
}
}
protected void clearAuthenticationAttributes(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session == null) {
return;
}
session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
}
public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
this.redirectStrategy = redirectStrategy;
}
protected RedirectStrategy getRedirectStrategy() {
return redirectStrategy;
}
}
经过几天的研究和测试,此实现在集群环境中运行是正确的。
如果有人需要示例项目,Mati 在您的 github 存储库中有一个:
https://github.com/Mati20041/spring-session-jpa-repository
我有一个超过 spring 4 的应用程序,具有 spring 身份验证安全性和 spring 会话以在集群环境中共享会话。
我从 Spring Session 中实现了 sessionRepository 以将会话存储在数据库中,所以当我进入站点 spring session 时创建一个名为 "SESSION" 的 cookie 并将其存储在数据库上。
这个会话数据库实现的想法在这里:
此刻我有一个饼干"SESSION"。 当我登录站点 spring 时,安全性会创建另一个 cookie "JSESSION" 但这并没有存储在数据库中,并且这个 cookie 具有 "authentication info".
我的问题是:这个实现对于集群环境是否正确?或者我需要再做一次修改?
提前致谢。
编辑 2:
我最近测试了我的应用程序,我在解释时犯了一个错误,当我进入网站时我有一个 cookie "SESSION" 即使我登录了 "SESSION" cookie 剧照,但是那里不是另一个 cookie,如果我清理会话 table 并刷新用户注销的站点。这是正确的行为吗?
编辑:
这是我来自 SecurityConfig 的 "configure"(从 WebSecurityConfigurerAdapter 扩展)。
@Override
protected void configure(final HttpSecurity http) throws Exception {
// @formatter:off
http
//.csrf().disable()
.authorizeRequests()
.antMatchers(
"/login*",
"/logout*",
"/forgotPassword*",
"/user/initResetPassword*",
"/user/resetPassword*",
"/admin/saveConfiguration",
"/resources/**"
).permitAll()
.antMatchers("/invalidSession*").anonymous()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/login")
.defaultSuccessUrl("/homepage.html")
.failureUrl("/login.html?error=true")
.successHandler(myAuthenticationSuccessHandler)
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.addFilterBefore(this.sessionSessionRepositoryFilter, ChannelProcessingFilter.class)
.sessionManagement()
.invalidSessionUrl("/login.html")
.sessionFixation()
.migrateSession()
.and()
.logout()
.invalidateHttpSession(false)
.logoutUrl("/vu_logout")
.logoutSuccessUrl("/logout.html?ls=true")
.deleteCookies("JSESSION")
.logoutSuccessHandler(mySimpleUrlLogoutSuccessHandler)
.permitAll();
// @formatter:on
}
这是我的登录成功处理程序:
@Component("myAuthenticationSuccessHandler")
public class MySimpleUrlAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
private final Logger LOGGER = LoggerFactory.getLogger(getClass());
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
handle(request, response, authentication);
HttpSession session = request.getSession(false);
if (session != null) {
session.setMaxInactiveInterval(60 * 10);
}
clearAuthenticationAttributes(request);
}
protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
String targetUrl = determineTargetUrl(authentication);
if (response.isCommitted()) {
return;
}
redirectStrategy.sendRedirect(request, response, targetUrl);
}
protected String determineTargetUrl(Authentication authentication) {
boolean isUser = false;
boolean isAdmin = false;
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
for (GrantedAuthority grantedAuthority : authorities) {
if (grantedAuthority.getAuthority().equals("OPER") || grantedAuthority.getAuthority().equals("AUDITOR")) {
isUser = true;
} else if (grantedAuthority.getAuthority().equals("ADMIN")) {
isAdmin = true;
isUser = false;
break;
}
}
if(isUser || isAdmin)
{
return "/home.html";
}
else
{
throw new IllegalStateException();
}
}
protected void clearAuthenticationAttributes(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session == null) {
return;
}
session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
}
public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
this.redirectStrategy = redirectStrategy;
}
protected RedirectStrategy getRedirectStrategy() {
return redirectStrategy;
}
}
经过几天的研究和测试,此实现在集群环境中运行是正确的。
如果有人需要示例项目,Mati 在您的 github 存储库中有一个: https://github.com/Mati20041/spring-session-jpa-repository