返回介绍

4.6 使用 JSON 格式登录

发布于 2025-04-26 13:16:44 字数 2686 浏览 0 评论 0 收藏 0

Spring Security 中默认的登录参数传递格式是 key/value 形式,也就是表单登录格式,在实际项目中,我们可能会通过 JSON 格式来传递登录参数,这就需要我们自定义登录过滤器来实现。

通过 3.1.4 小节的介绍,大家已经明白登录参数的提取是在 UsernamePassword AuthenticationFilter 过滤器中完成的。如果我们要使用 JSON 格式登录,只需要模仿 Username PasswordAuthenticationFilter 过滤器定义自己的过滤器,再将自定义的过滤器放到 UsernamePasswordAuthenticationFilter 过滤器所在的位置即可。

思路理清了,我们来看代码实现。首先我们自定义一个 LoginFilter 继承自 Username PasswordAuthenticationFilter,代码如下:

(1)首先确保进入该过滤器中的请求是 POST 请求。

(2)根据请求的 content-type 来判断参数是 JSON 格式的还是 key/value 格式的,如果是 JSON 格式的,则直接在当前方法中处理;如果是 key/value 格式的,那直接调用父类的 attemptAuthentication 方法处理即可。

(3)如果请求参数是 JSON 格式,则首先利用 jackson 提供的 ObjectMapper 工具,将输入流转为 Map 对象,然后从 Map 对象中分别提取出用户名/密码信息并构造出 Username PasswordAuthenticationToken 对象,然后调用 AuthenticationManager 的 authenticate 方法执行认证操作。

其实 LoginFilter 中,从请求中提取出 JSON 参数之后的认证逻辑和父类 UsernamePassword AuthenticationFilter 中的认证逻辑是一致的,读者可以回顾第 3 章中关于 UsernamePassword AuthenticationFilter 的分析。

LoginFilter 定义完成后,接下来我们将其添加到 Spring Security 过滤器链中,代码如下:

(1)首先重写 configure 方法来定义一个登录用户。

(2)重写父类的 authenticationManagerBean 方法来提供一个 AuthenticationManager 实例,一会将配置给 LoginFilter。

(3)配置 loginFilter 实例,同时将 AuthenticationManager 实例设置给 loginFilter,然后再设置登录成功回调。当然,我们也可以在 loginFilter 中配置用户名/密码的参数名或者登录失败的回调。

(4)最后在 HttpSecurity 中,调用 addFilterAt 方法将 loginFilter 过滤器添加到 Username PasswordAuthenticationFilter 过滤器所在的位置。

配置完成后,重启项目,此时我们就可以使用 JSON 格式的数据来进行登录操作了,如图 4-11 所示。

图 4-11 使用 JSON 格式登录

有读者可能会注意到,当我们想要获取一个 AuthenticationManager 实例时,有两种不同的方式,第一种方式是通过重写父类的 authenticationManager 方法获取,第二种则是通过重写父类的 authenticationManagerBean 方法获取。表面上看两种方式获取到的 AuthenticationManager 实例在这里都可以运行,但实际上是有区别的。区别在于第一种获取到的是全局的 AuthenticationManager 实例,而第二种获取到的是局部的 AuthenticationManager 实例,而 LoginFilter 作为过滤器链中的一环,显然应该配置局部的 AuthenticationManager 实例,因为如果将全局的 AuthenticationManager 实例配置给 LoginFilter,则局部 Authentication Manager 实例所对应的用户就会失效,例如如下配置:

在上面这段代码中,我们将无法使用 javagirl/123 进行登录,因为 LoginFilter 中指定了全局的 AuthenticationManager 来做验证,所以局部的 AuthenticationManager 实例失效了。

在实际应用中,如果需要自己配置一个 AuthenticationManager 实例,大部分情况下,我们都是通过重写 authenticationManagerBean 方法来获取。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。