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调用回调机制详解

    Java调用回调机制详解 回调机制是一种常见的编程技术,在Java编程中也得到了广泛应用。由于Java是面向对象的编程语言,因此回调机制在Java中也是以对象的方式实现的。 什么是回调机制? 简单来说,回调机制就是在完成某个操作后,由被调用者主动调用调用者的方法,执行一定的操作。在Java中,回调机制通常采用接口回调的形式实现。 在接口回调中,被调用者会提供…

    Java 2023年5月26日
    00
  • 使用java的Calendar对象获得当前日期

    要使用Java的Calendar对象获得当前日期,有以下几个步骤: 1. 创建一个Calendar对象 需要导入java.util.Calendar类,创建Calendar对象,可以使用Calendar类中提供的静态方法getInstance()来获取当前时间的Calendar对象。 import java.util.Calendar; Calendar c…

    Java 2023年5月20日
    00
  • SpringBoot实现单元测试示例详解

    下面是关于SpringBoot实现单元测试示例的完整攻略,包含以下内容: 什么是单元测试 单元测试是指对程序中的最小可测试单元进行检查和验证。通俗的说,就是开发者编写的最小代码块的测试。它不关心整个系统、业务流程的正确性,而是只关注当前方法、类等代码片段的有效性和正确性。 单元测试的优点包括: 提高代码的质量和稳定性:及时发现和修复问题,减少后期维护成本 提…

    Java 2023年5月19日
    00
  • 全面解析java final关键字

    全面解析java final关键字 1. 什么是final关键字 final是Java语言中的一个关键字,它可以用来修饰变量、方法和类,表示该变量、方法或类只能被赋值一次或者在声明时被初始化一次,并不能再被修改或继承。final关键字有时被称为“不可变量”、“常量”、“最终变量”等。 2. final变量 final变量表示的是一旦被初始化,就不能再修改该变…

    Java 2023年5月26日
    00
  • Spring Boot整合Kafka教程详解

    下面我来为你详细讲解“Spring Boot整合Kafka教程详解”的完整攻略。 Spring Boot整合Kafka教程详解 什么是Kafka Kafka是一个由Apache软件基金会开发的开源,分布式的发布/订阅系统。它具有高吞吐量、强大的可扩展性和容错性,并且可以处理大量的实时数据。此外,Kafka还提供了多种客户端API,可以用来发送和接收消息。 S…

    Java 2023年5月20日
    00
  • SpringBoot SpringEL表达式的使用

    SpringEL表达式的使用攻略 1. SpringEL表达式的概述 Spring Expression Language(简称Spring EL)是一种表达式语言,用于在Spring应用程序中访问和操作对象图。它支持在运行时查询和操作对象图。 在Spring Boot应用程序中,可以使用Spring EL表达式来配置应用程序的各种组件,如依赖注入、AOP等…

    Java 2023年6月15日
    00
  • 通过button将form表单的数据提交到action层的实例

    下面是完整攻略及两条示例说明: 1. 创建表单 在html页面中使用form标签创建表单,指定表单的action属性为目标页面的url,同时指定表单的method属性为post或get。 示例代码: <form action="/submit" method="post"> <input type=&…

    Java 2023年6月15日
    00
  • 详解使用Spring Security进行自动登录验证

    使用Spring Security进行自动登录验证可以分为以下几个步骤: 1、添加Spring Security依赖 在pom.xml文件中添加以下依赖: <dependency> <groupId>org.springframework.security</groupId> <artifactId>sprin…

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