千家信息网

Spring security 02中怎么自定义用户登录页面和登录处理逻辑

发表于:2024-09-22 作者:千家信息网编辑
千家信息网最后更新 2024年09月22日,Spring security 02中怎么自定义用户登录页面和登录处理逻辑,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Spring
千家信息网最后更新 2024年09月22日Spring security 02中怎么自定义用户登录页面和登录处理逻辑

Spring security 02中怎么自定义用户登录页面和登录处理逻辑,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

Spring security 系列博客目录

  • Spring Security 01- 将 Spring security 引入到工程

  • Spring security 02-自定义用户登录页面和登录处理逻辑

  • Spring security 03-自定义登录成功后的处理逻辑

  • Spring security 04-整合 jwt

对应源代码

  • Spring Security 01- 将 Spring security 引入到工程

  • Spring security 02-自定义用户登录页面和登录处理逻辑

  • Spring security 03-自定义登录成功后的处理逻辑

  • Spring security 04-整合 jwt

开篇

上一篇(在项目里面引入spring-security会发生什么)我们将 Spring-seccurity 引入到了我们的spring-boot工程中,没有做多余的配置,spring-security 就已经默认帮我们配置了一个拦截器,应用启动后,当我们访问应用提供的资源时,都会跳转到 security 为我们提供的一个默认登陆页,当我们输入security为我们提供的用户名和密码,登陆成功后,就可以获取我们需要的资源。那么问题来了!我们如何自定义自己的登录页面,以及使用我们自己的用户信息去登录呢?

实战

创建工程

为了不影响之前的版本,我们这里新建一个模块 spring-security-02,之前的版本是spring-security-01. https://github.com/nimo10050/spring-security-sample/tree/master/spring-security-02

引入依赖

依赖跟上个版本一样,如下:

                                               org.springframework.boot                        spring-boot-starter-security                                                        org.springframework.boot                        spring-boot-starter-web                        

新建 SpringSecurity 配置类

既然我们需要自定义一些东西,只能通过额外配置的方式来实现。所以这里引入了spring-security的配置类

  • 添加 @Component注解

  • 添加 Spring-security 的注解 EnableWebSecurity 标记这是 security的 配置类

  • 继承 WebSecurityConfigurerAdapter 重写它的配置方法

  • 重写 configure(HttpSecurity http) 方法是为了定义登陆页

  • 重写 configure(AuthenticationManagerBuilder auth) 是为了定义登录逻辑

      package com.example.demo.config;  import com.example.demo.config.service.UserDetailServiceImpl;  import org.springframework.context.annotation.Bean;  import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;  import org.springframework.security.config.annotation.web.builders.HttpSecurity;  import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;  import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;  import org.springframework.security.core.userdetails.UserDetailsService;  import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;  import org.springframework.security.crypto.password.PasswordEncoder;  import org.springframework.stereotype.Component;  [@Component](https://my.oschina.net/u/3907912)  @EnableWebSecurity  public class WebSecurityConfig extends WebSecurityConfigurerAdapter {  [@Override](https://my.oschina.net/u/1162528)  protected void configure(HttpSecurity http) throws Exception {      http.csrf().disable();// 必须有, 不然会 403 forbidden      http.formLogin()                      .loginPage("/loginPage.html")// 自定义登录页                      .loginProcessingUrl("/form/login");// 自定义登录 action, 名字随便起                      // passwordParameter("password") 配置 form 表单 密码的 name 属性值                      // usernameParameter("username") 配置 form 表单 用户名的 name 属性值      // 访问 "/form/login", "/loginPage.html"   放行      http.authorizeRequests().antMatchers("/form/login", "/loginPage.html").permitAll()                      .anyRequest().authenticated();  }  /**   * 配置 用户登录处理类   *   * [@param](https://my.oschina.net/u/2303379) auth   * @throws Exception   */  @Override  protected void configure(AuthenticationManagerBuilder auth) throws Exception {      /* 将用户信息存储到内存中         实际上不会这样做,了解下即可      auth.inMemoryAuthentication()                      .withUser("zhangsan")                      .password(passwordEncoder().encode("123456"))                      .authorities("admin");*/      auth.userDetailsService(userDetailsService());  }  /**   * 自定义登录处理   *   * @return   */  @Bean  public UserDetailsService userDetailsService() {      return new UserDetailServiceImpl();  }  /**   * 加密工具   * 2.x 版本的 spring-security-starter 必须加上   *   * @return   */  @Bean  public PasswordEncoder passwordEncoder() {      return new BCryptPasswordEncoder();  }  }


UserDetailService 接口

通过重写 UserDetailService 接口的 loadUserByUsername方法来实现登录逻辑,在loadUserByUsername 方法里我们可以读取数据库或者其他存储介质,来校验我们的用户是否存在。最后将我们实现的类配置到config方法中。

/** * 自定义登录处理逻辑 */public class UserDetailServiceImpl implements UserDetailsService {/*    @Autowiredprivate PasswordEncoder passwordEncoder;*//** * @param username 登录页面输入的用户名 * @return * @throws UsernameNotFoundException */@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {    // TODO 根据 username 去用户表查询出来用户的信息,然后进行验证    // 验证成功后,返回Spring-Security 提供的 User 对象    // 对应三个构造参数依次是: 1.用户名 2.密码(经过 passwordEncoder 加密后的密码) 3.权限列表    return new User(username, "$2a$10$g1gzj4KvMNY1kMZT1xDx9ufLuaDvCFDpX.PdETx85zQwXI/Mn4ttC", AuthorityUtils.createAuthorityList("admin"));}public static void main(String[] args) {    System.out.println(new BCryptPasswordEncoder().encode("123456"));// $2a$10$g1gzj4KvMNY1kMZT1xDx9ufLuaDvCFDpX.PdETx85zQwXI/Mn4ttC}}

其他需要注意的点

  • 在 configure(HttpSecurity http) 方法中需要加上 http.csrf().disable();不用问为什么,加上就完事了。

  • 当我们重写了config 方法后,spring-security 就不会拦截我们要访问的资源了,所以需要重新配置下

http.authorizeRequests().antMatchers("/form/login","/loginPage.html").permitAll().anyRequest().authenticated();

  • 当我们定义了UserDetailService,应用启动时控制台就不会打印默认密码了。

  • 高版本的 security 必须要配置密码加密工具类。不然会报错

      passwordEncoder is null


关于Spring security 02中怎么自定义用户登录页面和登录处理逻辑问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注行业资讯频道了解更多相关知识。

0