【Spring Security】入门——使用Themeleaf渲染页面

技术点:

  1. Spring Boot
  2. Spring Security
  3. MySQL
  4. MyBatis
  5. Thymeleaf

本项目GitHub传送门

一、项目框架

1. 项目结构

在这里插入图片描述

2. 选择依赖

使用Spring Boot 创建项目。
依赖勾选

  1. Spring Boot DevTools
  2. Spring Web
  3. Spring Security
  4. Thymeleaf
  5. Mybatis Framework
  6. MySQL Driver

可参考此pom.xml文件

<?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>2.3.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.aaa</groupId>
    <artifactId>springboot-security-thymeleaf</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-security-thymeleaf</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </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.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.3</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </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>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

二、数据库

共5张表

  1. t_user 用户表
  2. t_role 角色表
  3. r_user_role 用户-角色
  4. r_permission 权限表
  5. r_role_permission 角色-权限
/*
 Navicat Premium Data Transfer

 Source Server         : localhost
 Source Server Type    : MySQL
 Source Server Version : 50610
 Source Host           : localhost:3306
 Source Schema         : user_db

 Target Server Type    : MySQL
 Target Server Version : 50610
 File Encoding         : 65001

 Date: 21/07/2020 21:29:29
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for t_permission
-- ----------------------------
DROP TABLE IF EXISTS `t_permission`;
CREATE TABLE `t_permission`  (
  `id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `code` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '权限标识符',
  `description` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '描述',
  `url` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '请求地址',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of t_permission
-- ----------------------------
INSERT INTO `t_permission` VALUES ('1', 'p1', '测试资源1', '/resource/r1');
INSERT INTO `t_permission` VALUES ('2', 'p2', '测试资源2', '/resource/r2');
INSERT INTO `t_permission` VALUES ('3', 'p3', '测试资源3', '/resource/r3');

-- ----------------------------
-- Table structure for t_role
-- ----------------------------
DROP TABLE IF EXISTS `t_role`;
CREATE TABLE `t_role`  (
  `id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `role_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `create_time` datetime(0) NULL DEFAULT NULL,
  `update_time` datetime(0) NULL DEFAULT NULL,
  `status` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `unique_role_name`(`role_name`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of t_role
-- ----------------------------
INSERT INTO `t_role` VALUES ('1', '管理员', NULL, NULL, NULL, '');

-- ----------------------------
-- Table structure for t_role_permission
-- ----------------------------
DROP TABLE IF EXISTS `t_role_permission`;
CREATE TABLE `t_role_permission`  (
  `role_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `permission_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  PRIMARY KEY (`role_id`, `permission_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of t_role_permission
-- ----------------------------
INSERT INTO `t_role_permission` VALUES ('1', '1');
INSERT INTO `t_role_permission` VALUES ('1', '2');

-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户id',
  `username` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `password` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `fullname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户姓名',
  `mobile` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '手机号',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES (1, 'zhangsan', '$2a$10$37vdSYJUVguwXpLDnZfEt.UDC0y6Yk2RCzFuJKfOrWCiTnUFlmj3K', NULL, NULL);

-- ----------------------------
-- Table structure for t_user_role
-- ----------------------------
DROP TABLE IF EXISTS `t_user_role`;
CREATE TABLE `t_user_role`  (
  `user_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `role_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `create_time` datetime(0) NULL DEFAULT NULL,
  `creator` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`user_id`, `role_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of t_user_role
-- ----------------------------
INSERT INTO `t_user_role` VALUES ('1', '1', NULL, NULL);
SET FOREIGN_KEY_CHECKS = 1;

三、代码实现

实现思路

  1. 配置Spring Boot环境。将服务器配置、数据源、MyBatis映射文件、启动文件完成配置。
  2. 完成基本的html(Thymeleaf)页面。用于测试用户注册、登录、访问资源功能。
  3. 配置html视图器。将使用Thymeleaf中的视图进行配置。
  4. 进行Spring Security配置。主要配置密码编码器、安全拦截器、登录页面。
  5. 编写dao层和mapper文件。用于连接数据库。
  6. 编写service层。一方面是实现用户的注册和登录,另一方面是实现spring-security核心接口,其负载着用户特定数据,它被用来在整个框架作为一个用户DAO。
  7. 编写controller层。用于页面访问,在controller接口中可以设置接口的访问权限,让Spring Security进行安全验证。

1. 配置文件

application.properties

# web
server.port=8080
server.servlet.context-path=/
spring.application.name=security-springboot
# DataSource
spring.datasource.url=jdbc:mysql://localhost:3306/user_db?serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# mybatis
mybatis.mapper-locations=classpath:mapper/*.xml

2. 编写测试页面

index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org/">
<head>
    <meta charset="UTF-8">
    <title>index</title>
</head>
<body>
登录成功
<h1>菜单页</h1>
<hr>
<h3><a href="/resource/r1" target="_blank">资源一</a></h3>
<h3><a href="/resource/r2" target="_blank">资源二</a></h3>
<h3><a href="/resource/r3" target="_blank">资源三</a></h3>

<hr>
<form th:action="@{/logout}" method="get" >
    <button type="submit" >退出</button>
</form>

</body>
</html>

login.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org/">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
<form th:action="@{/loginForm}" method="post" >
    用户名<input type="text" name="username" /><br>
    密码<input type="password" name="password" /><br>
    <button type="submit" >提交</button>
    <!-- ${session?.SPRING_SECURITY_LAST_EXCEPTION?.message} security自带的错误提示信息 -->
    <p th:if="${param.error}" th:text="${session?.SPRING_SECURITY_LAST_EXCEPTION?.message}" ></p>
</form>
<a th:href="@{/register}">注册</a>
</body>
</html>

register.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册</title>
</head>
<body>
<h1>注册</h1>
<form action="/user/register" method="post">
    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    <input type="submit" value="注册">
</form>
<hr>
<p><a href="/">登录</a></p>
</body>
</html>

3. 配置视图访问器

htmlController

package com.aaa.springbootsecuritythymeleaf.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author 淮南King
 * @date 2020-08-04
 */
@RestController
public class htmlController {
    @RequestMapping("/index")
    public ModelAndView index(){
        return new ModelAndView("/index");
    }

    @RequestMapping("/test")
    public Object test(){
        return "test 此请求无需权限";
    }

    /**
     * 自定义登录页面
     * @param error 错误信息显示标识
     * @return
     *
     */
    @GetMapping("/login")
    public ModelAndView login(String error){
        ModelAndView modelAndView = new ModelAndView("/login");
        modelAndView.addObject("error", error);
        return modelAndView;
    }


    /**
     * 自定义注册页面
     * @return
     *
     */
    @RequestMapping("/register")
    public ModelAndView register(){
        return new ModelAndView("register");
    }
}

4. 进行Spring Security配置

WebSecurityConfig

package com.aaa.springbootsecuritythymeleaf.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * spring security配置
 *
 * @author 淮南King
 */
@Configuration @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class WebSecurityConfig
    extends WebSecurityConfigurerAdapter {

    //密码编码器
    @Bean public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    //安全拦截机制
    @Override protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            //允许表单登录
            .formLogin()
                //登录页面路径
                .loginPage("/login")
                .loginProcessingUrl("/loginForm")
            //设置登录成功跳转页面,error=true控制页面错误信息的展示
            .successForwardUrl("/index").failureUrl("/login?error=true")
            .permitAll()
            .and()
            //允许不登陆就可以访问的方法,多个用逗号分隔
            .authorizeRequests().antMatchers("/test","/user/**","/register").permitAll()
            //其他的需要授权后访问
            .anyRequest().authenticated()
            .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
            .and()
            .logout()
            //登录退出
            .logoutUrl("/logout")
            //退出时情况cookies
            .and()
            .logout().deleteCookies("JESSIONID")
            .logoutSuccessUrl("/login?logout");
    }
}

MyUserDetail

package com.aaa.springbootsecuritythymeleaf.config;

import com.aaa.springbootsecuritythymeleaf.dao.UserDao;
import com.aaa.springbootsecuritythymeleaf.entity.User;
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.List;

/**
 * 实现spring-security核心接口,其负载的用户特定数据。
 *
 * @author 淮南King
 */
@Service
public class MyUserDetail implements UserDetailsService {

    @Autowired UserDao userDao;

    // 根据账号查询用户信息
    @Override public UserDetails loadUserByUsername(String username) {
        //将来连接数据库根据账号查询用户信息
        User userDto = userDao.getUserByUsername(username);
        //当查询此用户不存在时,将抛出用户名未找到异常
        if (userDto == null) {
            throw new UsernameNotFoundException("No such user found, the user name is: "+username);
        }
        //根据用户id查询权限
        List<String> permissions = userDao.findPermissionsByUserId(userDto.getId());
        //将permissions转为数组
        String[] permissionArray = new String[permissions.size()];
        permissions.toArray(permissionArray);
        UserDetails userDetails =
            org.springframework.security.core.userdetails.User.withUsername(userDto.getUsername()).password(userDto.getPassword()).authorities(permissionArray)
                .build();
        return userDetails;
    }
}

5. 编写dao层和mapper文件

UserDao.java

package com.aaa.springbootsecuritythymeleaf.dao;

import com.aaa.springbootsecuritythymeleaf.entity.User;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
 * 用户信息持久层
 * @author 淮南King
 */
@Mapper
public interface UserDao {
    /**
     * 根据账号查询用户信息
     *
     * @param username 用户姓名
     * @return 用户信息
     */
    User getUserByUsername(String username);

    /**
     * 根据用户id查询用户权限
     *
     * @param userId 用户id
     * @return 权限列表
     */
    List<String> findPermissionsByUserId(String userId);

    /**
     * 添加用户
     *
     * @param userDTO 用户信息
     * @return 修改条数
     */
    int addUser(User userDTO);
}

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="com.aaa.springbootsecuritythymeleaf.dao.UserDao">

    <select id="getUserByUsername" parameterType="String" resultType="com.aaa.springbootsecuritythymeleaf.entity.User">
        select id,username,password,fullname,mobile from t_user where username = #{username}
    </select>

    <select id="findPermissionsByUserId" parameterType="String" resultType="String">
        SELECT code FROM t_permission WHERE id IN(
            SELECT permission_id FROM t_role_permission WHERE role_id IN(
            SELECT role_id FROM t_user_role WHERE user_id = #{id} ))
    </select>

    <insert id="addUser" parameterType="com.aaa.springbootsecuritythymeleaf.entity.User">
        INSERT INTO `user_db`.`t_user`(`username`, `password`) VALUES (#{username},#{password})
    </insert>
</mapper>

6. 编写service层

UserService

package com.aaa.springbootsecuritythymeleaf.service;

import com.aaa.springbootsecuritythymeleaf.dao.UserDao;
import com.aaa.springbootsecuritythymeleaf.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 用户信息持久业务层
 *
 * @author 淮南King
 * @date 2020-07-21
 */
@Service
public class UserService {

    @Autowired UserDao dao;

    public User getUserByUsername(String username) {
        return dao.getUserByUsername(username);
    }

    public List<String> findPermissionsByUserId(String userId) {
        return dao.findPermissionsByUserId(userId);
    }

    /**
     * 添加用户
     * @param user
     * @return
     */
    public int addUser(User user) {
        //获取密码编码器
        PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        //将用户的密码进行编码
        String password = passwordEncoder.encode(user.getPassword());
        //将编码后的密码覆盖到用户信息中
        user.setPassword(password.substring(8));
        //将用户信息持久化到数据库中
        return dao.addUser(user);
    }
}

7. 编写controller层

LoginController

package com.aaa.springbootsecuritythymeleaf.controller;

import com.aaa.springbootsecuritythymeleaf.entity.User;
import com.aaa.springbootsecuritythymeleaf.service.UserService;
import com.aaa.springbootsecuritythymeleaf.util.SecurityUtil;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 淮南King
 */
@RestController
public class LoginController {

    @Resource private UserService service;

    @RequestMapping(value = "/login-success",produces = {"text/plain;charset=UTF-8"})
    public ModelAndView loginSuccess(){
        //获取当前线程的SecurityContext
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //获取当前线程中用户的名称,将名称传递至页面
        Map<String,Object> attributes = new HashMap<>();
        attributes.put("username", SecurityUtil.getUserNameByAuthentication(authentication));
        return new ModelAndView("menu",attributes);
    }

    @PostMapping("/user/register")
    public String register(User user) {
        service.addUser(user);
        return user.getUsername()+"注册成功";
    }
    @GetMapping("/register")
    public ModelAndView registerView() {
        return new ModelAndView("register");
    }

}

AuthController

package com.aaa.springbootsecuritythymeleaf.controller;

import com.aaa.springbootsecuritythymeleaf.util.SecurityUtil;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author 淮南King
 * @date 2020-07-21
 */
@RestController
@RequestMapping("/resource")
public class AuthController {

    /**
     * 测试资源1
     * 拥有p1权限才可以访问
     *
     * @return
     */
    @GetMapping(value = "/r1", produces = {"text/plain;charset=UTF-8"})
    @PreAuthorize("hasAuthority('p1')")
    public String resource1() {
        //获取当前线程的SecurityContext
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //获取当前线程的名称
        return SecurityUtil.getUserNameByAuthentication(authentication) + " 访问资源1";
    }

    /**
     * 测试资源2
     * 拥有p2权限才可以访问
     *
     * @return
     */
    @GetMapping(value = "/r2", produces = {"text/plain;charset=UTF-8"})
    @PreAuthorize("hasAuthority('p2')")
    public String resource2() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return SecurityUtil.getUserNameByAuthentication(authentication) + " 访问资源2";
    }

    /**
     * 测试资源3
     * 拥有p3权限才可以访问
     *
     * @return
     */
    @GetMapping(value = "/r3", produces = {"text/plain;charset=UTF-8"})
    @PreAuthorize("hasAuthority('p3')")
    public String resource3() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return SecurityUtil.getUserNameByAuthentication(authentication) + " 访问资源3";
    }
}

附:实体类与帮助类

User

package com.aaa.springbootsecuritythymeleaf.entity;

/**
 * DTO:与数据库保持一致<br>
 * 用户信息
 * @author 淮南King
 */
public class User {
    /**
     * 用户id
     */
    private String id;
    /**
     * 用户名
     */
    private String username;
    /**
     * 用户密码
     */
    private String password;
    /**
     * 用户角色ID
     */
    private Integer roleId;

    public String getId() {
        return id;
    }

    public void setId(String 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;
    }

    public Integer getRoleId() {
        return roleId;
    }

    public void setRoleId(Integer roleId) {
        this.roleId = roleId;
    }
}

Permission

package com.aaa.springbootsecuritythymeleaf.entity;
/**
 *  权限信息
 * @author 淮南King
 */
public class Permission {
    /**
     * 权限id
     */
    private String id;
    /**
     * 权限代号
     */
    private String code;
    /**
     * 权限描述
     */
    private String description;
    /**
     * 路径
     */
    private String url;

    public String getId() {
        return id;
    }

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

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

SecurityUtil

package com.aaa.springbootsecuritythymeleaf.util;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;

/**
 * Security帮助类
 * @author 淮南King
 * @date 2020-07-21
 */
public class SecurityUtil {

    /**
     * 根据当前执行线程的SecurityContext获取用户名称
     * @param authentication 当前认证通过的用户身份
     * @return 用户名
     */
    public static String getUserNameByAuthentication(Authentication authentication){
        String username = null;
        //用户身份
        Object principal = authentication.getPrincipal();
        if(principal == null){
            return "匿名";
        }
        if(principal instanceof UserDetails){
            UserDetails userDetails = (UserDetails)principal;
            username = userDetails.getUsername();
        }else{
            username = principal.toString();
        }
        return username;
    }
}



项目传送门

end…

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值