1. 导入依赖
<?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>
<groupId>tian.project</groupId>
<artifactId>easy_to_stop</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>easy_to_stop</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.24</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</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.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity6</artifactId>
<version>3.1.0.M1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<configuration>
<mainClass>tian.project.easy_to_stop.EasyToStopApplication</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</project>
2. 创建数据库表
CREATE TABLE `t_admin` (
`id` bigint(19) NOT NULL COMMENT '主键',
`admin` varchar(50) NOT NULL COMMENT '管理员账号',
`admin_password` varchar(50) NOT NULL COMMENT '管理员密码',
`role` varchar(50) NOT NULL COMMENT '角色',
`locked` tinyint(1) DEFAULT '1' COMMENT '判断账户密码是否未过期',
`check_enabled` tinyint(1) DEFAULT '1' COMMENT '判断账户是否可用',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3.配置实体类
package tian.project.easy_to_stop.pojo;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import org.omg.CORBA.IDLType;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import javax.annotation.security.DenyAll;
import javax.swing.*;
import java.util.*;
@ApiModel("管理员实体类")
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "t_admin")
public class Admin implements UserDetails {
@ApiModelProperty("主键-雪花算法策略")
@TableId(type = IdType.ASSIGN_ID)
private Long id;
@ApiModelProperty("管理员账号")
private String admin;
@ApiModelProperty("密码")
private String adminPassword;
@ApiModelProperty("角色")
private String role;
@ApiModelProperty("当前用户是否未锁定")
private Boolean locked;
@ApiModelProperty("当前账户是否可用")
private Boolean checkEnabled;
@ApiModelProperty("创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@TableField(value = "gmt_create",fill = FieldFill.INSERT)
private Date gmtCreate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@TableField(fill = FieldFill.INSERT_UPDATE)
@ApiModelProperty("更新时间")
private Date gmtModified;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<SimpleGrantedAuthority> authorities=new ArrayList<>();
authorities.add(new SimpleGrantedAuthority(role));
return authorities;
}
@Override
public String getUsername() {
return admin;
}
@Override
public String getPassword() {
return adminPassword;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return !locked;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return checkEnabled;
}
}
4.继承UserDetailsService
package tian.project.easy_to_stop.service;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;
import tian.project.easy_to_stop.pojo.Admin;
@Service
public interface AdminService extends UserDetailsService {
Admin getAdminByAdmin(String name);
}
5.实现UserDetailsService
package tian.project.easy_to_stop.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
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.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import tian.project.easy_to_stop.mapper.AdminMapper;
import tian.project.easy_to_stop.pojo.Admin;
import tian.project.easy_to_stop.service.AdminService;
import tian.project.easy_to_stop.service.UserService;
@Service
@Transactional(rollbackFor = Exception.class
)
public class AdminServiceImpl implements AdminService {
@Autowired
AdminMapper adminMapper;
@Override
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
Admin admin=this.getAdminByAdmin(name);
if(ObjectUtils.isEmpty(admin)){
throw new UsernameNotFoundException("账户不存在!");
}
Admin getAdmin=adminMapper.selectById(admin.getId());
UserDetails userDetails=User.withUsername(getAdmin.getAdmin())
.password(getAdmin.getAdminPassword())
.authorities(getAdmin.getRole())
.build();
System.out.println("admin:\n"+getAdmin);
System.out.println("userDetails:\n"+userDetails.getUsername());
System.out.println("roles:\n"+userDetails.getAuthorities());
System.out.println("locked:\n"+userDetails.isAccountNonLocked());
System.out.println("enabled:\n"+userDetails.isEnabled());
System.out.println("userDetails:\n"+userDetails.getUsername());
return userDetails;
}
@Override
public Admin getAdminByAdmin(String admin) {
QueryWrapper<Admin> queryWrapper=new QueryWrapper<>();
queryWrapper.eq("admin",admin);
return adminMapper.selectOne(queryWrapper);
}
}
6.创建页面及controller映射
package tian.project.easy_to_stop.controller;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Select;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import tian.project.easy_to_stop.constant.Constant;
import java.util.HashMap;
import java.util.Map;
@Controller
@RequestMapping("/page")
@Slf4j
public class PageController {
@ApiOperation("Hello World")
@GetMapping("/helloWorld")
public ModelAndView helloWorld(){
ModelAndView modelAndView=new ModelAndView("helloWorld");
modelAndView.addObject("name","你好");
return modelAndView;
}
@ApiOperation("管理员登录页面")
@GetMapping("/toLogin")
public ModelAndView toLogin(){
log.info("进入登录页面!");
ModelAndView modelAndView=new ModelAndView("toLogin");
return modelAndView;
}
@ApiOperation("views管理页面")
@GetMapping("/views/{page}")
public ModelAndView menu(@PathVariable("page") String page){
ModelAndView modelAndView=new ModelAndView("views/"+page);
log.info("进入页面!{}",modelAndView);
return modelAndView;
}
}
7.配置SecurityConfig
package tian.project.easy_to_stop.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.WebSecurityConfigurer;
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.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.Md4PasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.ObjectUtils;
import tian.project.easy_to_stop.constant.Constant;
import tian.project.easy_to_stop.service.AdminService;
import tian.project.easy_to_stop.service.UserService;
import tian.project.easy_to_stop.service.impl.AdminServiceImpl;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AdminService adminService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/page/views/**").hasRole("admin1")
.and()
.formLogin().loginPage("/page/toLogin")
.usernameParameter("admin")
.passwordParameter("password")
.permitAll()
.defaultSuccessUrl("/page/views/menu")
.failureUrl("/page/toLogin")
.and().logout().logoutSuccessUrl("/page/toLogin")
.invalidateHttpSession(true)
.clearAuthentication(true)
.permitAll()
.and()
.csrf().disable();
}
@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(adminService).passwordEncoder(passwordEncoder());
}
}