SpringBoot整合SpringSecurity

SpringBoot整合SpringSecurity

<dependency>
    <groupId>org.mybatis.spring.bootgroupId>
    <artifactId>mybatis-spring-boot-starterartifactId>
     <version>2.3.1version>
dependency>
<dependency>
    <groupId>mysqlgroupId>
    <artifactId>mysql-connector-javaartifactId>
dependency>

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-actuatorartifactId>
dependency>

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-webartifactId>
dependency>


<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starterartifactId>
dependency>


<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-testartifactId>
    <scope>testscope>
dependency>

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-thymeleafartifactId>
dependency>

sql

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    password VARCHAR(255) NOT NULL
);

Users.java

package com.sin.pojo;

/**
 * @createTime 2023/10/26 9:02
 * @createAuthor SIN
 * @use
 */

public class Users {
    private Integer id;
    private String username;
    private String password;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

UsersMapper.java

package com.sin.mapper;

import com.sin.pojo.Users;
import org.apache.ibatis.annotations.Mapper;

/**
 * @createTime 2023/10/26 9:03
 * @createAuthor SIN
 * @use
 */
@Mapper
public interface UsersMapper {

    /**
     * 添加数据
     * @param user 
     */
    void insertUser(Users user);

    /**
     * 根据username查询数据
     * @param username
     * @return
     */
    Users findByUsername(String username);
}

UsersMapper.xml


DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sin.mapper.UsersMapper">
      
    <insert id="insertUser" parameterType="com.sin.pojo.Users">
        INSERT INTO users (username, password) VALUES (#{username}, #{password})
    insert>
    
	
    <select id="findByUsername" parameterType="String" resultType="com.sin.pojo.Users">
        SELECT * FROM users WHERE username = #{username}
    select>

mapper>

UsersService.java

package com.sin.service;

import com.sin.pojo.Users;

/**
 * @createTime 2023/10/26 9:05
 * @createAuthor SIN
 * @use
 */
public interface UsersService {

    /**
     * 用户注册注册
     * @param user
     */
    void registerUser(Users user);

    /**
     * 用户登录
     * @param username
     * @param password
     * @return
     */
    boolean loginUser(String username, String password);
}

UsersServiceImpl.java

package com.sin.service.impl;

import com.sin.mapper.UsersMapper;
import com.sin.pojo.Users;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @createTime 2023/10/26 9:06
 * @createAuthor SIN
 * @use
 */
@Service
public class UsersServiceImpl implements com.sin.service.UsersService {
    @Autowired
    private UsersMapper usersMapper;

    /**
     * 注册
     * @param users
     */
    @Override
    public void registerUser(Users users) {
        usersMapper.insertUser(users);
    }

    /**
     * 登录
     * @param username
     * @param password
     * @return
     */
    @Override
    public boolean loginUser(String username, String password) {
        Users user = usersMapper.findByUsername(username);
        return user != null && user.getPassword().equals(password);
    }
}

UsersController.java

package com.sin.controller;

import com.sin.pojo.Users;
import com.sin.service.UserService;
import com.sin.service.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * @createTime 2023/10/26 9:08
 * @createAuthor SIN
 * @use
 */
@Controller
public class UsersController {
    @Autowired
    private UsersService usersService;

    @GetMapping("/register1")
    public String showRegistrationForm(Model model) {
        model.addAttribute("user", new Users());
        return "register1";
    }

    @PostMapping("/register1")
    public String registerUser(@ModelAttribute("user") @Validated Users user, BindingResult result) {
        if (result.hasErrors()) {
            return "register1";
        }

        usersService.registerUser(user);
        return "redirect:/login";
    }

    @GetMapping("/login")
    public String showLoginForm() {
        return "login";
    }

   @PostMapping("/login")
    public String loginUser(@RequestParam("username") String username, @RequestParam("password") String password) {
        boolean isValid = usersService.loginUser(username, password);
        // 登录成功后返回到/dashboard页面
        if (isValid) {
            return "redirect:/dashboard";
        } else {  // 登录失败返回该页面
            return "login";
        }
    }
}

register1.html

DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Registrationtitle>
head>
<body>
<h1>Registrationh1>
<form th:action="@{/register1}" th:object="${user}" method="post">
    <div>
        <label>Username:label>
        <input type="text" th:field="*{username}" required />
    div>
    <div>
        <label>Password:label>
        <input type="password" th:field="*{password}" required />
    div>
    <button type="submit">Registerbutton>
form>
body>
html>

login.html

DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Logintitle>
head>
<body>
<h1>Loginh1>
<form th:action="@{/login}" method="post">
    <div>
        <label>Username:label>
        <input type="text" name="username" required />
    div>
    <div>
        <label>Password:label>
        <input type="password" name="password" required />
    div>
    <button type="submit">Loginbutton>
form>
body>
html>

拦截功能

加入SpringSecurity

pom.xml


<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-securityartifactId>
dependency>

UserDetailsServiceImpl.java

package com.sin.service.impl;

import com.sin.mapper.UserMapper;
import com.sin.mapper.UsersMapper;
import com.sin.pojo.Users;
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;

import java.util.ArrayList;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {
  @Autowired
  private UsersMapper usersMapper;

    /**
    * 根据用户名加载用户信息
    */
  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
      // 通过用户名从数据库中查询用户信息
    Users user = usersMapper.findByUsername(username);
      // 如果用户不存在,抛出异常
    if (user == null) {
      throw new UsernameNotFoundException("用户不存在");
    }
      // 创建并返回一个SpringSecurity的UserDetails对象用于身份验证和授权
    return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), new ArrayList<>());
  }
}

SecurityConfig.java

package com.sin.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @createTime 2023/10/26 10:00
 * @createAuthor SIN
 * @use
 */
@Configuration // 表示这是这是一个配置类
@EnableWebSecurity // 启用web安全功能
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;

    /**
    * 配置请求授权规则和相关的登录, 登出设置
    */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests() // 配置请求授权规则
                .antMatchers("/register1", "/login").permitAll() // 允许不需要认证即可访问的URL路径
                .anyRequest().authenticated()// 其他所有请求都需要进行身份认证
                .and()
                .formLogin() // 配置表单登录相关设置
                .loginPage("/login") // 自定义登录页面的URL路径
                .defaultSuccessUrl("/dashboard") // 登录成功后的默认跳转的页面
                .permitAll() // 允许所有用户访问登录页面
                .and() 
                .logout() // 配置登出相关设置
                .permitAll(); // 允许所有用户访问登录url路径
    }

    /**
    * 配置身份认证方式
    */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 配置自定义的userDetailsService实例,用户处理身份认证
        auth.userDetailsService(userDetailsService); 
    }

    
    @Bean
    public PasswordEncoder passwordEncoder() {
        // 返回BCryptPasswordEncoder实例,用于对密码进行加密和验证
        return new BCryptPasswordEncoder();
    }
}

UsersController.java

  @Autowired
    private PasswordEncoder passwordEncoder;



@PostMapping("/register1")
public String registerUser(@ModelAttribute("user") @Validated Users user, BindingResult result) {
    if (result.hasErrors()) {
        return "register1";
    }
    String encodedPassword = passwordEncoder.encode(user.getPassword());
    user.setPassword(encodedPassword);

    usersService.registerUser(user);
    return "redirect:/login";
}

权限功能

sql

表中添加字段

alter table users add authority varchar(20) character set utf8mb4 default 'USER' comment '用户权限';

User.java

public class Users {
    private Integer id;
    private String username;
    private String password;

    private String authority;

UserMapper.xml

<insert id="insertUser" parameterType="com.sin.pojo.Users">
    INSERT INTO users (username, password,authority) VALUES (#{username}, #{password},#{authority})
insert>

UserDetailsServiceImpl.java

package com.sin.service.impl;

import com.sin.mapper.UserMapper;
import com.sin.mapper.UsersMapper;
import com.sin.pojo.Users;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
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;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {
  @Autowired
  private UsersMapper usersMapper;
    /**
    * 根据用户名加载用户信息
    */
  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
      // 通过用户名从数据库中查询用户信息
    Users user = usersMapper.findByUsername(username);
      // 如果用户不存在,抛出异常
    if (user == null) {
      throw new UsernameNotFoundException("用户不存在");
    }

      // 存储用户的权限信息
    List<GrantedAuthority> authorities = new ArrayList<>();
      // 将用户的权限信息添加到列表中,
      // SimpleGrantedAuthority类表示用户的权限,
    authorities.add(new SimpleGrantedAuthority(user.getAuthority()));

    return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), authorities);

  }
}

SecurityConfig.java

/**
* 配置HTTP请求的安全性
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests() // 对请求进行授权的配置
            .antMatchers("/register1", "/login").permitAll() // 所有用户都可以访问
            .antMatchers("/**").hasAuthority("ADMIN")// 该路径具有ADMIN权限才能访问
            .anyRequest().authenticated()// 其他的路径需要进行身份认证
            .and() // 连接多个授权规则
            .formLogin() // 授权表单的相关设置
            .loginPage("/login") // 自定义的登录页面路径为/login
            .defaultSuccessUrl("/dashboard") // 登录成功后跳转的路径
            .permitAll() // 登录页面和登录请求路径都允许所有用户访问,即不需要进行身份验证
            .and() 
            .logout() // 配置登出的相关操作
            .permitAll(); // 登出请求路径允许所有用户访问,即不需要进行身份验证
}

register1.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Registration</title>
</head>
<body>
<h1>Registration</h1>
<form th:action="@{/register1}" th:object="${user}" method="post">
    <div>
        <label>Username:</label>
        <input type="text" th:field="*{username}" required />
    </div>
    <div>
        <label>Password:</label>
        <input type="password" th:field="*{password}" required />
    </div>
    <div>
        <label>authoritie:</label>
        <input type="text" th:field="*{authority}" required />
    </div>
    <button type="submit">Register</button>
</form>
</body>
</html>

你可能感兴趣的:(spring,boot,后端,java)