Spring 引导过期 URL 不工作
Spring boot expiredURL not working
我有 "Vaadin 10 with Spring Boot" 申请。我想允许用户一次从一个地方访问应用程序。所以我使用了 maximumSessions(1)。例如,在 Chrome 浏览器中,我使用用户 "XYZ" 登录。现在使用相同的用户(即 "XYZ"),我尝试登录 Opera 浏览器。因此,按照下面显示的配置,它将使 Chrome 浏览器的会话过期,但不会重定向到“/login”。它显示消息 "Invalid JSON response from Server"。以下是 Spring 安全配置:
@Override
protected void configure(HttpSecurity http) throws Exception {
// Not using Spring CSRF here to be able to use plain HTML for the login page
http.csrf().disable()
// Register our CustomRequestCache, that saves unauthorized access attempts, so
// the user is redirected after login.
.requestCache().requestCache(new CustomRequestCache())
// Restrict access to our application.
.and().authorizeRequests()
.antMatchers("/ForgetPassword","/ChangePassword","/login").permitAll()
// Allow all flow internal requests.
.requestMatchers(SecurityUtils::isFrameworkInternalRequest).permitAll()
// Allow all requests by logged in users.
.anyRequest().authenticated()
// Configure the login page.
.and().formLogin().loginPage("/login").permitAll().loginProcessingUrl("/login")
.failureUrl("/login?error")
// Register the success handler that redirects users to the page they last tried
// to access
.successHandler(new SavedRequestAwareAuthenticationSuccessHandler())
// Configure logout
.and().logout().logoutSuccessUrl(LOGOUT_SUCCESS_URL)
.deleteCookies("JSESSIONID")
//.invalidateHttpSession(true)
.and()
.sessionManagement()
//.invalidSessionUrl("/login")
.maximumSessions(1)
//.maxSessionsPreventsLogin(false)
.sessionRegistry(sessionRegistry())
.expiredUrl("/login");
问题在于,通过重定向请求,Vaadin 接收登录页面作为对内部请求的响应。
这似乎有效:
.expiredSessionStrategy(e -> {
final String redirectUrl = e.getRequest().getContextPath() + "/login";
if(SecurityUtils.isFrameworkInternalRequest(e.getRequest())) {
e.getResponse().setHeader("Content-Type", "text/plain");
e.getResponse().getWriter().write("Vaadin-Refresh: " + redirectUrl);
} else {
e.getResponse().sendRedirect(redirectUrl);
}
});
它记录在
ConnectionStateHandler
public interface ConnectionStateHandler {
/**
* A string that, if found in a non-JSON response to a UIDL request, will
* cause the browser to refresh the page. If followed by a colon, optional
* whitespace, and a URI, causes the browser to synchronously load the URI.
*
* <p>
* This allows, for instance, a servlet filter to redirect the application
* to a custom login page when the session expires. For example:
* </p>
*
* <pre>
* if (sessionExpired) {
* response.setHeader("Content-Type", "text/html");
* response.getWriter().write(myLoginPageHtml + "<!-- Vaadin-Refresh: "
* + request.getContextPath() + " -->");
* }
* </pre>
*/
String UIDL_REFRESH_TOKEN = "Vaadin-Refresh";
我有 "Vaadin 10 with Spring Boot" 申请。我想允许用户一次从一个地方访问应用程序。所以我使用了 maximumSessions(1)。例如,在 Chrome 浏览器中,我使用用户 "XYZ" 登录。现在使用相同的用户(即 "XYZ"),我尝试登录 Opera 浏览器。因此,按照下面显示的配置,它将使 Chrome 浏览器的会话过期,但不会重定向到“/login”。它显示消息 "Invalid JSON response from Server"。以下是 Spring 安全配置:
@Override
protected void configure(HttpSecurity http) throws Exception {
// Not using Spring CSRF here to be able to use plain HTML for the login page
http.csrf().disable()
// Register our CustomRequestCache, that saves unauthorized access attempts, so
// the user is redirected after login.
.requestCache().requestCache(new CustomRequestCache())
// Restrict access to our application.
.and().authorizeRequests()
.antMatchers("/ForgetPassword","/ChangePassword","/login").permitAll()
// Allow all flow internal requests.
.requestMatchers(SecurityUtils::isFrameworkInternalRequest).permitAll()
// Allow all requests by logged in users.
.anyRequest().authenticated()
// Configure the login page.
.and().formLogin().loginPage("/login").permitAll().loginProcessingUrl("/login")
.failureUrl("/login?error")
// Register the success handler that redirects users to the page they last tried
// to access
.successHandler(new SavedRequestAwareAuthenticationSuccessHandler())
// Configure logout
.and().logout().logoutSuccessUrl(LOGOUT_SUCCESS_URL)
.deleteCookies("JSESSIONID")
//.invalidateHttpSession(true)
.and()
.sessionManagement()
//.invalidSessionUrl("/login")
.maximumSessions(1)
//.maxSessionsPreventsLogin(false)
.sessionRegistry(sessionRegistry())
.expiredUrl("/login");
问题在于,通过重定向请求,Vaadin 接收登录页面作为对内部请求的响应。
这似乎有效:
.expiredSessionStrategy(e -> {
final String redirectUrl = e.getRequest().getContextPath() + "/login";
if(SecurityUtils.isFrameworkInternalRequest(e.getRequest())) {
e.getResponse().setHeader("Content-Type", "text/plain");
e.getResponse().getWriter().write("Vaadin-Refresh: " + redirectUrl);
} else {
e.getResponse().sendRedirect(redirectUrl);
}
});
它记录在 ConnectionStateHandler
public interface ConnectionStateHandler {
/**
* A string that, if found in a non-JSON response to a UIDL request, will
* cause the browser to refresh the page. If followed by a colon, optional
* whitespace, and a URI, causes the browser to synchronously load the URI.
*
* <p>
* This allows, for instance, a servlet filter to redirect the application
* to a custom login page when the session expires. For example:
* </p>
*
* <pre>
* if (sessionExpired) {
* response.setHeader("Content-Type", "text/html");
* response.getWriter().write(myLoginPageHtml + "<!-- Vaadin-Refresh: "
* + request.getContextPath() + " -->");
* }
* </pre>
*/
String UIDL_REFRESH_TOKEN = "Vaadin-Refresh";