当前位置: 首页 > news >正文

网站建设总流程山东省城乡和住房建设厅网站

网站建设总流程,山东省城乡和住房建设厅网站,网站目录编辑审核的注意事项,快手自媒体平台Spring Securityjwtredis自定义认证逻辑 权限控制 1.拦截访问基本思路 2.创建数据库表#xff1a;角色表#xff08;应该6个表#xff0c;这里只用用户表代替角色表#xff09;、权限表、路径表、角色-权限表、权限-路径表 /* SQLyog Professional v12.14 (64 bit) MySQL…Spring Securityjwtredis自定义认证逻辑 权限控制 1.拦截访问基本思路 2.创建数据库表角色表应该6个表这里只用用户表代替角色表、权限表、路径表、角色-权限表、权限-路径表 /* SQLyog Professional v12.14 (64 bit) MySQL - 5.7.40 : Database - assist_silkworm_db ********************************************************************* *//*!40101 SET NAMES utf8 */;/*!40101 SET SQL_MODE*/;/*!40014 SET OLD_UNIQUE_CHECKSUNIQUE_CHECKS, UNIQUE_CHECKS0 */; /*!40014 SET OLD_FOREIGN_KEY_CHECKSFOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS0 */; /*!40101 SET OLD_SQL_MODESQL_MODE, SQL_MODENO_AUTO_VALUE_ON_ZERO */; /*!40111 SET OLD_SQL_NOTESSQL_NOTES, SQL_NOTES0 */; CREATE DATABASE /*!32312 IF NOT EXISTS*/assist_silkworm_db /*!40100 DEFAULT CHARACTER SET latin1 */;USE assist_silkworm_db;/*Table structure for table t_path */ # 路径表 DROP TABLE IF EXISTS t_path;CREATE TABLE t_path (path_id bigint(19) NOT NULL COMMENT 路径表id,path varchar(200) NOT NULL COMMENT 路径名称,gmt_created datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间,gmt_modified datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间,PRIMARY KEY (path_id) ) ENGINEInnoDB DEFAULT CHARSETlatin1;/*Data for the table t_path */insert into t_path(path_id,path,gmt_created,gmt_modified) values (1607234202607067138,/**,2023-02-23 12:07:42,2023-02-23 12:12:47);/*Table structure for table t_permission */DROP TABLE IF EXISTS t_permission; # 权限表 CREATE TABLE t_permission (permission_id bigint(19) NOT NULL COMMENT 主键ID,permission varchar(255) NOT NULL COMMENT 权限,gmt_created datetime DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间,gmt_modified datetime DEFAULT CURRENT_TIMESTAMP COMMENT 更新时间,PRIMARY KEY (permission_id),UNIQUE KEY role (permission) ) ENGINEInnoDB DEFAULT CHARSETutf8;/*Data for the table t_permission */insert into t_permission(permission_id,permission,gmt_created,gmt_modified) values (1607234202607067138,ROLE_BIG_ADMIN,2023-02-23 12:10:07,2023-02-23 12:10:07);/*Table structure for table t_permission_path */ # 权限路径表 DROP TABLE IF EXISTS t_permission_path;CREATE TABLE t_permission_path (id int(11) NOT NULL AUTO_INCREMENT COMMENT 主键ID,permission_id bigint(19) NOT NULL COMMENT 权限Id,path_id bigint(19) NOT NULL COMMENT 权限对应的路径,gmt_created datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间,gmt_modified datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间,PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCREMENT2 DEFAULT CHARSETutf8;/*Data for the table t_permission_path */insert into t_permission_path(id,permission_id,path_id,gmt_created,gmt_modified) values (1,1607234202607067138,1607234202607067138,2023-02-23 12:13:59,2023-02-23 12:13:59);/*Table structure for table t_user */ # 用户表 DROP TABLE IF EXISTS t_user;CREATE TABLE t_user (user_id bigint(19) NOT NULL AUTO_INCREMENT COMMENT 主键,username varchar(100) NOT NULL COMMENT 账号,password varchar(100) NOT NULL COMMENT 密码,gmt_created datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间,gmt_modified datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间,is_del tinyint(1) NOT NULL DEFAULT 0 COMMENT 是否删除,PRIMARY KEY (user_id) ) ENGINEInnoDB AUTO_INCREMENT1607234202607067139 DEFAULT CHARSETutf8;/*Data for the table t_user */insert into t_user(user_id,username,password,gmt_created,gmt_modified,is_del) values (1607234202607067138,admin,$2a$10$GE0hWDRIksPXpZCDtTEFP.8EKi25OQ8PPvc6Q14YzSyzpkkQzDPxW,2022-12-26 12:37:50,2023-02-23 12:09:05,0);/*Table structure for table t_user_permission */DROP TABLE IF EXISTS t_user_permission; # 用户权限表 CREATE TABLE t_user_permission (id int(11) NOT NULL AUTO_INCREMENT COMMENT 主键ID,user_id bigint(19) NOT NULL COMMENT 用户Id,permission_id bigint(19) NOT NULL COMMENT 权限Id,gmt_created datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间,gmt_modified datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间,PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCREMENT3 DEFAULT CHARSETutf8;/*Data for the table t_user_permission */insert into t_user_permission(id,user_id,permission_id,gmt_created,gmt_modified) values (2,1607234202607067138,1607234202607067138,2023-02-23 12:13:06,2023-02-23 12:13:06);/*!40101 SET SQL_MODEOLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKSOLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKSOLD_UNIQUE_CHECKS */; /*!40111 SET SQL_NOTESOLD_SQL_NOTES */; 3.导入依赖 !-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security -- dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-security/artifactIdversion2.7.4/version /dependency [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J2aKwzdu-1677162858470)(SpringSecurity%20%20JWT-%E6%9D%83%E9%99%90%E6%8E%A7%E5%88%B6.assets/image-20230223222442753.png)] ###4.创建实现UserDestails的实现类 package com.rfos.assistsilkworm.config.security;import com.rfos.assistsilkworm.pojo.User; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails;import java.util.ArrayList; import java.util.Collection; import java.util.List;/*** author hjt* date 2022/10/4 20:55* description*/Data AllArgsConstructor NoArgsConstructor public class UserDetailsDTO implements UserDetails {private User user;private ListString permissionList;private Collection? extends GrantedAuthority authorities;Overridepublic Collection? extends GrantedAuthority getAuthorities() {ListGrantedAuthority grantedAuthorityList new ArrayList();for (String permission : permissionList) {//拥有的权限名SimpleGrantedAuthority simpleGrantedAuthority new SimpleGrantedAuthority(permission);grantedAuthorityList.add(simpleGrantedAuthority);}setAuthorities(grantedAuthorityList);return grantedAuthorityList;}Overridepublic String getPassword() {return user.getPassword();}Overridepublic String getUsername() {return user.getUsername();}Overridepublic boolean isAccountNonExpired() {return true;}Overridepublic boolean isAccountNonLocked() {return true;}Overridepublic boolean isCredentialsNonExpired() {return true;}Overridepublic boolean isEnabled() {return true;} } UserDetails类 UserDetails(位于org.springframework.security.core.userdetails包下)主要和用户信息有关的接口该接口是提供用户信息的核心接口。该接口实现仅仅存储用户的信息。后续会将该接口提供的用户信息封装到认证对象Authentication中去 public interface UserDetails extends Serializable {// 权限// 用户的权限集 默认需要添加ROLE_ 前缀Collection? extends GrantedAuthority getAuthorities();// 密码// 用户的加密后的密码 不加密会使用{noop}前缀String getPassword();// 用户名String getUsername();// 帐户未过期boolean isAccountNonExpired();// 帐户未锁定boolean isAccountNonLocked();// 凭证是否过期boolean isCredentialsNonExpired();// 用户是否可用boolean isEnabled(); } 角色表等各个表对应的实体类 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ToXl9gvR-1677162858471)(SpringSecurity%20%20JWT-%E6%9D%83%E9%99%90%E6%8E%A7%E5%88%B6.assets/image-20230223222708838.png)] package com.rfos.assistsilkworm.pojo;import com.baomidou.mybatisplus.annotation.*;import java.util.Date; import java.io.Serializable; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor;/*** p* * /p** author rfos* since 2023-02-23*/ Data AllArgsConstructor NoArgsConstructor EqualsAndHashCode(callSuper false) TableName(t_user) ApiModel(valueUser对象, description) public class User implements Serializable {private static final long serialVersionUID 1L;ApiModelProperty(value 主键)TableId(value user_id, type IdType.ASSIGN_ID)private Long userId;ApiModelProperty(value 账号)private String username;ApiModelProperty(value 密码)private String password;ApiModelProperty(创建时间)//创建时间由SQL完成TableField(fill FieldFill.INSERT)private Date gmtCreated;ApiModelProperty(更新时间)//更新时间由数据库完成TableField(fill FieldFill.INSERT_UPDATE)private Date gmtModified;ApiModelProperty(value 是否删除)private Boolean isDel;}package com.rfos.assistsilkworm.pojo;import com.baomidou.mybatisplus.annotation.*;import java.util.Date; import java.io.Serializable;import com.fasterxml.jackson.annotation.JsonIgnore; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import springfox.documentation.annotations.ApiIgnore;/*** p* * /p** author rfos* since 2023-02-23*/ Data AllArgsConstructor NoArgsConstructor EqualsAndHashCode(callSuper false) TableName(t_path) ApiModel(valuePath对象, description) public class Path implements Serializable {private static final long serialVersionUID 1L;ApiModelProperty(value 路径表id)TableId(value path_id, type IdType.ASSIGN_ID)private Long pathId;ApiModelProperty(value 路径名称)private String path;ApiModelProperty(创建时间)//创建时间由SQL完成TableField(fill FieldFill.INSERT)private Date gmtCreated;ApiModelProperty(更新时间)//更新时间由数据库完成TableField(fill FieldFill.INSERT_UPDATE)private Date gmtModified;} package com.rfos.assistsilkworm.pojo;import com.baomidou.mybatisplus.annotation.*;import java.util.Date; import java.io.Serializable; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor;/*** p* * /p** author rfos* since 2023-02-23*/ Data AllArgsConstructor NoArgsConstructor EqualsAndHashCode(callSuper false) TableName(t_permission) ApiModel(valuePermission对象, description) public class Permission implements Serializable {private static final long serialVersionUID 1L;ApiModelProperty(value 主键ID)TableId(value permission_id, type IdType.ASSIGN_ID)private Long permissionId;ApiModelProperty(value 权限)private String permission;ApiModelProperty(创建时间)//创建时间由SQL完成TableField(fill FieldFill.INSERT)private Date gmtCreated;ApiModelProperty(更新时间)//更新时间由数据库完成TableField(fill FieldFill.INSERT_UPDATE)private Date gmtModified;}package com.rfos.assistsilkworm.pojo;import com.baomidou.mybatisplus.annotation.*;import java.util.Date; import java.io.Serializable; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor;/*** p* * /p** author rfos* since 2023-02-23*/ Data AllArgsConstructor NoArgsConstructor EqualsAndHashCode(callSuper false) TableName(t_permission_path) ApiModel(valuePermissionPath对象, description) public class PermissionPath implements Serializable {private static final long serialVersionUID 1L;ApiModelProperty(value 主键ID)TableId(value id, type IdType.AUTO)private Integer id;ApiModelProperty(value 权限Id)private Long permissionId;ApiModelProperty(value 权限对应的路径)private Long pathId;ApiModelProperty(创建时间)//创建时间由SQL完成TableField(fill FieldFill.INSERT)private Date gmtCreated;ApiModelProperty(更新时间)//更新时间由数据库完成TableField(fill FieldFill.INSERT_UPDATE)private Date gmtModified;}package com.rfos.assistsilkworm.pojo;import com.baomidou.mybatisplus.annotation.*;import java.util.Date; import java.io.Serializable; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor;/*** p* * /p** author rfos* since 2023-02-23*/ Data AllArgsConstructor NoArgsConstructor EqualsAndHashCode(callSuper false) TableName(t_user_permission) ApiModel(valueUserPermission对象, description) public class UserPermission implements Serializable {private static final long serialVersionUID 1L;ApiModelProperty(value 主键ID)TableId(value id, type IdType.AUTO)private Integer id;ApiModelProperty(value 用户Id)private Long userId;ApiModelProperty(value 权限Id)private Long permissionId;ApiModelProperty(创建时间)//创建时间由SQL完成TableField(fill FieldFill.INSERT)private Date gmtCreated;ApiModelProperty(更新时间)//更新时间由数据库完成TableField(fill FieldFill.INSERT_UPDATE)private Date gmtModified;} 5.创建自定义认证逻辑-UserDetailsService的实现类-UserDetailServiceImpl类 UserDetailsService接口 package org.springframework.security.core.userdetails; public interface UserDetailsService {UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException; }UserDetailServiceImpl类 package com.rfos.assistsilkworm.config.security;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.rfos.assistsilkworm.pojo.Permission; import com.rfos.assistsilkworm.pojo.User; import com.rfos.assistsilkworm.pojo.UserPermission; import com.rfos.assistsilkworm.service.PermissionService; import com.rfos.assistsilkworm.service.UserPermissionService; import com.rfos.assistsilkworm.service.UserService; 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 org.springframework.util.ObjectUtils;import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors;/*** author hjt* date 2022/10/5 11:24* description*/ Service(userDetailsServiceImpl) public class UserDetailsServiceImpl implements UserDetailsService {//用户业务Autowiredprivate UserService userService;Autowiredprivate PermissionService permissionService;Autowiredprivate UserPermissionService userPermissionService;/*重写方法username: 需要其数据的用户的用户名UsernameNotFoundException 找不到用户的异常*/Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {//获取用户并判断是否存在User user userService.getByName(username);if(ObjectUtils.isEmpty(user)){return null;}//封装用户信息至对应的认证类中UserDetailsDTO userDetailsDTO new UserDetailsDTO();userDetailsDTO.setUser(user);//TODO 获取角色对应的权限ListUserPermission userPermissions userPermissionService.list(new QueryWrapperUserPermission().eq(user_id, user.getUserId()));//TODO 获取权限id对应的所有权限ListString pathList new ArrayList();for (UserPermission userPermission : userPermissions) {ListPermission permissionList permissionService.list(new QueryWrapperPermission().eq(permission_id, userPermission.getPermissionId()));pathList.addAll(permissionList.stream().map(data- data.getPermission()).collect(Collectors.toList()));}userDetailsDTO.setPermissionList(pathList);return userDetailsDTO;}}6.JwtUtil工具类说明 /*** JWT工具类*/ public class JwtUtil {//有效期为public static final Long JWT_TTL 60 * 60 * 1000L;// 60 * 60 *1000 一个小时//设置秘钥明文public static final String JWT_KEY sangeng;public static String getUUID() {//随机生成token字符串String token UUID.randomUUID().toString().replaceAll(-, );return token;}/*** 生成jtw** param subject token中要存放的数据json格式* return*/public static String createJWT(String subject) {JwtBuilder builder getJwtBuilder(subject, null, getUUID());// 设置过期时间return builder.compact();}/*** 生成jtw** param subject token中要存放的数据json格式* param ttlMillis token超时时间* return*/public static String createJWT(String subject, Long ttlMillis) {JwtBuilder builder getJwtBuilder(subject, ttlMillis, getUUID());// 设置过期时间return builder.compact();}private static JwtBuilder getJwtBuilder(String subject, Long ttlMillis, String uuid) {//签名的算法SignatureAlgorithm signatureAlgorithm SignatureAlgorithm.HS256;//生成获取密钥SecretKey secretKey generalKey();long nowMillis System.currentTimeMillis();Date now new Date(nowMillis);if (ttlMillis null) {ttlMillis JwtUtil.JWT_TTL;}long expMillis nowMillis ttlMillis;Date expDate new Date(expMillis);return Jwts.builder().setId(uuid) //唯一的ID.setSubject(subject) // 主题 可以是JSON数据.setIssuer(sg) // 签发者.setIssuedAt(now) // 签发时间.signWith(signatureAlgorithm, secretKey) //使用HS256对称加密算法签名, 第二个参数为秘钥.setExpiration(expDate);//设置过期时间}/*** 创建token** param id* param subject* param ttlMillis* return*/public static String createJWT(String id, String subject, Long ttlMillis) {JwtBuilder builder getJwtBuilder(subject, ttlMillis, id);// 设置过期时间return builder.compact();}/*** 生成加密后的秘钥 secretKey** return*/public static SecretKey generalKey() {byte[] encodedKey Base64.getDecoder().decode(JwtUtil.JWT_KEY);SecretKey key new SecretKeySpec(encodedKey, 0, encodedKey.length, AES);return key;}/*** 解析** param jwt* return* throws Exception*/public static Claims parseJWT(String jwt) throws Exception {SecretKey secretKey generalKey();return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwt).getBody();} }7.创建过滤器JwtAuthenticationTokenFilter类拦截指定路径验证访问信息 OncePerRequestFilter继承OncePerRequestFilter用于继承实现并在每次请求时只执行一次过滤 package com.rfos.assistsilkworm.config.security;import com.alibaba.fastjson.JSONObject; import com.rfos.assistsilkworm.config.redis.RedisUtils; import com.rfos.assistsilkworm.config.security.UserDetailsDTO; import com.rfos.assistsilkworm.constant.CommonConstants; import com.rfos.assistsilkworm.enums.ResultCode; import com.rfos.assistsilkworm.exception.ApiException; import com.rfos.assistsilkworm.util.IPAddrUtil; import com.rfos.assistsilkworm.util.JwtUtils; import io.jsonwebtoken.Claims; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.filter.OncePerRequestFilter;import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Objects;/*** date 2022/10/4*/ Slf4j Component public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {Autowiredprivate RedisUtils redisUtil;//保证一次请求只调用一次doFilterInternal方法Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {log.info(用户访问requestURI{},ip{}, request.getRequestURI(), IPAddrUtil.getIpAddress(request));//获取请求头中的tokenString token request.getHeader(CommonConstants.TOKEN_HEAD);//如果没有token则为第一次访问过滤器放行-将请求转发给过滤器链上下一个对象if (!StringUtils.hasText(token)) {filterChain.doFilter(request, response);return;}//解析tokenlog.info(获取到请求的token:\ntoken);String userId;try {Claims claims JwtUtils.parseJWT(token);userId claims.getSubject();} catch (Exception e) {e.printStackTrace();throw new ApiException(ResultCode.FAIL_AUTHORITY);}//从redis中获取用户信息Object obj redisUtil.get(CommonConstants.TOKEN_HEAD : userId);if (Objects.isNull(obj)) {throw new ApiException(ResultCode.EMPTY_USER);}//获取认证对象的信息UserDetailsDTO userDetailsDTO JSONObject.parseObject(obj.toString(), UserDetailsDTO.class);log.info(用户访问requestURI{},username{},ip{}, request.getRequestURI(), userDetailsDTO.getUsername(), IPAddrUtil.getIpAddress(request));//存入SecurityContextHolder//TODO 获取权限信息封装到Authentication中log.info(获取权限对应的所有权限:\n{},userDetailsDTO.getAuthorities());/*UsernamePasswordAuthenticationToken继承AbstractAuthenticationToken实现Authentication所以当在页面中输入用户名和密码之后首先会进入到UsernamePasswordAuthenticationToken验证(Authentication)然后生成的Authentication会被交由AuthenticationManager来进行管理而AuthenticationManager管理一系列的AuthenticationProvider而每一个Provider都会通UserDetailsService和UserDetail来返回一个以UsernamePasswordAuthenticationToken实现的带用户名和密码以及权限的Authentication*/UsernamePasswordAuthenticationToken authenticationToken new UsernamePasswordAuthenticationToken(userDetailsDTO, null, userDetailsDTO.getAuthorities());//将用户信息保存在安全上下文中SecurityContextHolder.getContext().setAuthentication(authenticationToken);//放行filterChain.doFilter(request, response);}} 8.创建自定义的UrlFilterInvocationSecurityMetadataSource类实现FilterInvocationSecurityMetadataSource接口 FilterInvocationSecurityMetadataSource拦截url判断用户url的访问权限是否包含该用户的权限 package com.rfos.assistsilkworm.config.security;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.rfos.assistsilkworm.pojo.Path; import com.rfos.assistsilkworm.pojo.PermissionPath; import com.rfos.assistsilkworm.service.PathService; import com.rfos.assistsilkworm.service.PermissionPathService; import com.rfos.assistsilkworm.service.PermissionService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.stereotype.Component; import org.springframework.util.AntPathMatcher; import org.springframework.util.CollectionUtils; import org.springframework.security.access.SecurityConfig;import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List;/*** author hjt* Package com.kdcloud.srd.security* date 2022/10/5 20:14* description 获取url匹配的用户权限**/ Component public class UrlFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {//没有权限private static final String ROLE_NONE ROLE_NONE;Autowiredprivate PermissionPathService permissionPathService;Autowiredprivate PermissionService permissionService;Autowiredprivate PathService pathService;//路径匹配类AntPathMatcher antPathMatcher new AntPathMatcher();//开放的路径private final static String[] OPEN_PATH_LIST new String[]{/**,/static/**,/templates/**,/index,/login,/admin/login,/home/**,/user/login,/swagger-ui.html,/swagger-resources/**,/*/api-docs,/webjars/**,/v2/**,/api/**,/actuator/**};//filterInvocation获取该请求Overridepublic CollectionConfigAttribute getAttributes(Object requestObj) throws IllegalArgumentException {FilterInvocation filterInvocation (FilterInvocation) requestObj;String requestUrl filterInvocation.getRequestUrl();System.out.println(请求路径urlrequestUrl);//开放部分路径//静态资源不拦截if(isMatcherAllowedRequest(filterInvocation)){return null;}// 数据库中所有urlListPath pathList pathService.list();pathList.forEach(value- System.out.println(value.getPath()));for (Path path : pathList) {// 获取该url所对应的权限boolean match antPathMatcher.match(path.getPath(), requestUrl);System.out.println(match);if (match) {System.out.println(匹配的路径url\npath);//获取路径对应的所有权限ListPermissionPath permissionPaths permissionPathService.list(new QueryWrapperPermissionPath().eq(path_id, path.getPathId()));ListString permissionPathList new ArrayList();if (!CollectionUtils.isEmpty(permissionPaths)){for (PermissionPath permissionPath : permissionPaths) {String roleName permissionService.getById(permissionPath.getPermissionId()).getPermission();permissionPathList.add(roleName);}}// 能访问url对应角色权限信息System.out.println(能访问url对应角色权限信息:permissionPathList);return SecurityConfig.createList(permissionPathList.stream().toArray(String[]::new));}}// 如果数据中没有找到相应url资源则为非法访问return SecurityConfig.createList(ROLE_NONE);}/*** 判断当前请求是否在允许请求的范围内* param fi 当前请求* return 是否在范围中*/private boolean isMatcherAllowedRequest(FilterInvocation fi){return allowedRequest().stream().map(AntPathRequestMatcher::new).filter(requestMatcher - requestMatcher.matches(fi.getHttpRequest())).toArray().length 0;}/*** return 定义允许请求的列表*/private ListString allowedRequest(){return Arrays.asList(OPEN_PATH_LIST);}Overridepublic CollectionConfigAttribute getAllConfigAttributes() {return null;}/*** 表示返回的对象是否支持校验* param aClass* return*/Overridepublic boolean supports(Class? aClass) {return FunctionalInterface.class.isAssignableFrom(aClass);}} 9.决策访问处理器创建自定义的JwtAccessDeniedManager实现AccessDeniedManager接口 package com.rfos.assistsilkworm.config.security;import org.springframework.security.access.AccessDecisionManager; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.authentication.InsufficientAuthenticationException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.stereotype.Component;import java.util.Collection;/*** author hjt* date 2022/10/5 23:29* description决策访问处理器创建自定义的JwtAccessDeniedManager实现AccessDeniedManager接口*/ Component public class JwtAccessDeniedManager implements AccessDecisionManager {/*** auth认证信息* collection角色信息*/Overridepublic void decide(Authentication auth, Object o, CollectionConfigAttribute collection) throws AccessDeniedException, InsufficientAuthenticationException {Collection? extends GrantedAuthority auths auth.getAuthorities();for (ConfigAttribute configAttribute : collection) {if (ROLE_LOGIN.equals(configAttribute.getAttribute()) auth instanceof UsernamePasswordAuthenticationToken) {return;}for (GrantedAuthority authority : auths) {if (configAttribute.getAttribute().equals(authority.getAuthority())) {return;}}}throw new AccessDeniedException(权限不足);}Overridepublic boolean supports(ConfigAttribute configAttribute) {return true;}Overridepublic boolean supports(Class? aClass) {return true;} } 10.创建Spring Security的配置类securityConfig package com.rfos.assistsilkworm.config.security;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.ObjectPostProcessor; 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.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.access.AccessDeniedHandler;Configuration EnableGlobalMethodSecurity(prePostEnabled true) //开启注解匹配 public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {//自动装配自定义逻辑AutowiredQualifier(userDetailsServiceImpl)private UserDetailsService userDetailsService;//过滤器JwtAuthenticationTokenFilterAutowiredprivate JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;//用户请求处理过程中遇到认证异常时被ExceptionTranslationFilter用于开启特定认证方案(authentication schema)的认证流程Autowiredprivate AuthenticationEntryPoint authenticationEntryPoint;//拒绝访问处理Autowiredprivate AccessDeniedHandler accessDeniedHandler;//决策处理器Autowiredprivate JwtAccessDeniedManager jwtAccessDeniedManager;//请求访问url处理过滤器Autowiredprivate UrlFilterInvocationSecurityMetadataSource urlFilterInvocationSecurityMetadataSource;//密码加密Beanpublic PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}//加密密码public static void main(String[] args) {SpringSecurityConfig springSecurityConfig new SpringSecurityConfig();PasswordEncoder passwordEncoder springSecurityConfig.passwordEncoder();String encode passwordEncoder.encode(admin);System.out.println(加密后的密码:encode);}//配置访问路径Overrideprotected void configure(HttpSecurity http) throws Exception {http//关闭csrf.csrf().disable()//不通过Session获取SecurityContext.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);//把token校验过滤器添加到过滤器链中http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);//请求需要经过权限认证http.authorizeRequests().anyRequest().authenticated()//自定义的元数据源和权限决策配置.withObjectPostProcessor(new ObjectPostProcessorFilterSecurityInterceptor() {Overridepublic O extends FilterSecurityInterceptor O postProcess(O obj) {obj.setSecurityMetadataSource(urlFilterInvocationSecurityMetadataSource);obj.setAccessDecisionManager(jwtAccessDeniedManager);return obj;}});//配置异常处理器 自定义的http.exceptionHandling()//配置认证失败处理器.authenticationEntryPoint(authenticationEntryPoint).accessDeniedHandler(accessDeniedHandler);//允许跨域http.cors();}BeanOverridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {//使用自己的UserDetailsServiceauth.userDetailsService(userDetailsService);}} 11.创建登录接口生成封装验证信息 package com.rfos.assistsilkworm.service;import com.baomidou.mybatisplus.extension.service.IService; import com.rfos.assistsilkworm.common.CommonResult; import com.rfos.assistsilkworm.dto.LoginDTO; import com.rfos.assistsilkworm.pojo.User;/*** p* 服务类* /p** author rfos* since 2022-11-02*/ public interface UserService extends IServiceUser {/*** 管理员登录验证* param loginDTO* return*/CommonResult login(LoginDTO loginDTO);User getByName(String username); } package com.rfos.assistsilkworm.service.impl;import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.github.pagehelper.util.StringUtil; import com.rfos.assistsilkworm.common.CommonResult; import com.rfos.assistsilkworm.config.redis.RedisUtils; import com.rfos.assistsilkworm.config.security.UserDetailsDTO; import com.rfos.assistsilkworm.constant.CommonConstants; import com.rfos.assistsilkworm.constant.RedisConstants; import com.rfos.assistsilkworm.dto.LoginDTO; import com.rfos.assistsilkworm.enums.ResultCode; import com.rfos.assistsilkworm.exception.ApiException; import com.rfos.assistsilkworm.mapper.UserMapper; import com.rfos.assistsilkworm.pojo.User; import com.rfos.assistsilkworm.service.UserService; import com.rfos.assistsilkworm.util.JwtUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional;import java.util.Objects;/*** p* 服务实现类* /p** author rfos* since 2022-11-02*/ Service Transactional(rollbackFor Exception.class) Slf4j public class UserServiceImpl extends ServiceImplUserMapper, User implements UserService {Autowiredprivate UserMapper userMapper;Autowiredprivate RedisUtils redisUtils;Autowiredprivate AuthenticationManager authenticationManager;Overridepublic CommonResult login(LoginDTO loginDTO) {//封装用户认证信息UsernamePasswordAuthenticationToken authenticationToken new UsernamePasswordAuthenticationToken(loginDTO.getUsername(), loginDTO.getPassword());Authentication authenticate authenticationManager.authenticate(authenticationToken);if (Objects.isNull(authenticate)) {throw new ApiException(用户名或密码错误);}//使用username生成token令牌UserDetailsDTO userDetailsDTO (UserDetailsDTO) authenticate.getPrincipal();String userId String.valueOf(userDetailsDTO.getUser().getUserId());String jwt JwtUtils.createJWT(userId);log.info(使用username生成token:\njwt);//将认证信息authenticate存入redislog.info(authenticate存入redis:\n{},userDetailsDTO);redisUtils.set(CommonConstants.TOKEN_HEAD : userId, JSONObject.toJSONString(userDetailsDTO));return CommonResult.success(jwt);}Overridepublic User getByName(String username) {QueryWrapperUser userQueryWrapper new QueryWrapper();if(StringUtil.isNotEmpty(username)){userQueryWrapper.eq(username,username);userQueryWrapper.eq(is_del, CommonConstants.IS_NOT_DEL);}User user userMapper.selectOne(userQueryWrapper);return user;}}
http://www.dnsts.com.cn/news/115029.html

相关文章:

  • 惠州网站外包泗阳网站设计
  • 如何做最强的社交网站改变wordpress后台
  • 南京网络科技网站建设华为手机价格大全
  • 安徽黄山网站建设海外一套crm国内一套crm
  • 旅游网站设计理念wordpress nginx 403
  • 广州知名网站建设wordpress循环文章
  • 租车网站模版wordpress 获取自定义字段
  • 柳市专业网站托管企业网站 设计
  • 建设工程质量检测网站免费信息网站建设平台
  • 网站建设技巧饣金手指排名2732岁学做网站
  • 海州区建设局网站app制作的网站
  • 企业建设网站的步骤是什么意思桂林生活网租房
  • 网站开发甘特图找代写文章写手
  • 国外产品展示网站源码长春是不是要封城了
  • 北京做网站多少钱阿里巴巴企业官网
  • 天津网站优朝阳区互联网公司排名
  • 深圳市宝安网站建设湖州seo排名
  • 卡盟网站制作教程wordpress设置首主导航
  • 最优的郑州网站建设寿光网站建设优化
  • 丰城建设网站seo网站seo
  • 网站建设费用价格网站建设微信文章
  • 建设网站多久到账软件下载网站哪个好
  • 买个网站域名要多少钱一年企业信息系统的分类
  • vue网站开发教程wordpress制造商单页
  • 做网页去哪些网站找素材较好临沂做网站的公司哪里有
  • 做IT的需要别人打开网站吗广东网站备案查询系统
  • 移动 网站 素材外贸商城网站系统
  • 中山网站排名网站如何备案 流程
  • 订制网站做DJ网站违法吗
  • 学科网站建设方案广州新塘网站建设推广公司