登陆成功返回token,并能刷新token,permission控制层待测试

lzm
廖忠美 2024-06-23 20:45:58 +08:00
parent ebe18670ca
commit 0b57a8711f
68 changed files with 720 additions and 145 deletions

View File

@ -0,0 +1,68 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="AliAccessStaticViaInstance" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AliArrayNamingShouldHaveBracket" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AliControlFlowStatementWithoutBraces" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AliDeprecation" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AliEqualsAvoidNull" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AliLongLiteralsEndingWithLowercaseL" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AliMissingOverrideAnnotation" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AliWrapperTypeEquality" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAbstractClassShouldStartWithAbstractNaming" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAbstractMethodOrInterfaceMethodMustUseJavadoc" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAvoidApacheBeanUtilsCopy" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAvoidCallStaticSimpleDateFormat" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAvoidCommentBehindStatement" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAvoidComplexCondition" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAvoidConcurrentCompetitionRandom" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAvoidDoubleOrFloatEqualCompare" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAvoidManuallyCreateThread" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAvoidMissUseOfMathRandom" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAvoidNegationOperator" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAvoidNewDateGetTime" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAvoidPatternCompileInMethod" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAvoidReturnInFinally" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAvoidStartWithDollarAndUnderLineNaming" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAvoidUseTimer" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaBigDecimalAvoidDoubleConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaBooleanPropertyShouldNotStartWithIs" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaClassCastExceptionWithSubListToArrayList" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaClassCastExceptionWithToArray" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaClassMustHaveAuthor" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaClassNamingShouldBeCamel" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaCollectionInitShouldAssignCapacity" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaCommentsMustBeJavadocFormat" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaConcurrentExceptionWithModifyOriginSubList" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaConstantFieldShouldBeUpperCase" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaCountDownShouldInFinally" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaDontModifyInForeachCircle" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaEnumConstantsMustHaveComment" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaExceptionClassShouldEndWithException" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaIbatisMethodQueryForList" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaLockShouldWithTryFinally" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaLowerCamelCaseVariableNaming" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaMethodReturnWrapperType" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaMethodTooLong" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaPackageNaming" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaPojoMustOverrideToString" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaPojoMustUsePrimitiveField" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaPojoNoDefaultValue" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaRemoveCommentedCode" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaServiceOrDaoClassShouldEndWithImpl" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaSneakyThrowsWithoutExceptionType" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaStringConcat" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaSwitchExpression" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaSwitchStatement" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaTestClassShouldEndWithTestNaming" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaThreadLocalShouldRemove" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaThreadPoolCreation" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaThreadShouldSetName" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaTransactionMustHaveRollback" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaUndefineMagicConstant" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaUnsupportedExceptionWithModifyAsList" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaUseQuietReferenceNotation" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaUseRightCaseForDateFormat" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MapOrSetKeyShouldOverrideHashCodeEquals" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

View File

@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager"> <component name="MavenProjectsManager">
@ -22,5 +21,7 @@
<component name="PDMPlugin"> <component name="PDMPlugin">
<option name="skipTestSources" value="false" /> <option name="skipTestSources" value="false" />
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK" /> <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/etl-auth/etl-auth-server/target" />
</component>
</project> </project>

File diff suppressed because one or more lines are too long

View File

@ -16,6 +16,10 @@
<spring-boot.version>2.6.13</spring-boot.version> <spring-boot.version>2.6.13</spring-boot.version>
</properties> </properties>
<dependencies> <dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId> <artifactId>spring-boot-starter-jdbc</artifactId>
@ -36,6 +40,12 @@
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.6.6</version>
<scope>compile</scope>
</dependency>
</dependencies> </dependencies>
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>

View File

@ -0,0 +1,33 @@
package com.auth.common.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("t_data_source")
public class PathPermission {
@TableId(value = "id",type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "权限代号")
private String permissionCode;
@ApiModelProperty(value = "路由层次")
private String hierarchy;
@ApiModelProperty(value = "路由")
private String path;
@ApiModelProperty(value = "功能描述")
private String description;
@ApiModelProperty(value = "状态 0-废弃 1-正在使用")
private boolean status;
}

View File

@ -0,0 +1,24 @@
package com.auth.common.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@TableName("t_role_source")
@AllArgsConstructor
@NoArgsConstructor
public class RolesPermission {
@TableId(value = "id",type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "权限代号")
private String permissionCode;
@ApiModelProperty(value = "角色")
private String role;
}

View File

@ -0,0 +1,23 @@
package com.auth.common.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@TableName("t_user")
public class UserAccount {
@TableId(value = "id",type = IdType.AUTO)
private Integer id;
@ApiModelProperty("角色")
private String roles;
@ApiModelProperty("名称")
private String username;
@ApiModelProperty("密码/")
private String password;
}

View File

@ -0,0 +1,8 @@
package com.auth.common.enums;
public class PermissionConstants {
public static final String ROLES = "roles";
public static final String CODE_LIST = "codeList";
public static final String ROLE = "role";
public static final String PERMISSION_CODE = "permission_code";
}

View File

@ -2,11 +2,12 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.auth.server</groupId> <parent>
<groupId>com.bwie</groupId>
<artifactId>etl-auth</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>etl-auth-server</artifactId> <artifactId>etl-auth-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>etl-auth-server</name>
<description>etl-auth-server</description>
<properties> <properties>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@ -15,10 +16,32 @@
<spring-cloud-alibaba.version>2021.0.5.0</spring-cloud-alibaba.version> <spring-cloud-alibaba.version>2021.0.5.0</spring-cloud-alibaba.version>
</properties> </properties>
<dependencies> <dependencies>
<!--shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<dependency> <dependency>
<groupId>com.bwie</groupId> <groupId>com.bwie</groupId>
<artifactId>etl-jwt-manage</artifactId> <artifactId>etl-jwt-manage</artifactId>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<artifactId>servlet-api</artifactId>
<groupId>javax.servlet</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.bwie</groupId>
<artifactId>etl-auth-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.bwie</groupId> <groupId>com.bwie</groupId>

View File

@ -3,9 +3,12 @@ package com.auth.server;
import org.mybatis.spring.annotation.MapperScan; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication @SpringBootApplication
@MapperScan("com.auth.server.mapper") @MapperScan("com.auth.server.mapper")
@ComponentScan(basePackages = {"com.etl.jwt.util", "com.etl.jwt.config",
"com.auth.server.controller","com.auth.server.service","com.auth.server.service.impl"})
public class EtlAuthServerApplication { public class EtlAuthServerApplication {
public static void main(String[] args) { public static void main(String[] args) {

View File

@ -3,6 +3,8 @@ package com.auth.server.config;
import com.auth.server.util.UserRealm; import com.auth.server.util.UserRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
@ -66,4 +68,5 @@ public class ShiroConfig {
return hashedCredentialsMatcher; return hashedCredentialsMatcher;
} }
} }

View File

@ -1,29 +1,33 @@
package com.auth.server.controller; package com.auth.server.controller;
import com.alibaba.nacos.api.model.v2.Result; import com.alibaba.nacos.api.model.v2.Result;
import com.auth.server.entity.UserAccount; import com.auth.common.entity.UserAccount;
import com.auth.server.service.UserManageService; import com.auth.server.service.UserManageService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.etl.common.enums.ResponseCodeEnum;
import com.etl.common.result.CommonResult;
import com.etl.jwt.util.JwtTokenUtil; import com.etl.jwt.util.JwtTokenUtil;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.*;
import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.realm.SimpleAccountRealm;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Map; import java.util.Map;
/**
* controller
*/
@RestController @RestController
@Slf4j @Slf4j
@Api(tags = "登录-API") @Api(tags = "登录-API")
@RequestMapping("/user")
public class LoginControler { public class LoginControler {
@Autowired @Autowired
private UserManageService userManageService; private UserManageService userManageService;
@ -35,15 +39,27 @@ public class LoginControler {
{ {
String username=user.getUsername(); String username=user.getUsername();
String password=user.getPassword(); String password=user.getPassword();
// 创建SimpleAccountRealm并添加账户信息
SimpleAccountRealm simpleAccountRealm = new SimpleAccountRealm();
// 确保这里添加的用户名和密码与用户提供的匹配
simpleAccountRealm.addAccount(username, password, user.getRoles());
// 配置SecurityManager并设置Realm
DefaultSecurityManager securityManager = new DefaultSecurityManager(simpleAccountRealm);
SecurityUtils.setSecurityManager(securityManager);
//shiro验证 //shiro验证
Subject subject= SecurityUtils.getSubject(); Subject subject= SecurityUtils.getSubject();
log.info("!11"+subject);
//根据用户名密码生成一个令牌 //根据用户名密码生成一个令牌
UsernamePasswordToken token=new UsernamePasswordToken(username,password); AuthenticationToken token=new UsernamePasswordToken(username,password);
try { try {
//执行登录操作 //执行登录操作
subject.login(token); subject.login(token);
} catch (UnknownAccountException e) { } catch (UnknownAccountException e) {
log.info("登录用户不存在"); log.info("登录用户不存在:{}",e);
return new Result<>(416,"用户不存在",username); return new Result<>(416,"用户不存在",username);
} catch (IncorrectCredentialsException e) { } catch (IncorrectCredentialsException e) {
log.info("登录密码错误"); log.info("登录密码错误");
@ -61,4 +77,59 @@ public class LoginControler {
userManageService.getOne(new QueryWrapper<UserAccount>().eq("username",username)).getRoles(); userManageService.getOne(new QueryWrapper<UserAccount>().eq("username",username)).getRoles();
return Result.success(tokenMap); return Result.success(tokenMap);
} }
/**
* JWT,
*
* header
*/
/**
* JWT access_token access_token使
* JWT 使 JWT access_token access_token
* 使refresh tokentoken
*
* refresh_token access_token access_token refresh_token
* redis
* @param token
* @return
*/
@GetMapping("/token/refresh")
public CommonResult<Object> refreshToken(@RequestHeader(value = "${auth.jwt.header}") String token){
token = com.auth.server.util.SecurityUtils.replaceTokenPrefix(token);
if (StringUtils.isEmpty(token)) {
return new CommonResult<>(ResponseCodeEnum.TOKEN_MISSION.getCode(),
ResponseCodeEnum.TOKEN_MISSION.getMessage());
}
// 对Token解签名并验证Token是否过期
boolean isJwtNotValid = jwtTokenUtil.isTokenExpired(token);
if(isJwtNotValid){
return new CommonResult<>(ResponseCodeEnum.TOKEN_INVALID.getCode(),
ResponseCodeEnum.TOKEN_INVALID.getMessage());
}
// 验证 token 里面的 userId 是否为空
String userId = jwtTokenUtil.getUserIdFromToken(token);
String username = jwtTokenUtil.getUserNameFromToken(token);
if (StringUtils.isEmpty(userId)) {
return new CommonResult<>(ResponseCodeEnum.TOKEN_INVALID.getCode(),
ResponseCodeEnum.TOKEN_INVALID.getMessage());
}
// 这里为了保证 refreshToken 只能用一次,刷新后,会从 redis 中删除。
// 如果用的不是 redis 中的 refreshToken 进行刷新令牌,则不能刷新。
// 如果使用 redis 中已过期的 refreshToken 也不能刷新令牌。
boolean isRefreshTokenNotExisted = jwtTokenUtil.isRefreshTokenNotExistCache(token);
if(isRefreshTokenNotExisted){
return new CommonResult<>(ResponseCodeEnum.REFRESH_TOKEN_INVALID.getCode(),
ResponseCodeEnum.REFRESH_TOKEN_INVALID.getMessage());
}
//String us = jwtTokenUtil.getUserIdFromToken(token);
Map<String, Object> tokenMap = jwtTokenUtil.refreshTokenAndGenerateToken(userId, username);
return new CommonResult<>(200, ResponseCodeEnum.SUCCESS.getMessage(),tokenMap);
}
} }

View File

@ -0,0 +1,54 @@
package com.auth.server.controller;
import com.auth.common.entity.PathPermission;
import com.auth.common.entity.RolesPermission;
import com.auth.common.enums.PermissionConstants;
import com.auth.server.service.PathService;
import com.auth.server.service.PermissionService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* controller
*/
@RestController
@Api(tags ="权限-API")
@RequestMapping("/permission")
public class PermissionController {
@Autowired
private PermissionService permissionService;
@Resource
private PathService pathService;
@PostMapping("/permission/add")
public boolean permissionAdd(@RequestBody Map<String,Object> map) {
String roles = (String) map.get(PermissionConstants.ROLES);
List<String> codeList = (List<String>) map.get(PermissionConstants.CODE_LIST);
return permissionService.permissionAdd(roles, codeList);
}
@GetMapping("/get")
public List<String> pathGet(@RequestParam("roles") String roles) {
RolesPermission permission = permissionService.getOne(new QueryWrapper<RolesPermission>().eq(PermissionConstants.ROLE,roles));
String codes = StringUtils.strip(permission.getPermissionCode(), "[]");
List<String> list = Arrays.asList(codes.split(","));
List<String> pathList = new ArrayList<>();
for(String code:list){
String api = pathService.getOne(new QueryWrapper<PathPermission>().eq(PermissionConstants.PERMISSION_CODE,code.trim())).getPath();
pathList.add(api);
}
return pathList;
}
}

View File

@ -1,10 +0,0 @@
package com.auth.server.entity;
import lombok.Data;
@Data
public class RolesPermission {
private Integer id;
private String permissionCode;
private String role;
}

View File

@ -1,11 +0,0 @@
package com.auth.server.entity;
import lombok.Data;
@Data
public class UserAccount {
private Integer id;
private String roles;
private String username;
private String password;
}

View File

@ -0,0 +1,8 @@
package com.auth.server.mapper;
import com.auth.common.entity.PathPermission;
import com.auth.common.entity.RolesPermission;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface PathMapper extends BaseMapper<PathPermission> {
}

View File

@ -1,8 +1,8 @@
package com.auth.server.mapper; package com.auth.server.mapper;
import com.auth.server.entity.RolesPermission;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.auth.common.entity.RolesPermission;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface PermissionMapper extends BaseMapper<RolesPermission> { public interface PermissionMapper extends BaseMapper<RolesPermission> {
} }

View File

@ -1,7 +1,9 @@
package com.auth.server.mapper; package com.auth.server.mapper;
import com.auth.server.entity.UserAccount;
import com.auth.common.entity.UserAccount;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface UserMangeMapper extends BaseMapper<UserAccount> { public interface UserMangeMapper extends BaseMapper<UserAccount> {
} }

View File

@ -0,0 +1,9 @@
package com.auth.server.service;
import com.auth.common.entity.PathPermission;
import com.auth.common.entity.RolesPermission;
import com.auth.common.entity.UserAccount;
import com.baomidou.mybatisplus.extension.service.IService;
public interface PathService extends IService<PathPermission> {
}

View File

@ -1,7 +1,11 @@
package com.auth.server.service; package com.auth.server.service;
import com.auth.common.entity.RolesPermission;
import com.auth.common.entity.UserAccount;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List; import java.util.List;
public interface PermissionService { public interface PermissionService extends IService<RolesPermission> {
boolean permissionAdd(String roles, List<String> codeList); boolean permissionAdd(String roles, List<String> codeList);
} }

View File

@ -1,9 +1,10 @@
package com.auth.server.service; package com.auth.server.service;
import com.auth.server.entity.UserAccount; import com.auth.common.entity.UserAccount;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
public interface UserManageService extends IService<UserAccount> { public interface UserManageService extends IService<UserAccount> {
} }

View File

@ -0,0 +1,16 @@
package com.auth.server.service.impl;
import com.auth.common.entity.PathPermission;
import com.auth.common.entity.RolesPermission;
import com.auth.server.mapper.PathMapper;
import com.auth.server.mapper.PermissionMapper;
import com.auth.server.service.PathService;
import com.auth.server.service.PermissionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class PathServiceImpl extends ServiceImpl<PathMapper, PathPermission> implements PathService {
}

View File

@ -1,10 +1,10 @@
package com.auth.server.service.impl; package com.auth.server.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.auth.common.entity.RolesPermission;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.auth.server.entity.RolesPermission;
import com.auth.server.mapper.PermissionMapper; import com.auth.server.mapper.PermissionMapper;
import com.auth.server.service.PermissionService; import com.auth.server.service.PermissionService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -36,7 +36,9 @@ public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, RolesPe
rolesPermission.setId(role.getId()); rolesPermission.setId(role.getId());
result = permissionMapper.updateById(rolesPermission); result = permissionMapper.updateById(rolesPermission);
}else { }else {
rolesPermission.setPermissionCode(codeList.toString()); if (codeList!=null){
rolesPermission.setPermissionCode(codeList.toString());
}
result = permissionMapper.insert(rolesPermission); result = permissionMapper.insert(rolesPermission);
} }
return result > 0; return result > 0;

View File

@ -1,14 +1,15 @@
package com.auth.server.service.impl; package com.auth.server.service.impl;
import com.auth.server.entity.UserAccount;
import com.auth.common.entity.UserAccount;
import com.auth.server.mapper.UserMangeMapper; import com.auth.server.mapper.UserMangeMapper;
import com.auth.server.service.UserManageService; import com.auth.server.service.UserManageService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@Service @Service
@Slf4j
public class UserManageServiceImpl extends ServiceImpl<UserMangeMapper, UserAccount> implements UserManageService { public class UserManageServiceImpl extends ServiceImpl<UserMangeMapper, UserAccount> implements UserManageService {
} }

View File

@ -1,6 +1,7 @@
package com.auth.server.util; package com.auth.server.util;
import com.auth.server.entity.UserAccount;
import com.auth.common.entity.UserAccount;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.auth.server.service.UserManageService; import com.auth.server.service.UserManageService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;

View File

@ -1,5 +1,5 @@
server: server:
port: 9098 port: 9092
spring: spring:
application: application:
name: engine-jwt-manage name: engine-jwt-manage
@ -35,3 +35,15 @@ logging:
level: level:
com.bwie: DEBUG com.bwie: DEBUG
auth:
jwt:
enabled: true # 是否开启JWT登录认证功能
secret: passjava # JWT 私钥用于校验JWT令牌的合法性
expiration: 1800000 # JWT 令牌的有效期用于校验JWT令牌的合法性半个小时
header: Authorization # HTTP 请求的 Header 名称,该 Header作为参数传递 JWT 令牌
userParamName: userId # 用户登录认证用户名参数名称
pwdParamName: password # 用户登录认证密码参数名称
useDefaultController: true # 是否使用默认的JwtAuthController
skipValidUrl:
- /auth/login
- /auth/logout

View File

@ -0,0 +1,6 @@
<?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.auth.server.mapper.PathMapper">
</mapper>

View File

@ -1,5 +1,5 @@
server: server:
port: 9098 port: 9092
spring: spring:
application: application:
name: engine-jwt-manage name: engine-jwt-manage
@ -35,3 +35,15 @@ logging:
level: level:
com.bwie: DEBUG com.bwie: DEBUG
auth:
jwt:
enabled: true # 是否开启JWT登录认证功能
secret: passjava # JWT 私钥用于校验JWT令牌的合法性
expiration: 1800000 # JWT 令牌的有效期用于校验JWT令牌的合法性半个小时
header: Authorization # HTTP 请求的 Header 名称,该 Header作为参数传递 JWT 令牌
userParamName: userId # 用户登录认证用户名参数名称
pwdParamName: password # 用户登录认证密码参数名称
useDefaultController: true # 是否使用默认的JwtAuthController
skipValidUrl:
- /auth/login
- /auth/logout

View File

@ -0,0 +1,6 @@
<?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.auth.server.mapper.PathMapper">
</mapper>

View File

@ -1,5 +1,5 @@
#Generated by Maven #Generated by Maven
#Sat Jun 22 09:25:17 CST 2024 #Sat Jun 22 14:21:34 CST 2024
version=0.0.1-SNAPSHOT version=1.0-SNAPSHOT
groupId=com.auth.server groupId=com.bwie
artifactId=etl-auth-server artifactId=etl-auth-server

View File

@ -0,0 +1,29 @@
package com.etl.common.enums;
public enum ResponseCodeEnum {
SUCCESS(200, "成功"),
FAIL(412, "失败"),
LOGIN_ERROR(202, "用户名或密码错误"),
UNKNOWN_ERROR(500, "未知错误"),
PARAMETER_ILLEGAL(400, "参数不合法"),
TOKEN_INVALID(412, "token 已过期或验证不正确!"),
TOKEN_SIGNATURE_INVALID(403, "无效的签名"),
TOKEN_MISSION(403, "token 缺失"),
REFRESH_TOKEN_INVALID(412, "refreshToken 无效"),
LOGOUT_ERROR(444, "用户登出失败");
private final int code;
private final String message;
ResponseCodeEnum(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
}

View File

@ -0,0 +1,22 @@
package com.etl.common.result;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult<T>{
private Integer code;
private String message;
private T data;
private int dataSize;
public CommonResult(Integer code,String message){
this(code,message,null,0);
}
public CommonResult(Integer code,String message,T data){
this(code,message,data,0);
}
}

View File

@ -1,5 +1,5 @@
#Generated by Maven #Generated by Maven
#Sat Jun 22 09:25:13 CST 2024 #Sat Jun 22 14:21:30 CST 2024
version=1.0-SNAPSHOT version=1.0-SNAPSHOT
groupId=com.bwie groupId=com.bwie
artifactId=etl-common artifactId=etl-common

View File

@ -17,6 +17,20 @@
<spring-cloud.version>2021.0.5</spring-cloud.version> <spring-cloud.version>2021.0.5</spring-cloud.version>
</properties> </properties>
<dependencies> <dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.15</version>
</dependency>
<dependency>
<groupId>com.bwie</groupId>
<artifactId>etl-jwt-manage</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!--自定义包--> <!--自定义包-->
<dependency> <dependency>
<groupId>com.bwie</groupId> <groupId>com.bwie</groupId>

View File

@ -2,8 +2,10 @@ package com.etl.gateway;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication @SpringBootApplication
@ComponentScan(basePackages = {"com.etl.jwt.util", "com.etl.jwt.config"})
public class EtlGatewayApplication { public class EtlGatewayApplication {
public static void main(String[] args) { public static void main(String[] args) {

View File

@ -0,0 +1,136 @@
package com.etl.gateway.filters;
import com.alibaba.fastjson.JSON;
import com.etl.common.constants.TokenConstants;
import com.etl.common.result.CommonResult;
import com.etl.common.enums.ResponseCodeEnum;
import com.etl.jwt.config.AuthJwtProperties;
import com.etl.jwt.util.JwtTokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
@Slf4j
@Configuration
public class JwtAuthCheckFilter {
private static final String AUTH_TOKEN_URL = "/auth/login";
private static final String REFRESH_TOKEN_URL = "/auth/token/refresh";
public static final String USER_ID = "userId";
public static final String USER_NAME = "username";
public static final String FROM_SOURCE = "from-source";
@Resource
private AuthJwtProperties authJwtProperties;
@Resource
private JwtTokenUtil jwtTokenUtil;
@Bean
@Order(-101)
public GlobalFilter jwtAuthGlobalFilter() {
return (exchange, chain) -> {
ServerHttpRequest serverHttpRequest = exchange.getRequest();
ServerHttpResponse serverHttpResponse = exchange.getResponse();
ServerHttpRequest.Builder mutate = serverHttpRequest.mutate();
String requestUrl = serverHttpRequest.getURI().getPath();
// 跳过对登录请求的 token 检查。因为登录请求是没有 token 的,是来申请 token 的。
if(AUTH_TOKEN_URL.equals(requestUrl)) {
log.info("登录url放行");
return chain.filter(exchange);
}
// 从 HTTP 请求头中获取 JWT 令牌
String token = getToken(serverHttpRequest);
if (StringUtils.isEmpty(token)) {
return unauthorizedResponse(exchange, serverHttpResponse, ResponseCodeEnum.TOKEN_MISSION);
}
// 对Token解签名并验证Token是否过期
boolean isJwtNotValid = jwtTokenUtil.isTokenExpired(token);
if(isJwtNotValid){
return unauthorizedResponse(exchange, serverHttpResponse, ResponseCodeEnum.TOKEN_INVALID);
}
// 验证 token 里面的 userId 是否为空
String userId = jwtTokenUtil.getUserIdFromToken(token);
String username = jwtTokenUtil.getUserNameFromToken(token);
if (StringUtils.isEmpty(userId)) {
return unauthorizedResponse(exchange, serverHttpResponse, ResponseCodeEnum.TOKEN_INVALID);
}
// 设置用户信息到请求
addHeader(mutate, USER_ID, userId);
addHeader(mutate, USER_NAME, username);
// 内部请求来源参数清除
removeHeader(mutate, FROM_SOURCE);
return chain.filter(exchange.mutate().request(mutate.build()).build());
};
}
//添加头部信息
private void addHeader(ServerHttpRequest.Builder mutate, String name, Object value) {
if (value == null) {
return;
}
String valueStr = value.toString();
String valueEncode = urlEncode(valueStr);
mutate.header(name, valueEncode);
}
//移除头部信息
private void removeHeader(ServerHttpRequest.Builder mutate, String name) {
mutate.headers(httpHeaders -> httpHeaders.remove(name)).build();
}
//内容编码配置为UTF-8
static String urlEncode(String str) {
try {
return URLEncoder.encode(str, "UTF-8");
}
catch (UnsupportedEncodingException e)
{
return StringUtils.EMPTY;
}
}
//请求token
private String getToken(ServerHttpRequest request) {
String token = request.getHeaders().getFirst(authJwtProperties.getHeader());
// 如果前端设置了令牌前缀,则裁剪掉前缀
if (StringUtils.isNotEmpty(token) && token.startsWith(TokenConstants.PREFIX))
{
token = token.replaceFirst(TokenConstants.PREFIX, StringUtils.EMPTY);
}
return token;
}
//jwt鉴权失败处理类
private Mono<Void> unauthorizedResponse(ServerWebExchange exchange, ServerHttpResponse serverHttpResponse, ResponseCodeEnum responseCodeEnum) {
log.warn("token异常处理,请求路径:{}", exchange.getRequest().getPath());
serverHttpResponse.setStatusCode(HttpStatus.UNAUTHORIZED);
serverHttpResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
CommonResult<Object> responseResult = new CommonResult<>(responseCodeEnum.getCode(),responseCodeEnum.getMessage());
DataBuffer dataBuffer = serverHttpResponse.bufferFactory()
.wrap(JSON.toJSONStringWithDateFormat(responseResult, JSON.DEFFAULT_DATE_FORMAT)
.getBytes(StandardCharsets.UTF_8));
return serverHttpResponse.writeWith(Flux.just(dataBuffer));
}
}

View File

@ -3,6 +3,7 @@ package com.etl.gateway.filters;
import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@ -12,14 +13,15 @@ import reactor.core.publisher.Mono;
* @Author: dongyan Ma * @Author: dongyan Ma
* @Date: 2024/2/28 * @Date: 2024/2/28
*/ */
@Component
public class LogFilter implements GlobalFilter, Ordered { public class LogFilter implements GlobalFilter, Ordered {
@Override @Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return null; return chain.filter(exchange);
} }
@Override @Override
public int getOrder() { public int getOrder() {
return 1; return 0;
} }
} }

View File

@ -1,5 +1,5 @@
server: server:
port: 18080 port: 8080
spring: spring:
application: application:
name: engine-gateway name: engine-gateway

View File

@ -1,7 +1,9 @@
package com.etl.jwt.config; package com.etl.jwt.config;
import com.etl.jwt.util.JwtTokenUtil;
import lombok.Data; import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@Data @Data

View File

@ -5,6 +5,7 @@ import com.etl.jwt.config.AuthJwtProperties;
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts; import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -32,12 +33,12 @@ public class JwtTokenUtil {
@Resource @Resource
private AuthJwtProperties jwtProperties; private AuthJwtProperties jwtProperties;
/** /**
* token * token
* @param userId Id * @param userId Id
* @return token * @return token
*/ */
public Map<String, Object> generateTokenAndRefreshToken(String userId, String username) { public Map<String, Object> generateTokenAndRefreshToken(String userId, String username) {
//生成令牌及刷新令牌 //生成令牌及刷新令牌
Map<String, Object> tokenMap = buildToken(userId, username); Map<String, Object> tokenMap = buildToken(userId, username);

View File

@ -1,5 +1,5 @@
#Generated by Maven #Generated by Maven
#Sat Jun 22 09:25:14 CST 2024 #Sat Jun 22 14:21:31 CST 2024
version=1.0-SNAPSHOT version=1.0-SNAPSHOT
groupId=com.bwie groupId=com.bwie
artifactId=etl-jwt-manage artifactId=etl-jwt-manage