Spring Security实现用户名密码登录详解

下面是Spring Security实现用户名密码登录的详细攻略:

实现步骤

1. 添加Spring Security的Maven依赖

在项目的pom.xml文件中添加以下Maven依赖。

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

2. 配置Spring Security

在Spring Boot项目中,我们可以通过在application.properties或者application.yml配置文件中进行Spring Security的配置。

以下是一个示例的application.properties文件的配置:

# HTTP Basic 认证开关
spring.security.basic.enabled=true

# 配置用户名和密码
spring.security.user.name=admin
spring.security.user.password=admin123

以下是一个示例的application.yml文件的配置:

# HTTP Basic 认证开关
spring:
  security:
    basic:
      enabled: true

# 配置用户名和密码
spring:
  security:
    user:
      name: admin
      password: admin123

3. 添加验证页面

创建一个HTML页面(例如:login.html),添加用户名和密码输入框,并使用POST方法提交数据到/login接口。

以下是一个示例的login.html页面:

<!DOCTYPE html>
<html>
<head>
    <title>Login Page</title>
</head>
<body>
    <h1>Login Page</h1>

    <form method="post" action="/login">
        <label for="username">Username:</label>
        <input type="text" id="username" name="username" /><br /><br />

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

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

4. 自定义认证配置

创建一个类实现org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter接口,并重写configure(HttpSecurity http)方法。

以下是一个示例的WebSecurityConfigurer类的配置:

@Configuration
@EnableWebSecurity
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomUserDetailsService userDetailsService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/login").permitAll()
            .antMatchers("/admin").hasAuthority("ADMIN")
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .loginPage("/login")
            .defaultSuccessUrl("/home")
            .failureUrl("/login/error")
            .permitAll()
            .and()
            .logout()
            .permitAll();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
    }
}

5. 创建自定义用户类和密码加密器

创建一个实现org.springframework.security.core.userdetails.UserDetails接口的CustomUser类,表示我们自定义的用户类型,同时创建一个实现org.springframework.security.crypto.password.PasswordEncoder接口的PasswordEncoder类,用于对用户密码进行加密处理。

以下是一个示例的CustomUser类和PasswordEncoder类的代码:

public class CustomUser implements UserDetails {
    private String username;
    private String password;
    private List<GrantedAuthority> authorities;

    // 省略getter和setter,以及实现的UserDetails接口方法

    public CustomUser(String username, String password, String... roles) {
        this.username = username;
        this.password = password;
        List<GrantedAuthority> authorities = new ArrayList<>();
        for (String role : roles) {
            authorities.add(new SimpleGrantedAuthority(role));
        }
        this.authorities = authorities;
    }
}

public class PasswordEncoder implements org.springframework.security.crypto.password.PasswordEncoder {

    @Override
    public String encode(CharSequence charSequence) {
        return DigestUtils.sha256Hex(charSequence.toString());
    }

    @Override
    public boolean matches(CharSequence charSequence, String s) {
        return s.equals(encode(charSequence));
    }
}

6. 创建自定义用户服务类

创建一个实现org.springframework.security.core.userdetails.UserDetailsService接口的CustomUserDetailsService类,用于根据用户名查询用户信息。

以下是一个示例的CustomUserDetailsService类的代码:

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        // TODO: 从数据库中查询用户信息,并返回CustomUser对象
        CustomUser user = new CustomUser("admin", new PasswordEncoder().encode("admin123"), "ADMIN");
        return user;
    }
}

示例

示例一

配置文件

以下是示例一的application.yml文件的配置:

spring:
  security:
    basic:
      enabled: true

自定义认证配置

以下是示例一的WebSecurityConfigurer类的配置:

@Configuration
@EnableWebSecurity
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
    }
}

控制器

以下是示例一的控制器类的代码:

@RestController
public class TestController {

    @GetMapping("/")
    public String index() {
        return "Hello World";
    }

    @GetMapping("/admin")
    public String admin() {
        return "Hello Admin";
    }
}

示例说明

在示例一中,我们启用了HTTP Basic 认证,使用浏览器访问应用时,会弹出用户名和密码输入框,输入正确的用户名和密码后才能访问应用中的资源。

访问根路径(/)时,会提示输入用户名和密码。输入正确的用户名(admin)和密码(admin123)后,会看到页面上显示“Hello World”。

访问/admin时,同样需要输入用户名和密码,成功认证后,显示“Hello Admin”。

示例二

控制器

以下是示例二的控制器类的代码:

@RestController
public class TestController {

    @GetMapping("/")
    public String index() {
        return "Hello World";
    }

    @GetMapping("/login")
    public ModelAndView login(ModelAndView modelAndView) {
        modelAndView.setViewName("login");
        return modelAndView;
    }

    @GetMapping("/home")
    public String home() {
        return "Hello Home";
    }

    @GetMapping("/admin")
    public String admin() {
        return "Hello Admin";
    }

    @GetMapping("/login/error")
    public ModelAndView loginError(ModelAndView modelAndView) {
        modelAndView.addObject("error", true);
        modelAndView.setViewName("login");
        return modelAndView;
    }
}

配置文件

以下是示例二的application.yml文件的配置:

spring:
  security:
    basic:
      enabled: false
  thymeleaf:
    cache: false

自定义认证配置

以下是示例二的WebSecurityConfigurer类的配置:

@Configuration
@EnableWebSecurity
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomUserDetailsService userDetailsService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/login").permitAll()
            .antMatchers("/admin").hasAuthority("ADMIN")
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .loginPage("/login")
            .defaultSuccessUrl("/home")
            .failureUrl("/login/error")
            .permitAll()
            .and()
            .logout()
            .permitAll();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
    }
}

自定义用户类和密码加密器

以下是示例二的CustomUser类和PasswordEncoder类的代码:

public class CustomUser implements UserDetails {
    private String username;
    private String password;
    private List<GrantedAuthority> authorities;

    // 省略getter和setter,以及实现的UserDetails接口方法

    public CustomUser(String username, String password, String... roles) {
        this.username = username;
        this.password = password;
        List<GrantedAuthority> authorities = new ArrayList<>();
        for (String role : roles) {
            authorities.add(new SimpleGrantedAuthority(role));
        }
        this.authorities = authorities;
    }
}

public class PasswordEncoder implements org.springframework.security.crypto.password.PasswordEncoder {

    @Override
    public String encode(CharSequence charSequence) {
        return DigestUtils.sha256Hex(charSequence.toString());
    }

    @Override
    public boolean matches(CharSequence charSequence, String s) {
        return s.equals(encode(charSequence));
    }
}

自定义用户服务类

以下是示例二的CustomUserDetailsService类的代码:

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        // TODO: 从数据库中查询用户信息,并返回CustomUser对象
        CustomUser user = new CustomUser("admin", new PasswordEncoder().encode("admin123"), "ADMIN");
        return user;
    }
}

静态资源和模板文件

创建一个login.html的模板文件,用于显示登录页面。

以下是一个示例的login.html文件的内容:

<!DOCTYPE html>
<html>
<head>
    <title>Login Page</title>
</head>
<body>
    <h1>Login Page</h1>

    <div th:if="${param.error}">
        Invalid username or password.
    </div>

    <form method="post" action="/login">
        <label for="username">Username:</label>
        <input type="text" id="username" name="username" /><br /><br />

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

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

创建一个static文件夹,并在其中创建一个图片文件(例如:logo.png)。

示例说明

在示例二中,我们关闭了HTTP Basic 认证,启用了表单登录认证。访问根路径(/)时,会自动跳转到/login接口,展示登录页面(login.html)。

输入正确的用户名(admin)和密码(admin123)后,会自动跳转到/home页面,并显示“Hello Home”。

访问/admin时,因为没有该用户的角色授权,会跳转到/error页面。

如果账号或密码不正确,会跳转回登录页面,并提示“Invalid username or password.”。

示例二还演示了如何设置静态资源文件,以及如何解析模板文件。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Security实现用户名密码登录详解 - Python技术站

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

相关文章

  • Java模拟实现一个基于文本界面的《记账软件》

    /**@author: Noiimplant*@version: 1.0*/ 1. 利用java实现简易记账软件 根据尚硅谷java教程进行练习 2. 实现功能 记录家庭支出、收入,打印收支明细表 使用分级菜单的方式 3. 代码实现 3.1 GuliAccount.java package GuliAccount; import java.text.Simp…

    Java 2023年4月27日
    00
  • 详解Lombok快速上手(安装、使用与注解参数)

    详解 Lombok 快速上手 Lombok 是一个 Java 库,可以在编码时自动生成样板代码,以减少 Java 项目中冗长的样板代码量。 安装 Lombok 安装 Lombok 很简单。只需要在项目依赖中加入 Lombok,就能让 Lombok 自动为你生成样板代码。 下面是 Maven 和 Gradle 的配置: Maven <dependency…

    Java 2023年6月1日
    00
  • 微信小程序实现电子签名并导出图片

    下面我将详细讲解如何实现微信小程序实现电子签名并导出图片的完整攻略。 前置知识 在开始之前,需要了解一些前置知识: HTML5 canvas CanvasRenderingContext2D 微信小程序 file API 实现步骤 步骤一:创建 canvas 元素 在小程序的 WXML 文件中,创建一个 canvas 元素: <canvas id=&q…

    Java 2023年5月23日
    00
  • Java分布式锁的三种实现方案

    让我来详细讲解“Java分布式锁的三种实现方案”的完整攻略。 什么是分布式锁? 分布式锁是控制分布式系统之间同步访问共享资源的一种方式。在分布式系统中,多个节点会竞争同一个锁,这个锁可以是基于数据库或者基于缓存等其他方式实现的。 Java分布式锁的三种实现方案 基于数据库的分布式锁 这种锁的实现方式比较简单,通过数据库的行锁来实现分布式锁,通过insert或…

    Java 2023年5月26日
    00
  • Java 异常机制Exception和自定义异常

    Java 异常机制是 Java 中非常重要的一部分,异常机制可以帮助我们区分代码执行过程中出现的不正常情况,而不是简单的让代码继续执行下去。在 Java 中异常机制主要分为 Throwable、Error 和 Exception 三个类别,其中 Throwable 是异常的父类,Error 和 Exception 继承自 Throwable 类,其中 Err…

    Java 2023年5月27日
    00
  • SpringMVC中使用Thymeleaf模板引擎实例代码

    下面是关于SpringMVC中使用Thymeleaf模板引擎的完整攻略,包含两个示例说明。 SpringMVC中使用Thymeleaf模板引擎实例代码 Thymeleaf是一个流行的模板引擎,它可以与SpringMVC框架无缝集成。在本文中,我们将介绍如何在SpringMVC中使用Thymeleaf模板引擎。 步骤1:添加依赖 首先,我们需要在pom.xml…

    Java 2023年5月17日
    00
  • Java Web项目中连接Access数据库的配置方法

    下面我将为你详细讲解Java Web项目中连接Access数据库的配置方法。首先我们需要了解几个基本概念。 一、基本概念 在开始配置连接Access数据库之前,我们需要了解以下几个基本概念: ODBC:ODBC(Open Database Connectivity)是Microsoft提供的开放式数据库连接接口,它可以使不同的应用程序连接到不同的数据库。 J…

    Java 2023年5月20日
    00
  • 获取Java的MyBatis框架项目中的SqlSession的方法

    获取Java的MyBatis框架项目中的SqlSession对象的方法,可以从以下几个方面进行介绍。 方法一:通过MyBatis提供的SqlSessionFactory创建SqlSession对象 首先,在Java的MyBatis框架项目中,需要首先通过MyBatis提供的SqlSessionFactory创建SqlSession对象。可以通过以下步骤实现:…

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