Spring Security 6 基于数据库实现登录认证

在现代 web 应用程序中,安全性是必须要考虑的问题。Spring Security 提供了一套强大的认证和授权框架,允许我们轻松实现基于数据库的登录认证。本文将介绍如何使用 Spring Security 6 和 JPA 实现用户的登录认证。

项目结构

我们将基于 Spring Boot 创建一个简单的 Spring Security 项目,项目结构如下:

src/main/java/com/example/security/
    ├── SecurityApplication.java
    ├── config/
    │   └── SecurityConfig.java
    ├── controller/
    │   └── LoginController.java
    ├── entity/
    │   └── User.java
    ├── repository/
    │   └── UserRepository.java
    └── service/
        └── UserDetailsServiceImpl.java

1. 添加依赖

pom.xml 文件中添加 Spring Security 和 JPA 的依赖:

<dependencies>
    <!-- Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <!-- Spring Security -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <!-- Spring Data JPA -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <!-- H2 数据库(用于开发和测试) -->
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
    <!-- 其他依赖 -->
</dependencies>

2. 创建实体类

我们创建一个简单的 User 实体类,表示用户信息。

package com.example.security.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String password;

    // getters and setters
}

3. 创建 JPA Repository

接下来,我们创建一个 UserRepository 接口,用于操作数据库中的用户信息。

package com.example.security.repository;

import com.example.security.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {
    User findByUsername(String username);
}

4. 实现 UserDetailsService

实现 UserDetailsService 接口,加载用户的详细信息。

package com.example.security.service;

import com.example.security.entity.User;
import com.example.security.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

@Service
public class UserDetailsServiceImpl 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("User not found");
        }
        return org.springframework.security.core.userdetails.User.withUsername(user.getUsername())
                .password(user.getPassword())
                .roles("USER") // 默认角色
                .build();
    }
}

5. 配置 Spring Security

SecurityConfig 中配置 Spring Security 的基本设置。

package com.example.security.config;

import com.example.security.service.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

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

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

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

6. 创建登录控制器

创建一个控制器来处理登录请求:

package com.example.security.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class LoginController {

    @GetMapping("/login")
    public String login() {
        return "login"; // 返回登录页面视图
    }
}

7. 创建登录页面

最后,我们需要创建一个简单的登录页面 login.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Login</title>
</head>
<body>
    <form action="/login" method="post">
        <div>
            <label for="username">用户名:</label>
            <input type="text" id="username" name="username"/>
        </div>
        <div>
            <label for="password">密码:</label>
            <input type="password" id="password" name="password"/>
        </div>
        <div>
            <button type="submit">登录</button>
        </div>
    </form>
</body>
</html>

总结

至此,我们使用 Spring Security 6 实现了基于数据库的用户登录认证。在实际应用中,我们需要确保用户的密码是加密存储的,并且可以在注册时对密码进行加密。

这种实现方式具有一定的灵活性,可以根据需求拓展更多功能,例如角色权限控制、记住我功能等。希望本文能对您使用 Spring Security 提供一些帮助和启发!

点赞(0) 打赏

微信小程序

微信扫一扫体验

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部