我使用默认的Spring Security来处理注销/登录。我有一个处理/login
的Controller方法。
当我注销时,我看到Spring Security将我重定向到app/login? logout
。这个Spring创建的参数的存在(有时也app/login? error
)允许我将我的登录处理程序编写为:
@GetMapping("/participant/login")
public ModelAndView loginPage(HttpServletRequest request, HttpServletResponse response,
@RequestParam(value = "error", required = false) String error,
@RequestParam(value = "logout", required = false) String logout) {
log.info("Entering participant login page");
ModelAndView mav = new ModelAndView(LOGIN_JSP);
if (null != error) {
// We're coming to the login page after an Error
mav.addObject("info", "My generic error message");
} else if(null != logout){
// We're coming to the login page after a Logout
mav.addObject("info", "My generic logout message");
}
// ...Otherwise, normal Login page, no extra information
现在的问题是,当我注销时,我需要传递一个自定义参数 /logout转移到 /login.目标是我需要在/login
中接收一个参数,我可以检查就像系统创建的error
和logout
一样。
假设这个自定义参数是exitMsg
。
从我的应用程序中,我发出这个Spring Security Logout URL(注销是自动的,所以我没有特定的处理程序):
myapp。com/app/logout?exitsg=MyMessage
马上,登录处理程序就会丢失这个参数,而我没有它。
我考虑编写自己的/logout
处理程序,在其中我手动注销(使会话无效),然后使用此参数重定向到Login本人。这是这里的建议。但如果我这样做,我将失去获取Spring的自动? logout
和? error
请求参数的能力。在自动场景中,我正在获取它们,现在我没有。我只获取我自己指定的自定义参数。我需要保留? logout
和? error
,并且还测试我自己的新参数。
任何想法高度赞赏。
Spring Security配置:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/participant/**").authorizeRequests()
.antMatchers("/participant/id/**").permitAll()
.antMatchers("/participant/faq").permitAll()
.antMatchers("/participant/forgetPassword").permitAll()
.antMatchers("/participant/securityQuestions").permitAll()
.antMatchers("/participant/securityCheck").permitAll()
.antMatchers("/participant/resetPassword").permitAll()
.antMatchers("/participant/**").authenticated()
.and()
.formLogin().loginPage("/participant/login").permitAll()
.failureUrl("/participant/login?error").permitAll()
.defaultSuccessUrl("/participant/home")
.usernameParameter("username").passwordParameter("password")
.and()
.logout().logoutUrl("/participant/logout")
.logoutSuccessUrl("/participant/login?logout").permitAll()
.and()
.csrf().disable();
}
尽管接受了上述答案(感谢Praveen的帮助!),我找到的唯一真正的解决方案是避免Spring的默认注销-
注销处理程序只是一个常规控制器处理程序(我将其命名为“myLogout”),
@GetMapping("/participant/myLogout")
public String myLogout(HttpServletRequest request, HttpServletResponse response) throws Exception {
// Just for testing, the param is available:
System.out.println(request.getParameter("exitMsg");
// Manual logoff
CookieClearingLogoutHandler cookieClearingLogoutHandler = new CookieClearingLogoutHandler(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
SecurityContextLogoutHandler securityContextLogoutHandler = new SecurityContextLogoutHandler();
cookieClearingLogoutHandler.logout(request, response, null);
securityContextLogoutHandler.logout(request, response, null);
// My custom Logout JSP. No auto-redirects to Login
return LOGOUT_JSP;
}
如果需要param,它在服务器端和客户端的注销JSP中都有:
`${param.exitMsg}`: --> Output: `test`.
所有以某种方式重定向到使用参数登录的建议——无论是使用这里的CustomLogoutSuccessHandler
实现,还是直接通过这里的控制器重定向——在Spring Security Config“Login wall”需求为
// ... special URLs listed here, then at the end:
.antMatchers("/participant/**").authenticated()
在您的特殊权限列表之后。它不起作用,因为Spring Security将首先执行带有NO参数的基本 /login的Login-Wall要求,只要您尝试甚至重定向到带有参数的Login。并且只有这样,在您验证自己之后,它才会为带有参数的重定向服务,例如login?logout
我认为我们不应该在Config中去掉
. enticated()
,因为这是对所有请求创建Login-Wall保护的原因,这是一个重要的安全功能。但是当你有它时,你就不能将参数传递给/login
,因为带有NO参数的基本Login-Wall/login
总是会先发生。
这个问题没有真正的解决方案——我唯一能解决这个问题的方法就是绕过整个默认行为,只需要有一个与登录完全不同的专用注销页面。这个解决方案有效,我不需要立即重新显示登录页面。
您需要logoutAccessHandler
而不是. logoutAccessUrl("/login? logout")
配置logoutAccessHandler
如下所示
@Override
protected void configure(final HttpSecurity http) throws Exception
{
http
.authorizeRequests()
.antMatchers("/resources/**", "/", "/login", "/api/**")
.permitAll()
.antMatchers("/app/admin/*")
.hasRole("ADMIN")
.antMatchers("/app/user/*")
.hasAnyRole("ADMIN", "USER")
.and().exceptionHandling().accessDeniedPage("/403")
.and().formLogin()
.loginPage("/login").usernameParameter("userName")
.passwordParameter("password")
.defaultSuccessUrl("/app/user/dashboard")
.failureUrl("/login?error=true")
.and().logout()
.logoutSuccessHandler(new CustomLogoutSuccessHandler())
.invalidateHttpSession(true)
.and().csrf().disable();
http.sessionManagement().maximumSessions(1).expiredUrl("/login?expired=true");
}
我考虑编写自己的/注销处理程序
事实上,这不是注销处理程序,但它是注销启动器。
使用CustomLogout成功处理程序,您可以在其中获取请求参数's,并且可以再次设置它,如下所示。
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;
public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler
{
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException
{
Cookie cookie = new Cookie("JSESSIONID", null);
cookie.setPath(request.getContextPath());
cookie.setMaxAge(0);
response.addCookie(cookie);
if(request.getParameter("expired") != null)
{
response.sendRedirect(request.getContextPath()+"/login?expired=true");
}
else
{
response.sendRedirect(request.getContextPath() + "/login?logout=true");
}
}
}
从我的应用程序中,我发出这个Spring Security Logout URL(注销是自动的,所以我没有特定的处理程序)
servlet/Spring security中没有自动注销功能。只有我们能实现的是
1.自动化客户端发送注销请求
2.在服务器中我们可以设置session的maxInactiveInterval,这样就可以通过删除cookie/将cookie的年龄设置为过去的日期来使会话无效。一旦会话对下一个请求无效,Spring security过滤器链中的过滤器之一将其重定向到参数过期的 /login页面。/login? expated
如果您发起注销Spring security将删除cookie/使会话无效并重定向到参数注销的 /login页面。/login? logout
在Spring security中实现注销的配置有两种类型。
.and().logout()
.invalidateHttpSession(true)
//or
.deleteCookies("JSESSIONID")
编辑:在看到OP的答案后。此处添加缺少的信息。OP和我在临时答案中进行了长时间的聊天(该聊天和答案已被删除),我们在那里找到了登录墙。
“登录墙”是坏*配置的结果,您将定义一个自定义登录页面,并将其配置为在身份验证后允许访问的资源。(access=isAuthenticated
)但如果我们在会话无效后重定向到登录页面,则来自CustomLogoutSuccessHandler,Spring Security阻止登录页面访问(401未授权),因为该页面仅允许经过身份验证的用户访问。阻塞后,Spring Security性负责重定向到配置中配置的页面。登录页面(“/someloginpage”)。它迫使我们思考的是,正确地注销,正确地重定向到登录页面,但我在查询字符串中发送的参数并没有进入登录页面。如果我把这个叫做拼图,这没什么错,很难猜。
问题内容: 我想将值传递给javascript。如果可能的话,我该怎么办?如何在后备bean中接收它们? 问题答案:
问题内容: 我们已经设置了一些参数来在Jenkins中执行构建(使用简单的“参数化构建”设置)。作业被设置为Maven测试。有没有办法以编程方式将这些参数传递到我们的Java代码中?我们需要基于通过Jenkins设置的参数来执行某些更新功能。 问题答案: 是的,您可以通过Maven执行将Jenkins参数传递给Java代码,如下所示: 请注意, $ JOB_PARAM_1 将捕获Jenkins上设
当ARDUINO UNO上的引脚2接地时,此示例使用键盘库将您从计算机上的用户会话中注销。 草图同时按两个或三个键的顺序模拟按键,并在短暂延迟后释放它们。 Warning - 使用Keyboard.print()命令时,Arduino将接管计算机的键盘。 为确保在使用此功能运行草图时不会失去对计算机的控制,请在调用Keyboard.print()之前设置可靠的控制系统。 此草图设计为仅在将引脚拉到
我正在为webste构建一个功能,用户可以在其中重置密码。他收到一封电子邮件,其中包含URL中生成的令牌。单击此链接时,用户将被发送到/Reset页面。该页的Get方法如下:
我对JSP/servlets相当陌生,我一直在研究一些东西,它已经工作了一段时间。我有一个名为'telgir.jsp'的jsp,我从这个jsp向一个名为'tel Kayit'的servlet传递一个URL参数。 在LocalHost上运行时JSP页面的一个示例URL: 当我在servlet中接收到参数时,参数发生了变化,因此无法正确地对其进行解码并获得结果。根据我的研究,我意识到“%”符号使我的代
问题内容: 我已经编写了这个jQuery ajax方法,在下面调用了webmethod。除了作为用户对象的参数具有空字段之外,调用进行得很好。我在调试时可以在firebug中看到值,但它们无法通过webmethod中的User对象参数 我试图从jQuery方法传递给Webmethod的两个值是“ UserID”(Guid)和“ About”(字符串),它们都是User类的属性,但在服务端,是Use