spring-security详解

2年前 (2022) 程序员胖胖胖虎阿
321 0 0

spring-security详解

随便写一下,增删改查返回对应的字符

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

@RestController
@RequestMapping("/security")
public class OauthBase {

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

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

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

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

基础认证配置类

import org.springframework.context.annotation.Bean;
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.crypto.password.NoOpPasswordEncoder;
import org.springframework.stereotype.Component;

@Component
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 新增Security
     * 授权账户
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        /**
         * 账号、密码、接口权限
         */
        auth.inMemoryAuthentication().withUser("mykt").password("mykt").authorities("/");
    }

    /**
     * 认证方式
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        /**
         * 认证之后就能访问所有接口
         */
        http.authorizeRequests().antMatchers("/**").fullyAuthenticated().and().httpBasic();
    }

    /**
     * 加密方式,恢复以前模式
     * @return
     */
    @Bean
    public static NoOpPasswordEncoder PasswordEncoder(){
        return (NoOpPasswordEncoder)NoOpPasswordEncoder.getInstance();
    }
}

spring-security详解

输入对应的账号密码就可以访问对应的接口,这个非常简单。

From表单验证

/**
     * 认证方式
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        /**
         * 基础认证
         */
        //http.authorizeRequests().antMatchers("/**").fullyAuthenticated().and().httpBasic();
        /**
         * form表单验证
         */
        http.authorizeRequests().antMatchers("/**").fullyAuthenticated().and().formLogin();
    }

效果图(账号密码没变,页面自带,不需要自己写)

spring-security详解

配置权限规则(不同的账号对应不同的权限)

import org.springframework.context.annotation.Bean;
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.crypto.password.NoOpPasswordEncoder;
import org.springframework.stereotype.Component;

@Component
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 新增Security
     * 授权账户
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        /**
         * 账号、密码、接口权限
         */
        auth.inMemoryAuthentication().withUser("mykt-admin").password("mykt-admin").authorities("add","update","get","del");
        auth.inMemoryAuthentication().withUser("mykt-add").password("mykt-add").authorities("add");
        auth.inMemoryAuthentication().withUser("mykt-update").password("mykt-update").authorities("update");
        auth.inMemoryAuthentication().withUser("mykt-get").password("mykt-get").authorities("get");
        auth.inMemoryAuthentication().withUser("mykt-del").password("mykt-del").authorities("del");
    }

    /**
     * 认证方式
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        /**
         * 基础认证
         */
        //http.authorizeRequests().antMatchers("/**").fullyAuthenticated().and().httpBasic();
        /**
         * form表单验证
         */
        //http.authorizeRequests().antMatchers("/**").fullyAuthenticated().and().formLogin();
        /**
         * 拦截规则
         */
        http.authorizeRequests().antMatchers("/add").hasAnyAuthority("add")
                .antMatchers("/get").hasAnyAuthority("get")
                .antMatchers("/update").hasAnyAuthority("update")
                .antMatchers("/del").hasAnyAuthority("del")
                //form验证
                .antMatchers("/**").fullyAuthenticated().and().formLogin();

    }

    /**
     * 加密方式,恢复以前模式
     * @return
     */
    @Bean
    public static NoOpPasswordEncoder PasswordEncoder(){
        return (NoOpPasswordEncoder)NoOpPasswordEncoder.getInstance();
    }
}
创建了五个账号,mykt-admin、mykt-add 、mykt-update 、mykt-get 、mykt-del,那么从账号名称中就可以看出来这些账号对应的权限
mykt-add测试

spring-security详解
spring-security详解
spring-security详解

mykt-admin测试

spring-security详解
spring-security详解
spring-security详解
spring-security详解

权限不足跳转页面
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;


@Configuration
public class WebServerAutoConfiguration {

    @Bean
    public ConfigurableServletWebServerFactory webServerFactroy(){
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        ErrorPage errorPage403 = new ErrorPage(HttpStatus.FORBIDDEN,"/error/403");
        ErrorPage errorPage404 = new ErrorPage(HttpStatus.NOT_FOUND,"/error/404");
        ErrorPage errorPage500 = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR,"/error/500");
        factory.addErrorPages(errorPage403,errorPage404,errorPage500);
        return  factory;
    }

}
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ErrorController {

    @RequestMapping("/error/403")
    public String error403(){
        return "你当前访问的接口权限不足";
    }

    @RequestMapping("/error/404")
    public String error404(){
        return "资源不可用";
    }
}

spring-security详解
spring-security详解
spring-security详解

为了演示效果, 正常的环境应该是返回码值,由前端对码值进行错误逻辑判断跳转到对应错误页面

自定义登陆页面

创建页面将html文件放在resource文件下面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登陆</title>
</head>
<body>
<h1>自定义登陆页面</h1>
    <form action="/login" method="post">
        <span>用户名称</span><input type="text" name="username" /><br>
        <span>用户密码</span><input type="password" name="password" /><br>
        <input type="submit" value="登陆">
    </form>
</body>
</html>
指定登陆请求
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * login请求
 */
@Controller
public class LoginController {

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

}
import org.springframework.context.annotation.Bean;
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.crypto.password.NoOpPasswordEncoder;
import org.springframework.stereotype.Component;

@Component
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 新增Security
     * 授权账户
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        /**
         * 账号、密码、接口权限
         */
        auth.inMemoryAuthentication().withUser("mykt-admin").password("mykt-admin").authorities("add","update","get","del");
        auth.inMemoryAuthentication().withUser("mykt-add").password("mykt-add").authorities("add");
        auth.inMemoryAuthentication().withUser("mykt-update").password("mykt-update").authorities("update");
        auth.inMemoryAuthentication().withUser("mykt-get").password("mykt-get").authorities("get");
        auth.inMemoryAuthentication().withUser("mykt-del").password("mykt-del").authorities("del");
    }

    /**
     * 认证方式
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        /**
         * 基础认证
         */
        //http.authorizeRequests().antMatchers("/**").fullyAuthenticated().and().httpBasic();
        /**
         * form表单验证
         */
        //http.authorizeRequests().antMatchers("/**").fullyAuthenticated().and().formLogin();
        /**
         * 拦截规则
         */
        http.authorizeRequests().antMatchers("/add").hasAnyAuthority("add")
                .antMatchers("/get").hasAnyAuthority("get")
                .antMatchers("/update").hasAnyAuthority("update")
                .antMatchers("/del").hasAnyAuthority("del")
                .antMatchers("/login").permitAll()
                //form验证
                .antMatchers("/**").fullyAuthenticated().and().formLogin()
                //添加自定义跳转页面
                .loginPage("/login").and().csrf().disable();
    }

    /**
     * 加密方式,恢复以前模式
     * @return
     */
    @Bean
    public static NoOpPasswordEncoder PasswordEncoder(){
        return (NoOpPasswordEncoder)NoOpPasswordEncoder.getInstance();
    }
}

spring-security详解

这个地方写的时候出现过一个问题,一直报个错误
Hint: This may be the result of an unspecified view, due to default view name generation
后面百度终于查到,说是没加一个包,加了就可以了
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

RBAC权限架构(多对多关联)

spring-security详解
用户绑定角色,然后角色绑定权限,那么创建用户的时候,只要给用户选择对应的角色就赋予对应的权限,可以这样理解。

springsecurity整合RBAC权限架构

sql表

/*
Navicat MySQL Data Transfer

Source Server         : 127.0.0.1
Source Server Version : 50717
Source Host           : 127.0.0.1:3306
Source Database       : mayikt_rbac

Target Server Type    : MYSQL
Target Server Version : 50717
File Encoding         : 65001

Date: 2021-05-25 04:17:30
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for sys_permission
-- ----------------------------
DROP TABLE IF EXISTS `sys_permission`;
CREATE TABLE `sys_permission` (
  `id` int(10) NOT NULL,
  `permName` varchar(50) DEFAULT NULL,
  `permTag` varchar(50) DEFAULT NULL,
  `url` varchar(255) DEFAULT NULL COMMENT '请求url',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_permission
-- ----------------------------
INSERT INTO `sys_permission` VALUES ('1', '查询用户', 'getUser', '/getUser');
INSERT INTO `sys_permission` VALUES ('2', '添加用户', 'addUser', '/addUser');
INSERT INTO `sys_permission` VALUES ('3', '修改用户', 'updateUser', '/updateUser');
INSERT INTO `sys_permission` VALUES ('4', '删除用户', 'delUser', '/delUser');

-- ----------------------------
-- Table structure for sys_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role` (
  `id` int(10) NOT NULL,
  `roleName` varchar(50) DEFAULT NULL,
  `roleDesc` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_role
-- ----------------------------
INSERT INTO `sys_role` VALUES ('1', 'admin', '管理员');
INSERT INTO `sys_role` VALUES ('2', 'add_user', '添加管理员');

-- ----------------------------
-- Table structure for sys_role_permission
-- ----------------------------
DROP TABLE IF EXISTS `sys_role_permission`;
CREATE TABLE `sys_role_permission` (
  `role_id` int(10) DEFAULT NULL,
  `perm_id` int(10) DEFAULT NULL,
  KEY `FK_Reference_3` (`role_id`),
  KEY `FK_Reference_4` (`perm_id`),
  CONSTRAINT `FK_Reference_3` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`id`),
  CONSTRAINT `FK_Reference_4` FOREIGN KEY (`perm_id`) REFERENCES `sys_permission` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_role_permission
-- ----------------------------
INSERT INTO `sys_role_permission` VALUES ('1', '1');
INSERT INTO `sys_role_permission` VALUES ('1', '2');
INSERT INTO `sys_role_permission` VALUES ('1', '3');
INSERT INTO `sys_role_permission` VALUES ('1', '4');
INSERT INTO `sys_role_permission` VALUES ('2', '2');

-- ----------------------------
-- Table structure for sys_user
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
  `id` int(10) NOT NULL,
  `username` varchar(50) DEFAULT NULL,
  `realname` varchar(50) DEFAULT NULL,
  `password` varchar(50) DEFAULT NULL,
  `createDate` date DEFAULT NULL,
  `lastLoginTime` date DEFAULT NULL,
  `enabled` int(5) DEFAULT NULL,
  `accountNonExpired` int(5) DEFAULT NULL,
  `accountNonLocked` int(5) DEFAULT NULL,
  `credentialsNonExpired` int(5) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_user
-- ----------------------------
INSERT INTO `sys_user` VALUES ('1', 'mayikt_admin', '张三', '99743025dc21f56c63d0cb2dd34f06f5', '2018-11-13', '2018-11-13', '1', '1', '1', '1');
INSERT INTO `sys_user` VALUES ('2', 'mayikt_add', '小余', 'a5a6996f2e1953161522a93cbb5fb556', '2018-11-13', '2018-11-13', '1', '1', '1', '1');

-- ----------------------------
-- Table structure for sys_user_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_user_role`;
CREATE TABLE `sys_user_role` (
  `user_id` int(10) DEFAULT NULL,
  `role_id` int(10) DEFAULT NULL,
  KEY `FK_Reference_1` (`user_id`),
  KEY `FK_Reference_2` (`role_id`),
  CONSTRAINT `FK_Reference_1` FOREIGN KEY (`user_id`) REFERENCES `sys_user` (`id`),
  CONSTRAINT `FK_Reference_2` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

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

然后就是SpringBoot整合mybatis(略)
那么我们现在要做的就是把以前写死的账号、密码、url都要通过查询数据动态的拿到,那么这个就是我们接下来要做的事情。
SecurityConfig
import com.my.mapper.PermissionMapper;
import com.my.model.PermissionModel;
import com.my.service.serviceimpl.MemberDetailsServiceimpl;
import com.my.utils.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private MemberDetailsServiceimpl memberDetailsServiceimpl;

    /**
     * 新增Security
     * 授权账户
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(memberDetailsServiceimpl).passwordEncoder(new PasswordEncoder() {
            /**
             * 对用户输入的密码进行加密
             * @param charSequence
             * @return
             */
            @Override
            public String encode(CharSequence charSequence) {
                String encode = MD5Util.encode((String) charSequence);
                return encode;
            }
            /**
             * 加密比对
             * @param charSequence 输入明文密码
             * @param password  数据库中的密码
             * @return true 登陆成功  false 密码错误
             */
            @Override
            public boolean matches(CharSequence charSequence, String password) {
                //输入的密码进行加密
                String rawPass = MD5Util.encode((String) charSequence);
                //对比密码
                return  password.equals(rawPass);
            }
        });
    }

    /**
     * 认证方式
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry authorizeRequests = http.authorizeRequests();
        //查询到所有的权限
        /**
         * sql
         * SELECT
         *     id,
         *     permName,
         *     permTag,
         *     url
         * FROM
         *     sys_permission
         */
        List<PermissionModel> permissionList = permissionMapper.getPermissionList();
        permissionList.forEach(x->{
            //添加规则
            authorizeRequests.antMatchers(x.getUrl()).hasAnyAuthority(x.getPermTag());
        });
        authorizeRequests
        .antMatchers("/login").permitAll()
        .antMatchers("/**").fullyAuthenticated().and().formLogin()
            //添加自定义跳转页面
        .loginPage("/login").and().csrf().disable();
    }

    /**
     * 加密方式,恢复以前模式
     * @return
     */
    @Bean
    public static NoOpPasswordEncoder PasswordEncoder(){
        return (NoOpPasswordEncoder)NoOpPasswordEncoder.getInstance();
    }
}
重写UserDetailsService.loadUserByUsername方法
import com.my.mapper.PermissionMapper;
import com.my.mapper.UserMapper;
import com.my.model.PermissionModel;
import com.my.model.UserModel;
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.Component;

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

/**
 * 重写UserDetailsService.loadUserByUsername方法
 */
@Component
public class MemberDetailsServiceimpl implements UserDetailsService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private PermissionMapper permissionMapper;

    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
        //根据登陆的userName查询这个用户
        /**
         * sql
         *SELECT
         *     id,
         *     username,
         *     realname,
         *     PASSWORD,
         *     createDate,
         *     lastLoginTime,
         *     enabled,
         *     accountNonExpired,
         *     accountNonLocked,
         *     credentialsNonExpired
         * FROM
         *     sys_user
         * where
         *     username=#{username}
         */
        UserModel user = userMapper.getUser(userName);
        if(user == null){
            return null;
        }
        //根据用户查询权限
        /**
         * sql
         * SELECT
         *       s6.id,
         *       s6.permName,
         *       s6.permTag,
         *       s6.url
         *   FROM
         *       ( SELECT s2.user_id FROM sys_user s1 LEFT JOIN sys_user_role s2 ON s1.id = s2.user_id WHERE s1.username = #{username} ) s4
         *       LEFT JOIN sys_role s3 ON s4.user_id = s3.id
         *       LEFT JOIN sys_role_permission s5 ON s5.role_id = s3.id
         *       LEFT JOIN sys_permission s6 ON s6.id = s5.perm_id
         */
        List<PermissionModel> permissionList = permissionMapper.getPermission(user.getUsername());
        //创建权限集合
        List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        //添加权限
        permissionList.forEach(x ->{
            grantedAuthorities.add(new SimpleGrantedAuthority(x.getPermTag()));
        });
        //将权限绑定到user
        user.setAuthorities(grantedAuthorities);
        return user;
    }
}
UserModel 这个地方要注意,这个User实体类实现了UserDetails重写了方法,那么这些方法默认是返回false,我们要改成true,不然登陆会出现失败的情况。还有一个问题,就是重写UserDetails的方法,刚好我们字段也有一个类似的字段,在启动的时候项目就检查到这个不符合规范,最后我也是将我实体类中的字段set get方法删除。
/**
 * 用户表
 */
public class UserModel implements UserDetails {
    private Integer id;
    private String username;
    private String realname;
    private String password;
    private Date createDate;
    private Date lastLoginTime;
    private Integer enabled;
    private Integer accountNonExpired;
    private Integer accountNonLocked;
    private Integer credentialsNonExpired;
	//用户跟权限板顶,一对多
    private List<GrantedAuthority> authorities = new ArrayList<>();

    @Override
    public List<GrantedAuthority> getAuthorities() {
        return authorities;
    }

    public void setAuthorities(List<GrantedAuthority> authorities) {
        this.authorities = authorities;
    }

    public Integer getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }

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

    public String getRealname() {
        return realname;
    }

    public void setRealname(String realname) {
        this.realname = realname;
    }

    public String getPassword() {
        return password;
    }

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

    public Date getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }

    public Date getLastLoginTime() {
        return lastLoginTime;
    }

    public void setLastLoginTime(Date lastLoginTime) {
        this.lastLoginTime = lastLoginTime;
    }

}
MD5加密password
import java.security.MessageDigest;

public class MD5Util {
    //盐
    private static final String SALT = "mayikt";

    public static String encode(String password) {
        password = password + SALT;
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        char[] charArray = password.toCharArray();
        byte[] byteArray = new byte[charArray.length];

        for (int i = 0; i < charArray.length; i++)
            byteArray[i] = (byte) charArray[i];
        byte[] md5Bytes = md5.digest(byteArray);
        StringBuffer hexValue = new StringBuffer();
        for (int i = 0; i < md5Bytes.length; i++) {
            int val = ((int) md5Bytes[i]) & 0xff;
            if (val < 16) {
                hexValue.append("0");
            }

            hexValue.append(Integer.toHexString(val));
        }
        return hexValue.toString();
    }
}
演示admin账户,全部权限。我只写了一个查询,其他省略了。

spring-security详解
spring-security详解
spring-security详解

演示mykt-add,这个账户只有add权限,那么我们去用这个账户登陆去查询看看

spring-security详解
spring-security详解
spring-security详解

最后我将代码上传到百度网盘

链接:https://pan.baidu.com/s/1ImSsNg1XdMlZEU922jEiKA
提取码:yyds

版权声明:程序员胖胖胖虎阿 发表于 2022年11月5日 下午10:40。
转载请注明:spring-security详解 | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...