springboot 3.1.2 + springsecurity 6.1.2 基于数据库登录演示

引言

好久没有创建项目了,spring更新的也太快了,不做不知道,有一些常用的方法都被弃用了,这里就做个简单的演示把。
主要还是springSecurity配置文件这块比较重要。
文档:
官方文档
中文文档

创建项目

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>top.zunmx</groupId>
    <artifactId>CSM</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>CSM</name>
    <description>CSM</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>3.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.9</version>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

springSecurity配置文件

package top.zunmx.csm.configure;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
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.configurers.AbstractHttpConfigurer;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

import static org.springframework.security.config.Customizer.withDefaults;

@Configuration
@EnableWebSecurity
public class SecurityConfiguration {

    @Autowired
    private UserDetailsService userDetailsService;


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

    @Bean
    public AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService);
        authProvider.setPasswordEncoder(passwordEncoder());
        return authProvider;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests((authorizeHttpRequests) ->
                authorizeHttpRequests
                        .requestMatchers("/login").permitAll()
                        .requestMatchers("/logout").permitAll()
                        .requestMatchers("/login.html").permitAll()
//                        .requestMatchers("/admin").hasRole("ADMIN")
                        .anyRequest().authenticated()
        )
                .formLogin(form -> form
                        .loginProcessingUrl("/login")
                        .loginPage("/login.html")
                        .defaultSuccessUrl("/index.html")
                        .permitAll())
                .logout(withDefaults());

        http.cors(AbstractHttpConfigurer::disable);
        http.csrf(AbstractHttpConfigurer::disable);
        return http.build();
    }
}

userMapper

package top.zunmx.csm.mapper;

import org.apache.ibatis.annotations.Mapper;
import top.zunmx.csm.pojo.Users;

@Mapper
public interface UserMapper {
    Users getUserByName(String username);
}

user的pojo

package top.zunmx.csm.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDate;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Users {
    private Integer id;
    private String username;
    private String authcode;
    private Short status;
    private String group;
    private LocalDate createdTime;
    private LocalDate updateTime;
    private LocalDate lastLoginTime;
    private String lastLoginIP;
}

userDetailsService

package top.zunmx.csm.services;

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.User;
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.Component;
import top.zunmx.csm.mapper.UserMapper;
import top.zunmx.csm.pojo.Users;

import java.util.ArrayList;
import java.util.List;

@Component
public class userDetailsService implements UserDetailsService {
    @Autowired
    private UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        try {
            Users user = userMapper.getUserByName(username);
            GrantedAuthority role;
            List<GrantedAuthority> authorities = new ArrayList<>();
            role = new SimpleGrantedAuthority(user.getGroup());
            authorities.add(role);
            return new User(username, user.getAuthcode(), authorities);
        } catch (Exception e) {
            return null;
        }
    }
}

主入口

不要忘记添加注解

@MapperScan(basePackages = { "top.zunmx.csm.mapper" })

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="top.zunmx.csm.mapper.UserMapper">

    <select id="getUserByName" resultType="top.zunmx.csm.pojo.Users" parameterType="java.lang.String">
        SELECT * FROM users where username = #{username}
    </select>
</mapper>

登录样例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>BeesNet 登录</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        html {
            height: 100%;
        }

        body {
            height: 100%;
        }

        .container {
            height: 100%;
            background-image: linear-gradient(to right bottom, #000000, #062660);
        }

        .login-wrapper {
            background-color: #f3f3f8;
            width: 358px;
            height: 588px;
            border-radius: 15px;
            padding: 0 50px;
            position: relative;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
        }

        .header {
            font-size: 38px;
            font-weight: bold;
            text-align: center;
            line-height: 200px;
        }

        .input-item {
            background-color: #f3f3f8;
            display: block;
            width: 100%;
            margin-bottom: 20px;
            border: 0;
            padding: 10px;
            border-bottom: 1px solid rgb(128, 125, 125);
            font-size: 15px;
            outline: none;
        }

        .input-item:placeholder {
            text-transform: uppercase;
        }

        .btn {
            text-align: center;
            padding: 10px;
            width: 100%;
            margin-top: 40px;
            background-image: linear-gradient(to right, #414141, #303849);
            color: #fff;
            cursor: pointer;
            transition: all 0.3s linear;
        }

        .btn:hover {
            color: #d9d9d9;
            transition: all 0.3s linear;
        }

        .msg {
            text-align: center;
            line-height: 88px;

        }

        a {
            text-decoration-line: none;
            color: #297bff;
        }
    </style>
</head>
<body>
<div class="container">
    <form class="login-wrapper" method="post" action="/login">
        <div class="header">登录页</div>

        <div class="form-wrapper">
            <input type="text" name="username" placeholder="用户名" class="input-item">
            <input type="password" name="password" placeholder="密码" class="input-item">
            <div class="btn" onclick="login()">登录</input>
        </div>
        <div class="msg">
            <span id="message" style="color: red"></span>
        </div>
        </div>
    </form>
</div>
</body>
<script>
    document.getElementsByName("username")[0].value='root'
    document.getElementsByName("password")[0].value='root'
    if (parent.location.href === '/index.html') {
        parent.location.href = "/login.html"
    }
    if(window.location.search.lastIndexOf("?error") === 0)
        message.innerHTML = "用户名或密码错误"
    if(window.location.search.lastIndexOf("?logout") === 0)
        message.innerHTML = "用户注销登录成功"
    function login(){
        document.getElementsByClassName('login-wrapper')[0].submit()
    }
</script>
</html>

spring配置文件

server:
  port: 8798
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/csm
    username: root
    password: ******
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      initial-size: 20 # 初始连接数
      min-idle: 10 # 最小空闲连接数
      max-active: 100 # 最大连接数

mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: top.zunmx.csm.pojo
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: false
logging:
  level:
    root: trace

截图

登录页
用户名密码错误
注销登录

评论 0

还没有评论,来说点什么吧。

提交后需要审核才会公开。