写在前面

按照顺序接下来应该学习登录实现的机制,但是考虑到这是入门文章,因此这里先跳过,后续再来介绍。

接下来需要针对登录成功后的两种较为普遍的场景进行介绍,其实就是前后端分离和前后端不分离这两种情况,两种情况的处理方式是不相同的,本篇介绍前后端不分离模式下的处理方式,前后端分离模式则在下篇进行介绍,同时还会学习如何注销登录。

登录成功回调

SpringSecurity中有两个方法与登录成功重定向URL相关,分别是successForwardUrldefaultSuccessUrl,那么你可能就要问了,我怎么知道这两个方法与登录成功重定向URL相关呢?

前面说过SpringSecurity中与登录相关的配置信息都在FormLoginConfigurer类中,因此回到FormLoginConfigurer和它的父类AbstractAuthenticationFilterConfigurer中,可以发现前者存在successForwardUrl方法,而后者存在defaultSuccessUrl方法。

FormLoginConfigurer#successForwardUrl方法源码如下所示:

1
2
3
4
public FormLoginConfigurer<H> successForwardUrl(String forwardUrl) {
this.successHandler(new ForwardAuthenticationSuccessHandler(forwardUrl));
return this;
}

AbstractAuthenticationFilterConfigurer#defaultSuccessUrl方法源码如下所示:

1
2
3
4
5
6
7
8
9
10
11
public final T defaultSuccessUrl(String defaultSuccessUrl) {
return this.defaultSuccessUrl(defaultSuccessUrl, false);
}

public final T defaultSuccessUrl(String defaultSuccessUrl, boolean alwaysUse) {
SavedRequestAwareAuthenticationSuccessHandler handler = new SavedRequestAwareAuthenticationSuccessHandler();
handler.setDefaultTargetUrl(defaultSuccessUrl);
handler.setAlwaysUseDefaultTargetUrl(alwaysUse);
this.defaultSuccessHandler = handler;
return this.successHandler(handler);
}

可能光看源码看不出两者的用法,首先明确在使用的时候只需要选择其中一个配置即可,具体选择哪个需要结合具体业务需求

successForwardUrldefaultSuccessUrl这两者的区别如下:
(1)对于successForwardUrl来说,无论之前想访问的是哪个链接,登录后都会跳转到successForwardUrl指定的地址。如当开发者指定successForwardUrl的地址为/book,那么当你想访问http://localhost:8080/hello页面时,会因未登录而跳转至登录页面,然后正确输入账户信息并成功登陆后,注意此时页面会跳转至http://localhost:8080/book;或者说开发者直接在浏览器地址栏中输入登录地址,那么登录成功后页面也是会跳转至http://localhost:8080/book页面。

(2)对于defaultSuccessUrl来说,由于它存在两个重载方法,因此需要结合参数的数量来进行分析。当用户调用defaultSuccessUrl包含两个参数的方法时,即下面的方法:

1
2
3
4
5
6
7
public final T defaultSuccessUrl(String defaultSuccessUrl, boolean alwaysUse) {
SavedRequestAwareAuthenticationSuccessHandler handler = new SavedRequestAwareAuthenticationSuccessHandler();
handler.setDefaultTargetUrl(defaultSuccessUrl);
handler.setAlwaysUseDefaultTargetUrl(alwaysUse);
this.defaultSuccessHandler = handler;
return this.successHandler(handler);
}

可以看到defaultSuccessUrl就是默认跳转的地址,而defaultSuccessUrl参数则表明是否使用默认的跳转地址。

(a)当alwaysUse为true的时候,就表示使用默认的跳转地址,此时如开发者指定defaultSuccessUrl的地址为/book,那么当你想访问http://localhost:8080/hello页面时,会因未登录而跳转至登录页面,然后正确输入账户信息并成功登陆后,注意此时页面会跳转至http://localhost:8080/book;或者说开发者直接在浏览器地址栏中输入登录地址,那么登录成功后页面也是会跳转至http://localhost:8080/book页面。其实这时候就和successForwardUrl方法想表达的意思一样了。

(b)当alwaysUse为false的时候,就表示不使用默认的跳转地址,此时如开发者指定defaultSuccessUrl的地址为/book,那么当你想访问http://localhost:8080/hello页面时,会因未登录而跳转至登录页面,然后正确输入账户信息并成功登陆后,注意此时页面会跳转至http://localhost:8080/hello。开发者直接在浏览器地址栏中输入登录地址,那么登录成功后页面会跳转至http://localhost:8080/book页面。

(3)当用户调用defaultSuccessUrl只有一个参数的方法时,即下面的方法:

1
2
3
public final T defaultSuccessUrl(String defaultSuccessUrl) {
return this.defaultSuccessUrl(defaultSuccessUrl, false);
}

可以看到此时就是第二个参数为false的情况,因此其实就是上面(b)中的情况,因此这里就不赘述了。

笔者的配置信息如下:

登录失败回调

说完了登录成功回调,接下来聊一聊登录失败之后的回调,其实两者逻辑非常相似,提供的方式也是类似。

在SpringSecurity中有两个方法与登录失败重定向URL相关,分别是FormLoginConfigurer#failureForwardUrlAbstractAuthenticationFilterConfigurer#failureUrl方法。同样在使用的时候只需要选择其中一个配置即可,具体选择哪个需要结合具体业务需求。

failureForwardUrlfailureUrl这两者的区别如下:
(1)对于FormLoginConfigurer#failureForwardUrl方法来说,无论之前想访问的是哪个链接,都会因未跳转到登录页面,当登录不成功时页面会继续跳转至登录页面。

1
2
3
4
public FormLoginConfigurer<H> failureForwardUrl(String forwardUrl) {
this.failureHandler(new ForwardAuthenticationFailureHandler(forwardUrl));
return this;
}

(2)对于AbstractAuthenticationFilterConfigurer#failureUrl方法来说,无论之前想访问的是哪个链接,都会因未登录而跳转到登录页面,当登录不成功时页面会跳转至failureUrl方法中设置的authenticationFailureUrl链接。

1
2
3
4
5
public final T failureUrl(String authenticationFailureUrl) {
T result = this.failureHandler(new SimpleUrlAuthenticationFailureHandler(authenticationFailureUrl));
this.failureUrl = authenticationFailureUrl;
return result;
}

注销登录

为了后续测试需要,这里提前学习如何注销登录。其实和登录类似,注销相关的配置均在LogoutConfigurer类中:

1
public final class LogoutConfigurer<H extends HttpSecurityBuilder<H>> extends AbstractHttpConfigurer<LogoutConfigurer<H>, H> { }

可以看到该类继承自AbstractHttpConfigurer类,查阅一下AbstractHttpConfigurer类的源码:

这么看似乎该类并没有像登录那样的信息配置,那就回到LogoutConfigurer类,可以发现其中有两个重要的属性logoutUrllogoutSuccessUrl,顾名思义这些就是后续会用到的信息:

同时查看LogoutConfigurer类的信息可知,其实图中的这些方法就是开发者在MyWebSecurityConfig类的configure(HttpSecurity http)类中调用的方法:

所以当开发者需要什么配置其实就相当于在调用此类中对应的方法和属性:

根据上面的图片可以知道:(1)注销登录默认使用的是/logout,且开发者可以通过logoutUrl方法来修改默认的logoutUrl;(2)开发者可以通过logoutSuccessUrl()方法来修改注销成功后要跳转的页面;(3)clearAuthentication()方法表示清除验证信息,默认会自动清除;(4)invalidateHttpSession()方法表示使HttpSession失效,默认会自动清除;(5)deleteCookies()方法表示删除cookies信息;(6)logoutRequestMatcher()方法不仅可以修改注销登录的URL,还可以修改请求方式。实际开发过程中,这个方法和logoutUrl方法选择一个即可。

那么到此关于前后端不分离模式下的登录回调的学习和如何注销登录就到此结束,下一篇研究前后端分离模式下的登录内容。