详解Spring-Security的formLogin登录认证模式

3次阅读

共计 3214 个字符,预计需要花费 9 分钟才能阅读完成。

一、formLogin 的应用场景

在本专栏之前的文章中,已经给大家介绍过 Spring Security 的 HttpBasic 模式,该模式比较简单,只是进行了通过携带 Http 的 Header 进行简单的登录验证,而且没有定制的登录页面,所以使用场景比较窄。
对于一个完整的应用系统,与登录验证相关的页面都是高度定制化的,非常美观而且提供多种登录方式。这就需要 Spring Security 支持我们自己定制登录页面,也就是本文给大家介绍的 formLogin 模式登录认证模式。

准备工作

  • 新建一个 Spring Boot 的 web 应用,引入 Spring Security Starter。
  • 准备一个 login.html 登录页面,页面内容非常简单,一个 from 表单、用户名和密码输入框,一个提交按钮
  • 准备一个首页 index.html,在登录成功之后需要进入 index.html 首页
  • 首页可以看到 syslog(日志管理)、sysuer(用户管理)、biz1(业务一)、biz2(业务二)四个页面超文本链接选项。通过 controller 控制层跳转页面,并在对应页面写一些标志性文字即可,不需写具体业务。

需求

  • 我们希望 biz1(业务一)、biz2(业务二)普通的操作用户 user 就可以访问
  • 我们希望管理员可以访问包括 syslog(日志管理)和 sysuser(用户管理) 在内的所有资源

以上就是本文介绍 formLogin 模式需要进行的准备工作及需求,下面我们就来实现其中的核心的登录验证逻辑,准备工作非常简单请自行实现。(新建 spring boot 应用,登录页面、首页、四个业务页面都写成非常简单的 html 即可,不用写实际业务和样式。)

二、说明

formLogin 模式的三要素:

  • 登录验证逻辑
  • 资源访问控制规则,如:资源权限、角色权限
  • 用户信息

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

三、实现 formLogin 模式基础配置

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

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {http.csrf().disable() // 禁用跨站 csrf 攻击防御,后面的章节会专门讲解
            .formLogin()
                .loginPage("/login.html")// 用户未登录时,访问任何资源都转跳到该路径,即登录页面
                .loginProcessingUrl("/login")// 登录表单 form 中 action 的地址,也就是处理认证请求的路径
                .usernameParameter("uname")/// 登录表单 form 中用户名输入框 input 的 name 名,不修改的话默认是 username
                .passwordParameter("pword")//form 中密码输入框 input 的 name 名,不修改的话默认是 password
                .defaultSuccessUrl("/index")// 登录认证成功后默认转跳的路径
                .and()
            .authorizeRequests()
                .antMatchers("/login.html","/login").permitAll()// 不需要通过登录验证就可以被访问的资源路径
                .antMatchers("/biz1").hasAnyAuthority("biz1")  // 前面是资源的访问路径、后面是资源的名称或者叫资源 ID
                .antMatchers("/biz2").hasAnyAuthority("biz2")
                .antMatchers("/syslog").hasAnyAuthority("syslog")
                .antMatchers("/sysuser").hasAnyAuthority("sysuser")
                .anyRequest().authenticated();
    }
    
}

上面的代码分为两部分:

  • 第一部分是 formLogin 配置段,用于配置登录验证逻辑相关的信息。如:登录页面、登录成功页面、登录请求处理路径等。
  • 第二部分是 authorizeRequests 配置端,用于配置资源的访问权限。如:开发登录页面的 permitAll 开放访问,“/biz1”(业务一页面资源)需要有资源 ID 为 ”biz1″ 的用户才可以访问。

这时候,我们通过浏览器访问,随便测试一个没有访问权限的资源,都会跳转到 login.html 页面。

四、实现资源访问限制的需求

在上文中,我们配置了登录验证及资源访问的权限规则,我们还没有具体的用户,下面我们就来配置具体的用户。重写 WebSecurityConfigurerAdapter 的 configure(AuthenticationManagerBuilder auth) 方法

public void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication()
        .withUser("user").password(passwordEncoder().encode("123456")).authorities("biz1","biz2")
        .and()
        .passwordEncoder(passwordEncoder());// 配置 BCrypt 加密
}

@Bean
public PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();
}
  • inMemoryAuthentication 指的是在内存里面存储用户的身份认证和授权信息。
  • withUser("user") 用户名是 user
  • password(passwordEncoder().encode("123456")) 密码是加密之后的 123456
  • authorities("biz1","biz2") 指的是 user 用户拥有资源 ID 为 biz1(业务一) 和 biz2(业务二) 资源的权限

这样,我们就实现了文首提出的普通用户只能访问 biz1(业务一) 和 biz2(业务二) 资源的需求。那么管理员用户可以访问所有的资源的配置方式,你会不会呢?同样的配方、同样的方式、自己可以尝试一下哦!

五、静态资源访问

在我们的实际开发中,登录页面 login.html 和控制层 Controller 登录验证 ’/login’ 都必须无条件的开放。除此之外,一些静态资源如 css、js 文件通常也都不需要验证权限,我们需要将它们的访问权限也开放出来。下面就是实现的方法:重写 WebSecurityConfigurerAdapter 类的 configure(WebSecurity web) 方法


   @Override
    public void configure(WebSecurity web) {
        // 将项目中静态资源路径开放出来
        web.ignoring().antMatchers("/config/**", "/css/**", "/fonts/**", "/img/**", "/js/**");
    }

期待您的关注

  • 博主最近新写了一本书:《手摸手教您学习 SpringBoot 系列 -16 章 97 节》
  • 本文转载注明出处(必须带连接,不能只转文字):字母哥博客。
正文完
 0