SpringSecurity 自定义表单登录的实现

下面是SpringSecurity自定义表单登录的实现攻略:

1. 确定用户信息来源

在进行 SpringSecurity 表单登录认证之前,我们需要确定用户信息的来源。通常,我们可以从数据库、LDAP、Active Directory 或者使用第三方的 SAML/OAuth2 身份验证服务中获取用户信息,这里我们以数据库中获取用户信息为例。

2. 用户认证流程

SpringSecurity 表单登录认证的流程如下:

  1. 用户访问需要进行认证的资源,如 /login 页面。
  2. 进入登录页面后,用户输入用户名和密码,提交表单。
  3. SpringSecurity 接收请求,对用户名和密码进行认证。
  4. 如果用户名和密码正确,SpringSecurity 为用户生成一个令牌,并把令牌返回给客户端。
  5. 后续的每个请求都会携带该令牌信息,SpringSecurity 通过此令牌对请求进行权限校验。

3. 实现步骤

下面是自定义表单登录的实现步骤:

3.1 导入所需依赖

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
</dependency>

3.2 实现 UserDetailsSerrvice 接口

@Service
public class CustomUserDetailsService implements UserDetailsService {

  @Autowired
  private UserRepository userRepository;

  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    User user = userRepository.findByUsername(username);
    if(user == null) {
      throw new UsernameNotFoundException("用户名不存在!");
    }

    return new org.springframework.security.core.userdetails.User(
            user.getUsername(),
            user.getPassword(),
            user.getAuthorities());
  }
}

UserDetailsService 接口用于从数据库中获取用户信息。

3.3 实现 AuthenticationProvider 接口

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

  @Autowired
  private CustomUserDetailsService userDetailsService;

  @Override
  public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    String username = authentication.getName();
    String password = (String) authentication.getCredentials();

    UserDetails userDetails = userDetailsService.loadUserByUsername(username);
    if(!password.equals(userDetails.getPassword())) {
      throw new BadCredentialsException("密码不正确!");
    }

    return new UsernamePasswordAuthenticationToken(username, password, userDetails.getAuthorities());
  }

  @Override
  public boolean supports(Class<?> authentication) {
    return authentication.equals(UsernamePasswordAuthenticationToken.class);
  }
}

AuthenticationProvider 接口用于对用户的登陆信息进行认证。

3.4 配置 Security

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Autowired
  private CustomAuthenticationProvider customAuthenticationProvider;

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(customAuthenticationProvider);
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
      .authorizeRequests()
        .anyRequest().authenticated()
        .and()
      .formLogin()
        .loginPage("/login")
        .successForwardUrl("/index")
        .permitAll()
        .and()
      .logout().permitAll();
  }
}

在 SecurityConfig 中,我们指定了 CustomAuthenticationProvider 来进行认证,还配置了登录页面的路径、认证成功后跳转的页面路径。

3.5 创建登录页面

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>登录</title>
</head>
<body>
  <form action="/login" method="post">
    <label for="username">用户名:</label>
    <input type="text" id="username" name="username"><br>

    <label for="password">密码:</label>
    <input type="password" id="password" name="password"><br>

    <input type="submit" value="登录">
  </form>
</body>
</html>

4. 示例

下面提供两个示例:

4.1 基于 JPA 的用户认证

@Service
public class CustomUserDetailsService implements UserDetailsService {

  @Autowired
  private UserRepository userRepository;

  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    User user = userRepository.findByUsername(username);
    if(user == null) {
      throw new UsernameNotFoundException("用户名不存在!");
    }

    return new org.springframework.security.core.userdetails.User(
            user.getUsername(),
            user.getPassword(),
            user.getAuthorities());
  }
}

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

  @Autowired
  private CustomUserDetailsService userDetailsService;

  @Override
  public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    String username = authentication.getName();
    String password = (String) authentication.getCredentials();

    UserDetails userDetails = userDetailsService.loadUserByUsername(username);
    if(!password.equals(userDetails.getPassword())) {
      throw new BadCredentialsException("密码不正确!");
    }

    return new UsernamePasswordAuthenticationToken(username, password, userDetails.getAuthorities());
  }

  @Override
  public boolean supports(Class<?> authentication) {
    return authentication.equals(UsernamePasswordAuthenticationToken.class);
  }
}

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Autowired
  private CustomAuthenticationProvider customAuthenticationProvider;

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(customAuthenticationProvider);
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
      .authorizeRequests()
        .anyRequest().authenticated()
        .and()
      .formLogin()
        .loginPage("/login")
        .successForwardUrl("/index")
        .permitAll()
        .and()
      .logout().permitAll();
  }
}

4.2 基于 MyBatis 的用户认证

@Repository
public interface UserMapper {

  @Select("select * from user where username = #{username}")
  User findByUsername(String username);
}

@Service
public class CustomUserDetailsService implements UserDetailsService {

  @Autowired
  private UserMapper userMapper;

  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    User user = userMapper.findByUsername(username);
    if(user == null) {
      throw new UsernameNotFoundException("用户名不存在!");
    }

    return new org.springframework.security.core.userdetails.User(
            user.getUsername(),
            user.getPassword(),
            user.getAuthorities());
  }
}

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

  @Autowired
  private CustomUserDetailsService userDetailsService;

  @Override
  public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    String username = authentication.getName();
    String password = (String) authentication.getCredentials();

    UserDetails userDetails = userDetailsService.loadUserByUsername(username);
    if(!password.equals(userDetails.getPassword())) {
      throw new BadCredentialsException("密码不正确!");
    }

    return new UsernamePasswordAuthenticationToken(username, password, userDetails.getAuthorities());
  }

  @Override
  public boolean supports(Class<?> authentication) {
    return authentication.equals(UsernamePasswordAuthenticationToken.class);
  }
}

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Autowired
  private CustomAuthenticationProvider customAuthenticationProvider;

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(customAuthenticationProvider);
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
      .authorizeRequests()
        .anyRequest().authenticated()
        .and()
      .formLogin()
        .loginPage("/login")
        .successForwardUrl("/index")
        .permitAll()
        .and()
      .logout().permitAll();
  }
}

以上就是 SpringSecurity 自定义表单登录的实现攻略及两个示例。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringSecurity 自定义表单登录的实现 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • Java超详细整理讲解各种排序

    Java超详细整理讲解各种排序 本文详细讲解了Java中各种排序算法的实现方式及其时间复杂度。本文内容包括以下几个部分: 排序算法分类 冒泡排序 插入排序 选择排序 归并排序 快速排序 堆排序 排序算法分类 Java中的排序算法可以按照时间复杂度从小到大分为以下三类: 时间复杂度为O(n^2)的算法:冒泡排序、插入排序、选择排序 时间复杂度为O(nlogn)…

    Java 2023年5月19日
    00
  • java实现文件拷贝的七种方式

    我来为你讲解“Java实现文件拷贝的七种方式”的攻略。以下是这七种方式: 1. 使用字节流(InputStream和OutputStream)进行拷贝 字节流是Java I/O中的基本类,可以方便地进行文件拷贝。我们可以使用 FileInputStream 读取源文件,将数据写入 FileOutputStream 中实现文件拷贝。具体代码如下: public…

    Java 2023年5月20日
    00
  • java解析出url请求的路径和参数键值对类(解析出url请求的路径,包括页面)

    下面是详细的攻略: 1. 确定需求和目标 在写代码之前,我们需要明确自己的目标和需求,即需要完成什么样的功能。根据题目的要求,我们需要编写一个Java类,该类可以解析出传入的URL请求的路径和参数键值对。 2. 解析路径和参数 在Java中,我们可以使用Java内置的类库中的java.net.URL和java.net.URLConnection类来获取URL…

    Java 2023年6月15日
    00
  • SpringBoot接入轻量级分布式日志框架(GrayLog)的操作方法

    Spring Boot接入轻量级分布式日志框架(GrayLog)的操作方法 GrayLog是一个轻量级的分布式日志框架,可以帮助我们收集、存储和分析应用程序的日志。在本文中,我们将详细讲解如何在Spring Boot应用程序中接入GrayLog。 步骤一:添加依赖 我们需要在pom.xml文件中添加以下依赖项: <dependency> <…

    Java 2023年5月15日
    00
  • Spring入门实战之Profile详解

    以下是 “Spring入门实战之Profile详解”的完整攻略: 什么是 Spring Profile Spring是一个非常流行的 JavaEE 框架,它提供了许多元数据、配置和依赖注入等功能,便于我们快速构建应用程序。Spring Profile 是 Spring 框架中一项非常有用的功能。它可以用于定义可重用的配置、属性文件、JavaBean、组件等,…

    Java 2023年5月19日
    00
  • 基于ajax实现文件上传并显示进度条

    下面是基于ajax实现文件上传并显示进度条的完整攻略: 1. 准备工作 在前端实现基于ajax的文件上传需要以下几个工具/库: FormData对象:用于创建一个表单数据对象,方便把文件和其他数据打包发送到服务器端。 XMLHttpRequest对象:用于创建异步请求,可以通过它向服务器端发送数据。 FileReader对象:用于读取本地文件并把它转换成ba…

    Java 2023年5月20日
    00
  • 利用SpringMVC和Ajax实现文件上传功能

    利用SpringMVC和Ajax实现文件上传功能 在 Web 应用程序中,文件上传功能是非常常见的需求。本文将详细讲解如何利用 SpringMVC 和 Ajax 实现文件上传功能,包括如何配置 SpringMVC、如何编写前端代码、如何编写后端代码等,并提供两个示例说明。 配置 SpringMVC 在 SpringMVC 中,我们需要配置 Multipart…

    Java 2023年5月18日
    00
  • SpringBoot security安全认证登录的实现方法

    以下是关于SpringBoot security安全认证登录的实现方法的完整攻略,包含详细步骤、示例和代码: SpringBoot security安全认证登录的实现方法 概述 在网站或应用程序中,用户登录是非常常见的一种操作。而用户登录操作需要进行安全认证,防止非法用户的登录,保障网站或应用的安全。SpringBoot提供了基于Spring Securit…

    Java 2023年6月3日
    00
合作推广
合作推广
分享本页
返回顶部