在本专栏前篇文章中介绍了HttpBasic模式,该模式比较简单,只是进行了通过携带Http的Header进行简单的登录验证,而且没有可以定制的登录页面,所以使用场景比较窄。

对于一个完整的应用系统,与登录验证相关的页面都是高度定制化的,非常美观而且提供多种登录方式。这就需要Spring Security支持我们自己定制登录页面,也就是本文给大家介绍的FormLogin模式登录认证模式。

1. 新建项目

在介绍相关内容之前,需要先搭建一个demo,新建一个项目spring-security-02,需要添加依赖如下:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> 复制代码

除此之外其实还需要添加web、thymeleaf的依赖,这里就不在贴出来了

demo结构如下:

spring单点登录与权限管控(手摸手教你定制)(1)

2. 新建登录页面

这里不再使用Security默认的页面,自己定制一个,代码如下:

spring单点登录与权限管控(手摸手教你定制)(2)

单纯的一个表单登录页面,需要注意以下几个参数:

  1. action:security登录的url,可以自定义,下文介绍
  2. username:security登录的用户名,可以自定义,下文介绍
  3. password:security登录的密码,可以自定义,下文介绍

以上三个参数都可以在security通过配置的方式定义

3. 新建首页

这个是登录成功后跳转的首页,代码如下:

spring单点登录与权限管控(手摸手教你定制)(3)

4. 新建接口

在security中一切的接口都称之为资源,下面新建两个测试接口,代码如下:

spring单点登录与权限管控(手摸手教你定制)(4)

5. formLogin配置

在介绍如何配置之前,先来看下formLogin模式登录的5个要素:

  1. 登录认证逻辑-登录URL:这个URL在security中默认是/login且POST请求,但是也可以通过配置自定义
  2. 如何接收登录参数:用户名、密码默认接收的字段分别是username、password,同样也是可以通过配置自定义
  3. 登陆成功后逻辑:登录成功后的处理逻辑,比如跳转到指定的页面、返回特定的JSON数据,这个也是可以定制
  4. 资源访问控制规则:这个用于控制什么用户、什么角色可以访问什么资源,可以静态指定也可以从数据库中加载
  5. 用户具有角色权限:配置某个用户拥有什么角色、拥有什么权限,可以静态指定也可以从数据库中加载

一般来说,使用权限认证框架的的业务系统登录验证逻辑是固定的,而资源访问控制规则和用户信息是从数据库或其他存储介质灵活加载的。但本文所有的用户、资源、权限信息都是代码配置写死的,旨在为大家介绍formLogin认证模式,如何从数据库加载权限认证相关信息我还会结合RBAC权限模型再写文章的。

针对上述5个的要素,formLogin配置代码如下:

spring单点登录与权限管控(手摸手教你定制)(5)

首先,我们要继承WebSecurityConfigurerAdapter ,重写configure(HttpSecurity http) 方法,该方法用来配置登录验证逻辑。请注意看代码中的注释信息。

上述代码分为两个部分:

第一部分是formLogin配置段,用于配置登录验证逻辑相关的信息。如:登录页面、登录成功页面、登录请求处理路径等。

第二部分是authorizeRequests配置段,用于配置资源的访问控制规则

6. 用户、角色配置

在上述的规则中配置了一些资源需要特定的角色才可以访问,比如user、admin,那么这些角色如何去指定呢?

在security中提供了配置的方式,代码如下:

spring单点登录与权限管控(手摸手教你定制)(6)

上述的代码配置很简单,创建了两个用户且指定了角色,分别如下:

配置解释如下:

7. 简单测试

按照上述6个步骤基本实现了一个表单登录,下面测试一下

浏览器访问http://localhost:8081/hello2,第一次访问由于未登录会自动跳转到登录页面,如下图:

spring单点登录与权限管控(手摸手教你定制)(7)

输入用户名和密码,由于/hello2这个资源需要admin的角色才能访问,因此必须用admin这个用户登录,否则将会报403的错误,登录成功后将能够正常访问

spring单点登录与权限管控(手摸手教你定制)(8)

如果用户名或者密码错误将会触发.failureUrl("/login/page")这个配置,自动跳转到登录页面

8. 自定义登录结果

在第5步的配置中,和登录结果相关的配置有如下两个:

这两个配置都是指定URL的方式:

但是在web应用开发过程中需求是千变万化的,有时需要我们针对登录结果做个性化处理,比如:

因此需要自定义的登录结果,这篇文章先介绍如何定制跳转页面,关于JSON格式数据就是前后端分离架构下需要用到,后文介绍

8.1 自定义登录成功结果

AuthenticationSuccessHandler接口是Security提供的认证成功处理器接口,我们只需要去实现它即可。但是通常来说,我们不会直接去实现AuthenticationSuccessHandler接口,而是继承SavedRequestAwareAuthenticationSuccessHandler 类,这个类会记住用户上一次请求的资源路径,比如/hello2这个路径,登录成功后将会自动跳转到/hello2这个页面而不是首页

代码如下:

spring单点登录与权限管控(手摸手教你定制)(9)

8.2 自定义登录失败结果

这里我们同样没有直接实现AuthenticationFailureHandler接口,而是继承SimpleUrlAuthenticationFailureHandler 类。该类中默认实现了登录验证失败的跳转逻辑,即登陆失败之后回到登录页面。我们可以利用这一点简化我们的代码。

代码如下:

spring单点登录与权限管控(手摸手教你定制)(10)

8.3 SecurityConfig中配置

配置如下:

spring单点登录与权限管控(手摸手教你定制)(11)

将自定义的AuthenticationSuccessHandler和AuthenticationFailureHandler注入到Spring Security配置类中

使用formlogin模式,配置successHandler和failureHandler。

不要配置defaultSuccessUrl和failureUrl,否则自定义handler将失效。handler配置与URL配置只能二选一

总结

本篇文章介绍了Spring Security 的 formLogin的配置方式,需要注意的是这里不支持前后端分离架构,关于前后端分离架构如何整合,后文会介绍

来源:https://juejin.cn/post/7140096326829621261

,