引言
好久没有创建项目了,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