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日

相关文章

  • 基于IDEA部署Tomcat服务器的步骤详解

    基于IDEA部署Tomcat服务器的步骤详解 一、安装Tomcat服务器 在官方网站下载Tomcat服务器,选择 .zip 格式的压缩包进行下载。 解压缩下载的压缩包到本地的某个目录下。例如:D:\apache-tomcat-8.5.61 配置环境变量。在系统环境变量中添加 CATALINA_HOME 变量,变量值为 Tomcat 的路径。例如:D:\apa…

    Java 2023年6月16日
    00
  • 一个简单的SpringBoot项目快速搭建详细步骤

    下面是一个简单的Spring Boot项目快速搭建的详细步骤: 1. 创建项目 创建新的Maven项目,使用Spring Boot Initializer或直接通过IDEA、Eclipse等集成开发工具来创建一个空的Maven项目。在创建过程中,可以选择使用哪些依赖项作为项目的基础。Spring Boot Initializer会提供一些预置了基础配置的项目…

    Java 2023年5月15日
    00
  • Java中数组的创建与传参方法(学习小结)

    下面我将详细讲解“Java中数组的创建与传参方法(学习小结)”的完整攻略。 一、Java中数组的创建 Java中数组是一组同类型数据元素的集合。数组中的每个元素可以通过索引来访问,索引从0开始,到数组长度减1为止。 1.1 声明数组 声明数组需要指定数组的类型和数组名。语法格式如下: type[] arrayName; 例如,声明一个整型数组 variabl…

    Java 2023年5月26日
    00
  • 深入讲解spring boot中servlet的启动过程与原理

    深入讲解SpringBoot中Servlet的启动过程与原理 在SpringBoot中,Servlet是一种常见的Web组件,用于处理HTTP请求和响应。本文将深入讲解SpringBoot中Servlet的启动过程与原理。 1. Servlet的启动过程 在SpringBoot中,Servlet的启动过程可以分为以下几个步骤: SpringBoot启动时,会…

    Java 2023年5月15日
    00
  • Java NIO 文件通道 FileChannel 用法及原理

    Java NIO 文件通道 FileChannel 用法及原理 简介 Java NIO(New Input/Output)是JDK 1.4中引入的新API,用于提高I/O操作的效率。其中有一项非常重要的特性——FileChannel,它提供了一种负责读取、写入、映射和操作文件的NIO接口。 FileChannel的主要功能包括:- 文件的读写操作- 文件的内…

    Java 2023年5月20日
    00
  • java如何获取本地操作系统进程列表

    获取本地操作系统进程列表可以使用Java自带的管理类java.lang.management.ManagementFactory和java.lang.management.RuntimeMXBean。 首先,我们需要通过ManagementFactory类的getRuntimeMXBean()方法获得当前运行时的RuntimeMXBean对象,然后即可调用该…

    Java 2023年5月24日
    00
  • Springboot+hibernate实现简单的增删改查示例

    现在我将详细讲解如何用Springboot和Hibernate实现一个简单的增删改查示例,示例将包括两个部分。 简介 Springboot是一个开源的Java开发框架,可以帮助开发者快速构建高效、可扩展的web应用程序。而Hibernate则是一个Java持久化框架,通过ORM(对象关系映射)的方式来实现对象和关系数据之间的映射。通过结合使用Springbo…

    Java 2023年5月19日
    00
  • 30基于java的酒店管理系统设计与实现

    本章节给给大家介绍一个简单的基于java的酒店管理系统设计与实现。 系统概要 以往的酒店管理系统相关信息管理,都是工作人员手工统计。这种方式不但时效性低,而且需要查找和变更的时候很不方便。随着科学的进步,技术的成熟,计算机信息化也日新月异的发展,如今计算机已经进入了人类社会发展的各个领域,并且发挥着十分重要的作用。本系统充分利用网络的便捷,在工作效率上,得到…

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