写点什么

从零开始学 Spring Boot 系列 - 集成 Spring Security 实现用户认证与授权

  • 2024-07-01
    福建
  • 本文字数:5172 字

    阅读完需:约 17 分钟

在 Web 应用程序中,安全性是一个至关重要的方面。Spring Security 是 Spring 框架的一个子项目,用于提供安全访问控制的功能。通过集成 Spring Security,我们可以轻松实现用户认证、授权、加密、会话管理等安全功能。本篇文章将指导大家从零开始,在 Spring Boot 项目中集成 Spring Security,并通过 MyBatis-Plus 从数据库中获取用户信息,实现用户认证与授权。


环境准备


在开始之前,请确保你的开发环境已经安装了 Java、Gradle 和 IDE(如 IntelliJ IDEA 或 Eclipse)。同时,你也需要在项目中引入 Spring Boot、Spring Security、MyBatis-Plus 以及数据库的依赖。


创建 Spring Boot 项目


首先,我们需要创建一个 Spring Boot 项目。可以使用 Spring Initializr(https://start.spring.io/)来快速生成项目结构。在生成项目时,选择所需的依赖,如 Web、Thymeleaf(或 JSP)、Spring Security 等。


添加 Spring Security 依赖


在项目的 pom.xml(Maven)或 build.gradle(Gradle)文件中,添加 Spring Security 的依赖。对于 Gradle,添加以下依赖:

group = 'cn.daimajiangxin'version = '0.0.1-SNAPSHOT'description ='Spring Security'dependencies {    implementation 'org.springframework.boot:spring-boot-starter-web'    compileOnly 'org.projectlombok:lombok'    annotationProcessor 'org.projectlombok:lombok'    runtimeOnly 'mysql:mysql-connector-java:8.0.17'    // MyBatis-Plus 依赖    implementation 'com.baomidou:mybatis-plus-spring-boot3-starter:3.5.5'    implementation 'org.springframework.boot:spring-boot-starter-security'    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'}
复制代码


对于 Maven,添加以下依赖:

<dependency>      <groupId>org.springframework.boot</groupId>      <artifactId>spring-boot-starter-security</artifactId>  </dependency>
复制代码


创建实体类


创建一个简单的实体类,映射到数据库表。

package cn.daimajiangxin.springboot.learning.model;
import com.baomidou.mybatisplus.annotation.IdType;import com.baomidou.mybatisplus.annotation.TableField;import com.baomidou.mybatisplus.annotation.TableId;import com.baomidou.mybatisplus.annotation.TableName;import lombok.Data;
import java.io.Serializable;
@TableName(value ="user")@Datapublic class User implements Serializable { /** * 学生ID */ @TableId(type = IdType.AUTO) private Long id;
/** * 姓名 */ private String name; @TableField(value="user_name") private String userName;
private String password;
/** * 邮箱 */ private String email;
/** * 年龄 */ private Integer age;
/** * 备注 */ private String remark;


@TableField(exist = false) private static final long serialVersionUID = 1L;}
复制代码


创建 Mapper 接口


创建对应的 Mapper 接口,通常放在与实体类相同的包下,并继承 BaseMapper 接口。例如:

package cn.daimajiangxin.springboot.learning.mapper;
import cn.daimajiangxin.springboot.learning.model.User;import com.baomidou.mybatisplus.core.mapper.BaseMapper;public interface UserMapper extends BaseMapper<User> {
}
复制代码


创建 Mapper XML 文件


在 resources 的 mapper 目录下创建对应的 XML 文件,例如 UserMapper.xml:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"        "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="cn.daimajiangxin.springboot.learning.mapper.UserMapper">
<resultMap id="BaseResultMap" type="cn.daimajiangxin.springboot.learning.model.User"> <id property="id" column="id" jdbcType="BIGINT"/> <result property="name" column="name" jdbcType="VARCHAR"/> <result property="user_name" column="userName" jdbcType="VARCHAR"/> <result property="password" column="password" jdbcType="VARCHAR"/> <result property="email" column="email" jdbcType="VARCHAR"/> <result property="age" column="age" jdbcType="INTEGER"/> <result property="remark" column="remark" jdbcType="VARCHAR"/> </resultMap>
<sql id="Base_Column_List"> id,name,email,age,remark </sql> <select id="findAllUsers" resultMap="BaseResultMap"> select <include refid="Base_Column_List"></include> from user </select></mapper>
复制代码


创建 Service 接口


在 service 目录下服务类接口 UserService

package cn.daimajiangxin.springboot.learning.service;
import cn.daimajiangxin.springboot.learning.model.User;import com.baomidou.mybatisplus.extension.service.IService;
public interface UserService extends IService<User> {
}
复制代码


创建 Service 实现类


在 service 目录下创建一个 impl 目录,并创建 UserService 实现类 UserServiceImpl

package cn.daimajiangxin.springboot.learning.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;import cn.daimajiangxin.springboot.learning.model.User;import cn.daimajiangxin.springboot.learning.service.UserService;import cn.daimajiangxin.springboot.learning.mapper.UserMapper;import org.springframework.stereotype.Service;@Servicepublic class UserServiceImpl extends ServiceImpl<UserMapper, User>implements UserService{
}
复制代码


创建 UserDetailsService 实现类

package cn.daimajiangxin.springboot.learning.service.impl;
import cn.daimajiangxin.springboot.learning.model.User;import cn.daimajiangxin.springboot.learning.service.UserService;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;import jakarta.annotation.Resource;import org.springframework.security.core.GrantedAuthority;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;
import java.util.ArrayList;import java.util.List;
@Servicepublic class UserDetailServiceImpl implements UserDetailsService { @Resource private UserService userService; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { LambdaQueryWrapper<User> queryWrapper=new LambdaQueryWrapper<User>(); queryWrapper.eq(User::getUserName,username); User user=userService.getOne(queryWrapper); List<GrantedAuthority> authorities = new ArrayList<>(); return new org.springframework.security.core.userdetails.User(user.getName(), user.getPassword(),authorities ); }}
复制代码


Java 配置类


创建一个配置类,并创建 SecurityFilterChain 的 Bean。

package cn.daimajiangxin.springboot.learning.config;
import jakarta.annotation.Resource;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.crypto.password.PasswordEncoder;import org.springframework.security.crypto.password.StandardPasswordEncoder;import org.springframework.security.web.SecurityFilterChain;
@Configuration@EnableWebSecuritypublic class SecurityConfig { @Resource private UserDetailsService userDetailsService; @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(authorizeRequests -> authorizeRequests .requestMatchers("/", "/home") .permitAll() .anyRequest().authenticated() // 其他所有请求都需要认证 ) .formLogin(formLogin -> formLogin .loginPage("/login") // 指定登录页面 .permitAll() // 允许所有人访问登录页面 ) .logout(logout -> logout .permitAll() // 允许所有人访问注销URL ) // 注册重写后的UserDetailsService实现 .userDetailsService(userDetailsService); return http.build(); // 添加自定义过滤器或其他配置 }
@Bean public PasswordEncoder passwordEncoder() { return new StandardPasswordEncoder(); }}
复制代码


创建登录页面


在 src/main/resources/templates 目录下创建一个 Thymeleaf 模板作为登录页面,例如 login.html。

<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org"><head>    <title>登录</title></head><body><form th:action="@{/doLogin}" method="post">    <div><label> User Name : <input type="text" name="username"/> </label></div>    <div><label> Password: <input type="password" name="password"/> </label></div>    <div><input type="submit" value="登录"/></div></form></body></html>
复制代码


创建控制器


创建一个 UserController,

package cn.daimajiangxin.springboot.learning.controller;
import cn.daimajiangxin.springboot.learning.model.User;import cn.daimajiangxin.springboot.learning.service.UserService;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.servlet.ModelAndView;
import java.util.List;
@RestControllerpublic class UserController { private final UserService userService;
@Autowired public UserController(UserService userService) { this.userService = userService; }
@GetMapping({"/login",}) public ModelAndView login(Model model) { ModelAndView mv = new ModelAndView("login"); return mv ; } @PostMapping("/doLogin") public String doLogin(@RequestParam String username,@RequestParam String password) { QueryWrapper<User> queryWrapper=new QueryWrapper<>(); queryWrapper.eq("user_name",username); User user= userService.getOne(queryWrapper); if(user==null){ return "登录失败,用户没有找到"; } if(! user.getPassword().equals(password)){ return "登录失败,密码错误"; } return "登录成功"; }
}
复制代码


登录页面


运行你的 Spring Boot 应用程序,用浏览器访问http://localhost:8080/login.



文章转载自:代码匠心

原文链接:https://www.cnblogs.com/daimajiangxin/p/18274933

体验地址:http://www.jnpfsoft.com/?from=infoq

用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
从零开始学Spring Boot系列-集成Spring Security实现用户认证与授权_spring_快乐非自愿限量之名_InfoQ写作社区