说明:今天有个哥们问我有没有什么好的权限框架推荐,我了解了一下他们对业务的要求,我反手就给他推荐了Security权限框架,他说他看过我之前的Shiro权限管理博客,感觉Shiro不错。我说区别不大,Security除了不能脱离Spring,Shiro能做的Security都能做,而且Security对oauth、OpenID等也有支持,Shiro就需要自己手动去实现了。那哥们就说:关键你没有写过Security相关的博客啊!当时我脑瓜子就嗡嗡的,这是那儿跟那儿啊。。。。。。后来感觉Security也用过几次了,整理成博客也可以吧。
细节可以查看官网,这里只是使用!
工程目录:
1.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 http://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.1.6.RELEASE</version> </parent> <groupId>Security_Pub</groupId> <artifactId>Security_Pub</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>Security_Pub Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <junit.version>4.12</junit.version> <log4j.version>1.2.17</log4j.version> <lombok.version>1.14.8</lombok.version> <druid.version>1.1.16</druid.version> <commonslang.version>2.6</commonslang.version> <redis.version>2.1.3.RELEASE</redis.version> <springfox.version>2.7.0</springfox.version> <mybatis.plus.boot.starter.version>3.0.1</mybatis.plus.boot.starter.version> <pagehelper.spring.boot.starter.version>1.2.10</pagehelper.spring.boot.starter.version> <mysql-connector.version>5.1.39</mysql-connector.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-taglibs</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity5</artifactId> </dependency> <!-- 引入 lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </dependency> <!-- swagger --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>${springfox.version}</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>${springfox.version}</version> </dependency> <!-- pagehelper分页 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>${pagehelper.spring.boot.starter.version}</version> </dependency> <!-- mybatis-plus --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${mybatis.plus.boot.starter.version}</version> </dependency> <!--mysql数据库依赖包--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql-connector.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>${redis.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.70</version> <scope>compile</scope> </dependency> <dependency> <groupId>apache-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.0</version> </dependency> </dependencies> </project>
2.application.yml文件
server: port: 8080 #数据源 spring: datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/my_security_test?useUnicode=true&characterEncoding=UTF-8 username: root password: root #日期配置 yyyy-MM-dd HH:mm:ss jackson: date-format: yyyy-MM-dd HH:mm:ss #映射xml mybatis-plus: mapper-locations: classpath:mapping/*.xml type-aliases-package: com.dev.model configuration: #开启驼峰 map-underscore-to-camel-case: true #分页插件 pagehelper: auto-dialect: mysql reasonable: true support-methods-arguments: true
3.Result.java
package com.dev.common; import com.alibaba.fastjson.JSON; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.servlet.ServletResponse; import java.io.PrintWriter; import java.util.List; /** * @author 李庆伟 * @date 2020/4/16 9:52 */ @Data public class Result { @ApiModelProperty(value = "返回码") private int code; @ApiModelProperty(value = "返回数据") private Object data; @ApiModelProperty(value = "返回描述") private String msg; @ApiModelProperty(value = "返回长度") private long count; /**返回成功 */ public static Result success(List<Object> data, long count){ Result result = new Result(); result.setCode(0);//成功 result.setMsg("成功");//提示语 result.setData(data); result.setCount(count); return result; } /**返回成功 */ public static Result success(List data){ Result result = new Result(); result.setCode(0);//成功 result.setMsg("成功");//提示语 result.setData(data); result.setCount(data == null || data.size() == 0 ? 0 : data.size()); return result; } /**返回成功 */ public static Result successForPage(List data,Integer count){ Result result = new Result(); result.setCode(0);//成功 result.setMsg("成功");//提示语 result.setData(data); result.setCount(count == null ? 0 : count); return result; } /**返回成功 */ public static Result success(){ Result result = new Result(); result.setCode(0);//成功 result.setMsg("成功");//提示语 return result; } /**返回成功 */ public static Result success(Object object){ Result result = new Result(); result.setCode(0);//成功 result.setMsg("成功");//提示语 result.setData(object);//返回内容 return result; } /**返回失败 */ public static Result error(){ Result result = new Result(); result.setCode(1);//失败 result.setMsg("失败");//提示语 return result; } /**返回失败 */ public static Result error(int code, String msg){ Result result = new Result(); result.setCode(code);//失败 result.setMsg(msg);//提示语 return result; } /**返回信息*/ public static Result response(int code, String msg, Object data) { Result result = new Result(); result.setCode(code); result.setMsg(msg); result.setData(data); return result; } /**Response输出Json格式 */ public static void responseJson(ServletResponse response, Object data) { PrintWriter out = null; try { response.setCharacterEncoding("UTF-8"); response.setContentType("application/json"); out = response.getWriter(); out.println(JSON.toJSONString(data)); out.flush(); } catch (Exception e) { System.out.println("Response输出Json异常:" + e); } finally { if (out != null) { out.close(); } } } }
4.MyException.java
package com.dev.config.exception; /** * @author 李庆伟 * @date 2020/4/16 10:10 */ public class MyException extends RuntimeException{ private int code; private String msg; public MyException(int code, String msg){ super(msg); this.code = code; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } }
5.TopException.java
package com.dev.config.exception; import com.dev.common.Result; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.access.AccessDeniedException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; /** * @author 李庆伟 * @date 2020/4/16 10:11 */ @ControllerAdvice public class TopException { private Logger logger = LoggerFactory.getLogger(this.getClass()); @ExceptionHandler(value = Exception.class) @ResponseBody public Result handle(Exception e){ if(e instanceof MyException){ logger.error("业务日志",e); MyException myException = (MyException) e; return Result.error(myException.getCode(),myException.getMessage()); }else if(e instanceof AccessDeniedException){ return Result.error(403,"访问权限不足"); } logger.error("系统日志",e); return Result.error(1000,"业务繁忙"); } }
6.UserAccessDeniedHandler.java
package com.dev.config.security.handler; import com.dev.common.Result; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.stereotype.Component; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * 无权限处理类 * @author 李庆伟 * @date 2021/7/26 10:00 */ @Component public class UserAccessDeniedHandler implements AccessDeniedHandler { @Override public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { Result.responseJson(response, Result.response(403, "权限不足,拒绝访问", accessDeniedException.getMessage())); } }
7.UserAuthenticationProvider.java
package com.dev.config.security.handler; import com.dev.config.security.Md5Util; import com.dev.model.SysUserDetails; import com.dev.service.impl.SysUserDetailsService; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Component; /** * @author 李庆伟 * @date 2021/7/26 10:49 */ @Component public class UserAuthenticationProvider implements AuthenticationProvider { @Autowired private SysUserDetailsService userDetailsService; /** * 身份验证 */ @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { String username = (String) authentication.getPrincipal(); // 获取用户名 String password = (String) authentication.getCredentials(); // 获取密码 if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) { throw new UsernameNotFoundException("用户名或密码不能为空"); } if(username.equals("admin") && password.equals("123456")){ SysUserDetails sysUserDetails = (SysUserDetails) userDetailsService.loadUserByUsername(username); return new UsernamePasswordAuthenticationToken(sysUserDetails, password, sysUserDetails.getAuthorities()); } else if (username.equals("admin") && !password.equals("123456")){ throw new BadCredentialsException("用户名或密码错误"); } else { SysUserDetails sysUserDetails = (SysUserDetails) userDetailsService.loadUserByUsername(username); if (sysUserDetails == null) { throw new UsernameNotFoundException("用户名不存在"); } if(!sysUserDetails.getPassword().equals(Md5Util.MD5(password))){ throw new BadCredentialsException("用户名或密码错误"); } return new UsernamePasswordAuthenticationToken(sysUserDetails, password, sysUserDetails.getAuthorities()); } } /** * 支持指定的身份验证 */ @Override public boolean supports(Class<?> authentication) { return true; } }
8.UserLoginFailureHandler.java
package com.dev.config.security.handler; import com.dev.common.Result; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 登录失败处理类 * @author 李庆伟 * @date 2021/7/26 10:03 */ @Component public class UserLoginFailureHandler implements AuthenticationFailureHandler { @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) { Result.responseJson(response, Result.response(500, "登录失败", exception.getMessage())); } }
9.UserLoginSuccessHandler.java
package com.dev.config.security.handler; import com.dev.common.Result; import com.dev.model.SysUserDetails; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.util.HashMap; import java.util.Map; /** * 登录成功处理类 * @author 李庆伟 * @date 2021/7/26 10:02 */ @Component public class UserLoginSuccessHandler implements AuthenticationSuccessHandler { @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { SysUserDetails sysUserDetails = (SysUserDetails) authentication.getPrincipal(); Map<String, String> tokenMap = new HashMap<>(); HttpSession session = request.getSession(); session.setAttribute("user", sysUserDetails); Result.responseJson(response, Result.response(0, "登录成功", tokenMap)); } }
10.UserLogoutSuccessHandler.java
package com.dev.config.security.handler; import com.dev.common.Result; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 登出成功处理类 * @author 李庆伟 * @date 2021/7/26 10:04 */ @Component public class UserLogoutSuccessHandler implements LogoutSuccessHandler { @Override public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { SecurityContextHolder.clearContext(); Result.responseJson(response, Result.response(200, "登出成功", null)); } }
11.UserNotLoginHandler.java
package com.dev.config.security.handler; import com.dev.common.Result; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.stereotype.Component; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author 李庆伟 * @date 2021/7/27 15:39 */ @Component public class UserNotLoginHandler implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { Result.responseJson(response, Result.response(401, "未登录", authException.getMessage())); } }
12.UserPermissionEvaluator.java
package com.dev.config.security.handler; import com.dev.config.exception.MyException; import com.dev.model.SysUserDetails; import com.dev.model.TSysRes; import com.dev.service.TSysResService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.security.access.PermissionEvaluator; import org.springframework.security.core.Authentication; import org.springframework.stereotype.Component; import java.io.Serializable; import java.util.HashSet; import java.util.List; import java.util.Set; /** * @author 李庆伟 * @date 2021/7/26 14:33 */ @Configuration @Component public class UserPermissionEvaluator implements PermissionEvaluator { @Autowired private TSysResService tSysResService; /** * 判断是否拥有权限 * [authentication, targetUrl, permission] * @return {@link boolean} * @throws * @author 李庆伟 * @date 2021/12/7 19:42 */ @Override public boolean hasPermission(Authentication authentication, Object targetUrl, Object permission) { SysUserDetails sysUserDetails = null; try { sysUserDetails = (SysUserDetails) authentication.getPrincipal(); } catch (Exception e){ throw new MyException(403,"权限不足"); } Set<String> permissions = new HashSet<String>(); // 用户权限 List<TSysRes> authList = tSysResService.findResByUserId(sysUserDetails.getId()); for (int i = 0; i < authList.size() ; i++) { permissions.add(authList.get(i).getPermission()); } // 判断是否拥有权限 if (permissions.contains(permission.toString())) { return true; } return false; } @Override public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) { return false; } }
13.AutoSecurityConfig.java
package com.dev.config.security; import com.dev.config.security.handler.*; 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.method.configuration.EnableGlobalMethodSecurity; 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.bcrypt.BCryptPasswordEncoder; import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler; /** * @author 李庆伟 * @date 2021/7/26 14:36 */ @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) // 开启方法权限注解 public class AutoSecurityConfig extends WebSecurityConfigurerAdapter { /** * 无权限处理类 */ @Autowired private UserAccessDeniedHandler userAccessDeniedHandler; /** * 用户未登录处理类 */ @Autowired private UserNotLoginHandler userNotLoginHandler; /** * 用户登录成功处理类 */ @Autowired private UserLoginSuccessHandler userLoginSuccessHandler; /** * 用户登录失败处理类 */ @Autowired private UserLoginFailureHandler userLoginFailureHandler; /** * 用户登出成功处理类 */ @Autowired private UserLogoutSuccessHandler userLogoutSuccessHandler; /** * 用户登录验证 */ @Autowired private UserAuthenticationProvider userAuthenticationProvider; /** * 用户权限注解 */ @Autowired private UserPermissionEvaluator userPermissionEvaluator; /** * 加密方式,没使用这种加密方式 */ @Bean public BCryptPasswordEncoder bCryptPasswordEncoder() { return new BCryptPasswordEncoder(); } /** * 注入自定义PermissionEvaluator * * @return */ @Bean public DefaultWebSecurityExpressionHandler userSecurityExpressionHandler() { DefaultWebSecurityExpressionHandler handler = new DefaultWebSecurityExpressionHandler(); handler.setPermissionEvaluator(userPermissionEvaluator); return handler; } /** * 用户登录验证 */ @Override protected void configure(AuthenticationManagerBuilder auth) { auth.authenticationProvider(userAuthenticationProvider); } //@Value("${jwt.whiteList}") private String whiteList = "zhangsan,lisi";//白名单,这里是不做验证的方法 /** * 安全权限配置 */ @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() // 权限配置 .antMatchers(whiteList.split(",")).permitAll()// 获取白名单(不进行权限验证) //.anyRequest().authenticated() // 其他的需要登陆后才能访问 .and().httpBasic().authenticationEntryPoint(userNotLoginHandler) // 配置未登录处理类 .and().formLogin().loginProcessingUrl("/user/login")// 配置登录URL //.and().formLogin().loginPage("/user/login")// 配置登录URL .successHandler(userLoginSuccessHandler) // 配置登录成功处理类 .failureHandler(userLoginFailureHandler) // 配置登录失败处理类 .and().logout().logoutUrl("/logout/submit")// 配置登出地址 .logoutSuccessHandler(userLogoutSuccessHandler) // 配置用户登出处理类 .and().logout() //退出登录相关配置 .logoutSuccessUrl("/page/index") //退出成功后跳转的页面 .deleteCookies("JSESSIONID") //退出时要删除的Cookies的名字 .and().exceptionHandling().accessDeniedHandler(userAccessDeniedHandler)// 配置没有权限处理类 .and().cors()// 开启跨域 .and().csrf().disable(); // 禁用跨站请求伪造防护 //http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); // 禁用session(使用Token认证) //http.headers().cacheControl(); // 禁用缓存 /*http.headers() .frameOptions().sameOrigin() .httpStrictTransportSecurity().disable();*/ //http.addFilter(new JWTAuthenticationFilter(authenticationManager())); 添加JWT过滤器,这一版就不写jtw取代session会话功能了 http.headers().frameOptions().disable(); } }
14.Md5Util.java
package com.dev.config.security; import java.security.MessageDigest; /** * @author 李庆伟 * @date 2021/7/28 15:54 */ public class Md5Util { public final static String MD5(String s) { char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; try { // 密码+盐组合 byte[] btInput = s.getBytes(); // 获得MD5摘要算法的 MessageDigest 对象 MessageDigest mdInst = MessageDigest.getInstance("MD5"); // 使用指定的字节更新摘要 mdInst.update(btInput); // 获得密文 byte[] md = mdInst.digest(); // 把密文转换成十六进制的字符串形式 int j = md.length; char str[] = new char[j * 2]; int k = 0; for (int i = 0; i < j; i++) { byte byte0 = md[i]; str[k++] = hexDigits[byte0 >>> 4 & 0xf]; str[k++] = hexDigits[byte0 & 0xf]; } return new String(str); } catch (Exception e) { e.printStackTrace(); return null; } } /** * description 测试MD5加密方法 * * @param: [args] * @return * @Date 2021/5/19 */ public static void main(String[] args) { String pwd = Md5Util.MD5("123456"); System.out.println(pwd ); } }
15.SwaggerConfig.java
package com.dev.config; import com.dev.App8080; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.ParameterBuilder; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Parameter; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; import java.util.ArrayList; import java.util.List; /** * 文档配置 * * @return {@link } * @throws * @author 李庆伟 * @date 2021/7/19 17:15 */ @ConditionalOnWebApplication @Configuration @EnableSwagger2 public class SwaggerConfig { /** * swagger2的配置文件,这里可以配置swagger2的一些基本的内容,比如扫描的包等等 */ @Bean public Docket createRestApi() { List<Parameter> pars = new ArrayList<>(); ParameterBuilder token = new ParameterBuilder(); /*token.name("Authorization").description("Authorization") .modelRef(new ModelRef("string")) .parameterType("header") .required(false).build(); pars.add(token.build()); ParameterBuilder languageCode = new ParameterBuilder(); languageCode.name("languageCode").description("languageCode") .modelRef(new ModelRef("string")) .parameterType("header") .required(false).build(); pars.add(languageCode.build());*/ return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage(App8080.class.getPackage().getName())) .build() .globalOperationParameters(pars) .apiInfo(apiInfo()); } /** * //构建 api文档的详细信息函数 * @return */ private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("SOD LRP Application Server RESTful API") .version("1.0") .build(); } }
16.TSysUserController.java
package com.dev.controller; import com.dev.common.Result; import io.swagger.annotations.*; import lombok.extern.slf4j.Slf4j; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; /** * 系统用户服务 * @author 李庆伟 * @date 2021/7/19 17:04 */ @Slf4j @RequestMapping("tSysUser") @RestController @Api(value = "系统用户服务", tags = "系统用户服务") public class TSysUserController { @PreAuthorize("hasRole('ROLE_/tSysUser/findByPage')") @PostMapping("findByPage") @ApiOperation(value = "添加系统用户", notes = "添加系统用户", produces = "application/json") public Result findByPage(){ log.info("测试用户分页查询权限"); return Result.success("测试用户分页查询权限"); } @PreAuthorize("hasRole('ROLE_/tSysUser/add')") @PostMapping("add") @ApiOperation(value = "添加系统用户", notes = "添加系统用户", produces = "application/json") public Result add(){ log.info("测试用户添加权限"); return Result.success("测试用户添加权限"); } @PreAuthorize("hasRole('ROLE_/tSysUser/edit')") @PostMapping("edit") @ApiOperation(value = "添加系统用户", notes = "修改系统用户", produces = "application/json") public Result edit(){ log.info("测试用户编辑权限"); return Result.success("测试用户编辑权限"); } @PreAuthorize("hasRole('ROLE_/tSysUser/delete')") @PostMapping("delete") @ApiOperation(value = "删除系统用户", notes = "删除系统用户", produces = "application/json") public Result delete(){ log.info("测试用户删除权限"); return Result.success("测试用户删除权限"); } }
17.TSysResMapper.java
package com.dev.dao; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.dev.model.TSysRes; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import java.util.List; /** * @author 李庆伟 * @date 2021/7/19 17:06 */ @Mapper public interface TSysResMapper extends BaseMapper<TSysRes> { @Select("select " + " a.id, " + " a.name, " + " a.res_url, " + " a.permission, " + " a.res_type, " + " a.icon, " + " a.pid, " + " a.create_date " + "from " + " t_sys_res a " + "where a.res_type = '0' " + "order by a.create_date ") List<TSysRes> findAllForAdminMenu(); }
18.TSysRoleMapper.java
package com.dev.dao; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.dev.model.TSysRole; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import java.util.List; /** * @author 李庆伟 * @date 2021/7/19 17:06 */ @Mapper public interface TSysRoleMapper extends BaseMapper<TSysRole> { /** * 根据用户名查询用户有的角色 * [userId] * @return {@link List<TSysRole>} * @throws * @author 李庆伟 * @date 2021/7/27 14:40 */ @Select("SELECT r.* FROM t_sys_role r " + "LEFT JOIN t_sys_user_role ur ON ur.role_id = r.id " + "WHERE " + "ur.user_id = #{userId} ") List<TSysRole> findRoleByUserId(String userId); }
19.TSysRoleResMapper.java
package com.dev.dao; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.dev.model.TSysRoleRes; import org.apache.ibatis.annotations.Mapper; import java.util.List; import java.util.Map; /** * @author 李庆伟 * @date 2021/7/19 17:06 */ @Mapper public interface TSysRoleResMapper extends BaseMapper<TSysRoleRes> { List<String> selectRoleResByMap(Map<String, Object> map); }
20.TSysUserMapper.java
package com.dev.dao; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.dev.model.TSysUser; import org.apache.ibatis.annotations.Mapper; /** * @author 李庆伟 * @date 2021/7/19 17:06 */ @Mapper public interface TSysUserMapper extends BaseMapper<TSysUser> { }
21.TSysUserRoleMapper.java
package com.dev.dao; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.dev.model.TSysUserRole; import org.apache.ibatis.annotations.Mapper; /** * @author 李庆伟 * @date 2021/7/19 17:06 */ @Mapper public interface TSysUserRoleMapper extends BaseMapper<TSysUserRole> { }
22.SysUserDetails.java
package com.dev.model; import lombok.Data; import lombok.EqualsAndHashCode; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import java.io.Serializable; import java.util.Collection; /** * @author 李庆伟 * @date 2021/7/26 9:48 */ @Data @EqualsAndHashCode(callSuper = false) public class SysUserDetails extends TSysUser implements UserDetails, Serializable { private static final long serialVersionUID = 1L; /** * 用户角色 */ private Collection <GrantedAuthority> authorities; /** * 账号是否过期 */ private boolean isAccountNonExpired = false; /** * 账号是否锁定 */ private boolean isAccountNonLocked = false; /** * 证书是否过期 */ private boolean isCredentialsNonExpired = false; /** * 账号是否有效 */ private boolean isEnabled = true; /** * 获得用户权限 */ @Override public Collection<? extends GrantedAuthority> getAuthorities() { return authorities; } /** * 判断账号是否过期 */ @Override public boolean isAccountNonExpired() { return isAccountNonExpired; } /** * 判断账号是否锁定 */ @Override public boolean isAccountNonLocked() { return isAccountNonLocked; } /** * 判断证书是否过期 */ @Override public boolean isCredentialsNonExpired() { return isCredentialsNonExpired; } /** * 判断账号是否有效 */ @Override public boolean isEnabled() { return isEnabled; } }
23.TSysRes.java
package com.dev.model; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.util.Date; /** * 系统资源实体 * @return {@link } * @throws * @author 李庆伟 * @date 2021/7/22 9:25 */ @Data @TableName("t_sys_res") public class TSysRes { @TableId private String id;//主键 private String name;//资源名称 private String resUrl;//资源路径 private String permission;//做拦截的code private String resType;//0菜单 1按钮 private String pid;//父级id private String icon;//菜单图标 private String createUser;//创建人 private Date createDate;//创建时间 }
24.TSysRole.java
import lombok.Data; import java.util.Date; /** * 系统角色实体 * @author 李庆伟 * @date 2021/7/19 17:00 */ @Data @TableName("t_sys_role") public class TSysRole { @TableId private String id;//主键 private String roleName;//角色名称 private String roleExplain;//角色描述 private String createUser;//创建人 private Date createDate;//创建时间 }
25.TSysRoleRes.java
package com.dev.model; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; /** * 系统角色资源实体 * @author 李庆伟 * @date 2021/7/19 17:00 */ @Data @TableName("t_sys_role_res") public class TSysRoleRes { @TableId private String id;//主键 private String roleId;//角色id private String resId;//资源id }
26.TSysUser.java
package com.dev.model; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.io.Serializable; import java.util.Date; /** * 系统用户实体 * @author 李庆伟 * @date 2021/7/19 17:00 */ @Data @TableName("t_sys_user") public class TSysUser implements Serializable { private static final long serialVersionUID = 1L; @TableId private String id;//主键 private String username;//用户名 private String password;//密码 private String nickName;//昵称 private String cellPhone;//电话 private String mail;//邮件 private Date birthday;//生日 private String status;//状态(0-正常,1-禁用,2-删除) private String accountType;//1系统账号 2客户账号 private String inviteCode;//邀请码 private String sex;//性别:0男 1女 private String address;//地址 private Integer upNum;//获赞总量 private Integer readNum;//文章被阅读总量 private String sign;//签名 private String pictureId;//用户头像 private String createUser;//创建人 private Date createDate;//创建时间 }
27.TSysUserRole.java
package com.dev.model; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; /** * 系统用户角色实体 * @author 李庆伟 * @date 2021/7/19 17:00 */ @Data @TableName("t_sys_user_role") public class TSysUserRole { @TableId private String id;//主键 private String userId;//用户名id private String roleId;//角色id }
28.SysUserDetailsService.java
package com.dev.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.dev.model.SysUserDetails; import com.dev.model.TSysRes; import com.dev.model.TSysUser; import com.dev.dao.TSysResMapper; import com.dev.service.TSysResService; import com.dev.service.TSysUserService; import com.github.pagehelper.util.StringUtil; import org.springframework.beans.BeanUtils; 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.Service; import javax.annotation.Resource; import java.util.HashSet; import java.util.List; import java.util.Set; /** * @author 李庆伟 * @date 2021/7/26 10:44 */ @Service public class SysUserDetailsService implements UserDetailsService { @Autowired private TSysUserService tSysUserService; @Resource private TSysResMapper tSysResMapper; @Autowired private TSysResService tSysResService; /** * 说明:重写UserDetailsService中的loadUserByUsername,就是查询用户详细信息封装到 UserDetails * 业务: * ①如果是admin会拥有全部权限 * ②如果不是admin就去查用户信息和用户拥有的权限 * [username] * @return {@link UserDetails} * @throws * @author 李庆伟 * @date 2021/12/7 19:49 */ @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { List<TSysRes> resList = null; if(username.equals("admin")){ TSysUser tSysUser = new TSysUser(); tSysUser.setId("admin"); tSysUser.setUsername("admin"); tSysUser.setNickName("系统管理员"); SysUserDetails sysUserDetails = new SysUserDetails(); BeanUtils.copyProperties(tSysUser, sysUserDetails); Set<GrantedAuthority> authorities = new HashSet<>(); // 角色集合 //admin用户有的资源集合 resList = tSysResMapper.selectList(new QueryWrapper<>()); for (int i = 0; i < resList.size() ; i++) { if(StringUtil.isNotEmpty(resList.get(i).getPermission())){ authorities.add(new SimpleGrantedAuthority("ROLE_" + resList.get(i).getPermission())); } } sysUserDetails.setAuthorities(authorities); return sysUserDetails; } TSysUser tSysUser = tSysUserService.findByUsername(username); if (tSysUser != null) { SysUserDetails sysUserDetails = new SysUserDetails(); BeanUtils.copyProperties(tSysUser, sysUserDetails); Set<GrantedAuthority> authorities = new HashSet<>(); // 角色集合 resList = tSysResService.findResByUserId(sysUserDetails.getId());//当前用户有的资源集合 if(resList != null){ for (int i = 0; i < resList.size() ; i++) { if(StringUtil.isNotEmpty(resList.get(i).getPermission())){ authorities.add(new SimpleGrantedAuthority("ROLE_" + resList.get(i).getPermission())); } } } sysUserDetails.setAuthorities(authorities); return sysUserDetails; } return null; } }
29.TSysResServiceImpl.java
package com.dev.service.impl; import com.dev.model.TSysRes; import com.dev.model.TSysRole; import com.dev.dao.TSysResMapper; import com.dev.dao.TSysRoleMapper; import com.dev.dao.TSysRoleResMapper; import com.dev.service.TSysResService; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 系统角色服务 * @author 李庆伟 * @date 2021/7/19 17:06 */ @Service public class TSysResServiceImpl implements TSysResService { @Resource private TSysResMapper tSysResMapper; @Resource private TSysRoleMapper tSysRoleMapper; @Resource private TSysRoleResMapper tSysRoleResMapper; /** * 根据用户id查询用户拥有的资源 * [userId] * @return {@link List< TSysRes>} * @throws * @author 李庆伟 * @date 2021/12/7 20:34 */ @Override public List<TSysRes> findResByUserId(String userId) { //获取用户有的角色 //根据当前登录用户获取角色 List<TSysRole> roleList = tSysRoleMapper.findRoleByUserId(userId); if(roleList == null || roleList.size() == 0){ //如果用户没有角色返回没有权限 return null; } //根据角色获取菜单资源id关系集合 Map<String,Object> map = new HashMap<>(); map.put("roleList",roleList); List<String> tSysRoleResList = tSysRoleResMapper.selectRoleResByMap(map); if(tSysRoleResList == null || tSysRoleResList.size() == 0){ //如果用户没有角色返回没有权限 return null; } //根据资源id获取菜单资源 return tSysResMapper.selectBatchIds(tSysRoleResList); } }
30.TSysRoleResServiceImpl.java
package com.dev.service.impl; import com.dev.service.TSysRoleResService; import org.springframework.stereotype.Service; /** * 系统角色资源服务 * @author 李庆伟 * @date 2021/7/19 17:06 */ @Service public class TSysRoleResServiceImpl implements TSysRoleResService { }
31.TSysRoleServiceImpl.java
package com.dev.service.impl; import com.dev.service.TSysRoleService; import org.springframework.stereotype.Service; /** * 系统角色服务 * @author 李庆伟 * @date 2021/7/19 17:06 */ @Service public class TSysRoleServiceImpl implements TSysRoleService { }
32.TSysUserRoleServiceImpl.java
package com.dev.service.impl; import com.dev.service.TSysUserRoleService; import org.springframework.stereotype.Service; /** * 系统用户角色服务 * @author 李庆伟 * @date 2021/7/19 17:06 */ @Service public class TSysUserRoleServiceImpl implements TSysUserRoleService { }
33.TSysUserServiceImpl.java
package com.dev.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.dev.model.TSysUser; import com.dev.dao.TSysUserMapper; import com.dev.service.TSysUserService; import org.springframework.stereotype.Service; import javax.annotation.Resource; /** * 系统用户服务 * @author 李庆伟 * @date 2021/7/19 17:06 */ @Service public class TSysUserServiceImpl implements TSysUserService { @Resource private TSysUserMapper tSysUserMapper; /** * 根据用户名查询用户 * [username] * @return {@link TSysUser} * @throws * @author 李庆伟 * @date 2021/7/27 11:11 */ public TSysUser findByUsername(String username) { QueryWrapper queryWrapper = new QueryWrapper(); queryWrapper.eq("username",username); return tSysUserMapper.selectOne(queryWrapper); } }
34.TSysResService.java
package com.dev.service; import com.dev.model.TSysRes; import java.util.List; /** * @author 李庆伟 * @date 2021/7/19 17:05 */ public interface TSysResService { List<TSysRes> findResByUserId(String userId); }
35.TSysRoleResService.java
package com.dev.service; /** * @author 李庆伟 * @date 2021/7/19 17:05 */ public interface TSysRoleResService { }
36.TSysRoleService.java
package com.dev.service; /** * @author 李庆伟 * @date 2021/7/19 17:05 */ public interface TSysRoleService { }
37.TSysUserRoleService.java
package com.dev.service; /** * @author 李庆伟 * @date 2021/7/19 17:05 */ public interface TSysUserRoleService { }
38.TSysUserService.java
package com.dev.service; import com.dev.model.TSysUser; /** * @author 李庆伟 * @date 2021/7/19 17:05 */ public interface TSysUserService { TSysUser findByUsername(String username); }
39.App8080.java
package com.dev; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @return {@link } * @throws * @author 李庆伟 * @date 2021/7/14 14:41 */ @SpringBootApplication public class App8080 { public static void main(String[] args) { SpringApplication.run(App8080.class,args); } }
40.TSysRoleResMapper.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.dev.dao.TSysRoleResMapper"> <!--根据父id集和查询资源 (包括菜单和按钮)--> <select id="selectRoleResByMap" parameterType="java.util.List" resultType="java.lang.String"> select a.res_id from t_sys_role_res a where 1 = 1 and a.role_id in <foreach item="item" index="index" collection="roleList" open="(" separator="," close=")"> #{item.id} </foreach> </select> </mapper>
库表设计:
sql:直接导入数据库中行了,用户表密码是Md5加密, 密码为:123456
/* Navicat Premium Data Transfer Source Server : 本机数据库mysql Source Server Type : MySQL Source Server Version : 50143 Source Host : localhost:3306 Source Schema : my_security_test Target Server Type : MySQL Target Server Version : 50143 File Encoding : 65001 Date: 08/12/2021 21:17:27 */ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for t_sys_res -- ---------------------------- DROP TABLE IF EXISTS `t_sys_res`; CREATE TABLE `t_sys_res` ( `id` varchar(38) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '资源id', `name` varchar(38) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '资源名称', `res_url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '资源路径', `permission` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '资源code', `res_type` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '0菜单 1按钮', `pid` varchar(38) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '父级id', `create_user` varchar(38) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, `create_date` datetime DEFAULT NULL, `icon` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '菜单图标' ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '系统-资源表【菜单】' ROW_FORMAT = Compact; -- ---------------------------- -- Records of t_sys_res -- ---------------------------- INSERT INTO `t_sys_res` VALUES ('101', '用户添加', '/tSysUser/add', '/tSysUser/add', '1', '100', NULL, NULL, ''); INSERT INTO `t_sys_res` VALUES ('100', '用户管理', '/tSysUser/findByPage', '/tSysUser/findByPage', '0', '', NULL, NULL, 'fa fa-snowflake-o'); INSERT INTO `t_sys_res` VALUES ('102', '用户修改', '/tSysUser/edit', '/tSysUser/edit', '1', '100', NULL, NULL, 'fa fa-home'); INSERT INTO `t_sys_res` VALUES ('103', '用户删除', '/tSysUser/delete', '/tSysUser/delete', '1', '100', NULL, NULL, 'fa fa-home'); -- ---------------------------- -- Table structure for t_sys_role -- ---------------------------- DROP TABLE IF EXISTS `t_sys_role`; CREATE TABLE `t_sys_role` ( `id` varchar(38) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '角色id', `role_name` varchar(38) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '角色名称', `role_explain` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '描述', `create_user` varchar(38) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '创建人', `create_date` datetime DEFAULT NULL COMMENT '创建时间' ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '系统-角色表' ROW_FORMAT = Compact; -- ---------------------------- -- Records of t_sys_role -- ---------------------------- INSERT INTO `t_sys_role` VALUES ('277144172094291968', '部门经理', '部门经理', NULL, '2021-08-27 10:22:51'); INSERT INTO `t_sys_role` VALUES ('277144675716956160', '普通员工', '普通员工', NULL, '2021-08-27 10:24:51'); INSERT INTO `t_sys_role` VALUES ('277646459757658112', '测试员工', '测试员工', '', '2021-08-28 19:38:46'); -- ---------------------------- -- Table structure for t_sys_role_res -- ---------------------------- DROP TABLE IF EXISTS `t_sys_role_res`; CREATE TABLE `t_sys_role_res` ( `id` varchar(38) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '主键', `role_id` varchar(38) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '角色id', `res_id` varchar(38) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '资源id' ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '系统-角色资源表中间表' ROW_FORMAT = Compact; -- ---------------------------- -- Records of t_sys_role_res -- ---------------------------- INSERT INTO `t_sys_role_res` VALUES ('1234', '277144675716956160', '101'); INSERT INTO `t_sys_role_res` VALUES ('12345', '277144675716956160', '100'); INSERT INTO `t_sys_role_res` VALUES ('123456', '277144172094291968', '100'); INSERT INTO `t_sys_role_res` VALUES ('123457', '277144172094291968', '101'); INSERT INTO `t_sys_role_res` VALUES ('123458', '277144172094291968', '102'); -- ---------------------------- -- Table structure for t_sys_user -- ---------------------------- DROP TABLE IF EXISTS `t_sys_user`; CREATE TABLE `t_sys_user` ( `id` varchar(38) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '主键', `username` varchar(38) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名', `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码', `nick_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '昵称', `cell_phone` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '手机号', `mail` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '邮件', `birthday` datetime DEFAULT NULL COMMENT '生日', `status` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '状态(0-正常,1-删除,2-禁用)', `account_type` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '1系统账号 2客户账号', `invite_code` varchar(60) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '邀请码', `sex` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '性别:0男 1女', `up_num` int(11) DEFAULT NULL COMMENT '所有获赞总量', `read_num` int(11) DEFAULT NULL COMMENT '所有文章阅读总量', `address` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '地址', `create_user` varchar(38) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '创建人', `create_date` datetime DEFAULT NULL COMMENT '创建时间', `sign` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '用户签名', `picture_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '用户头像' ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '系统-用户表' ROW_FORMAT = Compact; -- ---------------------------- -- Records of t_sys_user -- ---------------------------- INSERT INTO `t_sys_user` VALUES ('276866508766838784', 'liqingwei', 'E10ADC3949BA59ABBE56E057F20F883E', '李庆伟', '15801174628', 'liqingwei01@cnpc.cn', NULL, '0', '1', '3781941dd39446b89e98cb661766aade', NULL, 0, 0, NULL, NULL, '2021-08-26 15:59:31', NULL, NULL); INSERT INTO `t_sys_user` VALUES ('277657251341139964', 'zhangsan', 'E10ADC3949BA59ABBE56E057F20F883E', '张三', '15801174626', 'zhangsan@qq.com', '2021-08-04 00:00:00', '0', '1', 'ea819ca462914e938943752d48ae8bcc', '0', 0, 0, '河南北京北', 'admin', '2021-08-28 20:21:38', '啥也不是。。。', '287348042074423296'); -- ---------------------------- -- Table structure for t_sys_user_role -- ---------------------------- DROP TABLE IF EXISTS `t_sys_user_role`; CREATE TABLE `t_sys_user_role` ( `id` varchar(38) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '主键', `user_id` varchar(38) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户id', `role_id` varchar(38) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '角色id', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '系统-用户角色中间表' ROW_FORMAT = Compact; -- ---------------------------- -- Records of t_sys_user_role -- ---------------------------- INSERT INTO `t_sys_user_role` VALUES ('111', '276866508766838784', '277144675716956160'); INSERT INTO `t_sys_user_role` VALUES ('222', '277657251341139964', '277144172094291968'); SET FOREIGN_KEY_CHECKS = 1;
测试:访问路径均为POST请求。
使用Postman测试 liqingwei用户
http://localhost:8080/user/login?username=liqingwei&password=123456
http://localhost:8080/tSysUser/findByPage
http://localhost:8080/tSysUser/edit
http://localhost:8080/tSysUser/delete
使用Postman测试 zhangsan用户
http://localhost:8080/user/login?username=zhangsan&password=123456
http://localhost:8080/tSysUser/findByPage
http://localhost:8080/tSysUser/edit
http://localhost:8080/tSysUser/delete
下篇博客更新Springboot+Security+JWT