提交 3ea7da10 authored 作者: fit2cloud-chenyw's avatar fit2cloud-chenyw

feat: 使用ak,sk访问api接口以及swagger

上级 91749926
......@@ -2,18 +2,17 @@ package io.dataease.auth.config;
import io.dataease.auth.api.dto.CurrentRoleDto;
import io.dataease.auth.api.dto.CurrentUserDto;
import io.dataease.auth.entity.ASKToken;
import io.dataease.auth.entity.JWTToken;
import io.dataease.auth.entity.SysUserEntity;
import io.dataease.auth.entity.TokenInfo;
import io.dataease.auth.handler.ApiKeyHandler;
import io.dataease.auth.service.AuthUserService;
import io.dataease.auth.util.JWTUtils;
import io.dataease.commons.utils.BeanUtils;
import io.dataease.commons.utils.LogUtil;
import io.dataease.listener.util.CacheUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
......@@ -37,7 +36,7 @@ public class F2CRealm extends AuthorizingRealm {
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof JWTToken;
return token instanceof JWTToken || token instanceof ASKToken;
}
//验证资源权限
......@@ -56,12 +55,27 @@ public class F2CRealm extends AuthorizingRealm {
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
if (auth instanceof ASKToken) {
Object accessKey = auth.getPrincipal();
Object signature = auth.getCredentials();
Long userId = ApiKeyHandler.getUser(accessKey.toString(), signature.toString());
SysUserEntity userEntity = userWithId(userId);
CurrentUserDto currentUserDto = queryCacheUserDto(userEntity);
return new SimpleAuthenticationInfo(currentUserDto, signature, "f2cReam");
}
try {
CacheUtils.get("lic_info", "lic");
}catch (Exception e) {
LogUtil.error(e);
throw new AuthenticationException("lic error");
}
TokenInfo tokenInfo = null;
String token = null;
try {
......@@ -78,13 +92,14 @@ public class F2CRealm extends AuthorizingRealm {
throw new AuthenticationException("token invalid");
}
// 使用缓存
SysUserEntity user = authUserService.getUserById(userId);
/*SysUserEntity user = authUserService.getUserById(userId);
if (user == null) {
throw new AuthenticationException("User didn't existed!");
}
if (user.getEnabled()==0) {
throw new AuthenticationException("User is valid!");
}
}*/
SysUserEntity user = userWithId(userId);
String pass = null;
try {
pass = user.getPassword();
......@@ -94,6 +109,29 @@ public class F2CRealm extends AuthorizingRealm {
if (! JWTUtils.verify(token, tokenInfo, pass)) {
throw new AuthenticationException("Username or password error");
}
/*// 使用缓存
List<CurrentRoleDto> currentRoleDtos = authUserService.roleInfos(user.getUserId());
// 使用缓存
List<String> permissions = authUserService.permissions(user.getUserId());
CurrentUserDto currentUserDto = BeanUtils.copyBean(new CurrentUserDto(), user);
currentUserDto.setRoles(currentRoleDtos);
currentUserDto.setPermissions(permissions);*/
CurrentUserDto currentUserDto = queryCacheUserDto(user);
return new SimpleAuthenticationInfo(currentUserDto, token, "f2cReam");
}
public SysUserEntity userWithId(Long userId) {
SysUserEntity user = authUserService.getUserById(userId);
if (user == null) {
throw new AuthenticationException("User didn't existed!");
}
if (user.getEnabled()==0) {
throw new AuthenticationException("User is valid!");
}
return user;
}
public CurrentUserDto queryCacheUserDto(SysUserEntity user) {
// 使用缓存
List<CurrentRoleDto> currentRoleDtos = authUserService.roleInfos(user.getUserId());
// 使用缓存
......@@ -101,6 +139,6 @@ public class F2CRealm extends AuthorizingRealm {
CurrentUserDto currentUserDto = BeanUtils.copyBean(new CurrentUserDto(), user);
currentUserDto.setRoles(currentRoleDtos);
currentUserDto.setPermissions(permissions);
return new SimpleAuthenticationInfo(currentUserDto, token, "f2cReam");
return currentUserDto;
}
}
package io.dataease.auth.entity;
import org.apache.shiro.authc.AuthenticationToken;
public class ASKToken implements AuthenticationToken {
private String accessKey;
private String signature;
public ASKToken(String accessKey, String signature) {
this.accessKey = accessKey;
this.signature = signature;
}
@Override
public Object getPrincipal() {
return accessKey;
}
@Override
public Object getCredentials() {
return signature;
}
}
package io.dataease.auth.filter;
import io.dataease.auth.entity.ASKToken;
import io.dataease.auth.entity.JWTToken;
import io.dataease.auth.entity.SysUserEntity;
import io.dataease.auth.entity.TokenInfo;
import io.dataease.auth.handler.ApiKeyHandler;
import io.dataease.auth.service.AuthUserService;
import io.dataease.auth.util.JWTUtils;
import io.dataease.commons.utils.CommonBeanFactory;
......@@ -48,6 +50,18 @@ public class JWTFilter extends BasicHttpAuthenticationFilter {
@Override
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
if (ApiKeyHandler.isApiKeyCall(httpServletRequest)) {
// Long userId = ApiKeyHandler.getUser(httpServletRequest);
ASKToken askToken = ApiKeyHandler.buildToken(httpServletRequest);
// UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(userId.toString(), ApiKeyHandler.random);
getSubject(request, response).login(askToken);
return true;
}
String authorization = httpServletRequest.getHeader("Authorization");
if (StringUtils.startsWith(authorization, "Basic")) {
return false;
......@@ -72,7 +86,10 @@ public class JWTFilter extends BasicHttpAuthenticationFilter {
*/
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
if (isLoginAttempt(request, response)) {
// 先判断是不是api调用
HttpServletRequest hRequest = (HttpServletRequest) request;
if (isLoginAttempt(request, response) || ApiKeyHandler.isApiKeyCall(hRequest)) {
try {
boolean loginSuccess = executeLogin(request, response);
return loginSuccess;
......
package io.dataease.auth.handler;
import io.dataease.auth.entity.ASKToken;
import io.dataease.commons.utils.CodingUtil;
import io.dataease.plugins.config.SpringContextUtil;
import io.dataease.plugins.xpack.ukey.dto.request.XpackUkeyDto;
import io.dataease.plugins.xpack.ukey.service.UkeyXpackService;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.http.HttpServletRequest;
import java.util.UUID;
public class ApiKeyHandler {
public static final String API_ACCESS_KEY = "accessKey";
public static final String API_SIGNATURE = "signature";
public static String random = UUID.randomUUID().toString() + UUID.randomUUID().toString();
public static Long getUser(HttpServletRequest request) {
if (request == null) {
return null;
}
return getUser(request.getHeader(API_ACCESS_KEY), request.getHeader(API_SIGNATURE));
}
public static ASKToken buildToken(HttpServletRequest request) {
if (request == null) {
return null;
}
String accessKey = request.getHeader(API_ACCESS_KEY);
String signature = request.getHeader(API_SIGNATURE);
ASKToken askToken = new ASKToken(accessKey, signature);
return askToken;
}
public static Boolean isApiKeyCall(HttpServletRequest request) {
if (request == null) {
return false;
}
if (StringUtils.isBlank(request.getHeader(API_ACCESS_KEY)) || StringUtils.isBlank(request.getHeader(API_SIGNATURE))) {
return false;
}
return true;
}
public static XpackUkeyDto ukey(String accessKey) {
UkeyXpackService ukeyXpackService = SpringContextUtil.getBean(UkeyXpackService.class);
XpackUkeyDto userKey = ukeyXpackService.getUserKey(accessKey);
return userKey;
}
public static Long getUser(String accessKey, String signature) {
if (StringUtils.isBlank(accessKey) || StringUtils.isBlank(signature)) {
return null;
}
XpackUkeyDto userKey = ukey(accessKey);
if (userKey == null) {
throw new RuntimeException("invalid accessKey");
}
String signatureDecrypt;
try {
signatureDecrypt = CodingUtil.aesDecrypt(signature, userKey.getSecretKey(), accessKey);
} catch (Throwable t) {
throw new RuntimeException("invalid signature");
}
String[] signatureArray = StringUtils.split(StringUtils.trimToNull(signatureDecrypt), "|");
if (signatureArray.length < 2) {
throw new RuntimeException("invalid signature");
}
if (!StringUtils.equals(accessKey, signatureArray[0])) {
throw new RuntimeException("invalid signature");
}
long signatureTime = 0l;
try {
signatureTime = Long.valueOf(signatureArray[signatureArray.length - 1]).longValue();
} catch (Exception e) {
throw new RuntimeException(e);
}
if (Math.abs(System.currentTimeMillis() - signatureTime) > 1800000) {
//签名30分钟超时
throw new RuntimeException("expired signature");
}
return userKey.getUserId();
}
}
......@@ -7,6 +7,7 @@ import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.util.UUID;
/**
* 加密解密工具
......@@ -153,6 +154,17 @@ public class CodingUtil {
}
}
/*public static String getSignature(String accessKey, String secretKey) throws Exception {
return aesEncrypt(accessKey + "|" + UUID.randomUUID().toString() + "|" + System.currentTimeMillis(), secretKey, accessKey);
}
public static void main(String[] args) throws Exception{
String accessKey = "gnPFmtAsdLhUEWPA";
String secretKey = "TfK5FGUle0KRfJJJ";
String signature = getSignature(accessKey, secretKey);
System.out.println(signature);
}*/
public static String secretKey() {
try {
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
......
......@@ -77,7 +77,9 @@ public class Knife4jConfiguration {
private Docket defaultApi(String groupName, String packageName) {
List<SecurityScheme> securitySchemes=new ArrayList<>();
securitySchemes.add(apiKey());
securitySchemes.add(accessKey());
securitySchemes.add(signature());
List<SecurityContext> securityContexts = new ArrayList<>();
securityContexts.add(securityContext());
......@@ -100,8 +102,12 @@ public class Knife4jConfiguration {
.build();
}
private ApiKey apiKey() {
return new ApiKey("Authorization", "Authorization", "header");
private ApiKey accessKey() {
return new ApiKey("accessKey", "accessKey", "header");
}
private ApiKey signature() {
return new ApiKey("signature", "signature", "header");
}
......@@ -109,7 +115,12 @@ public class Knife4jConfiguration {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
return CollectionUtil.newArrayList(new SecurityReference("Authorization", authorizationScopes));
List<SecurityReference> results = new ArrayList<>();
results.add(new SecurityReference("accessKey", authorizationScopes));
results.add(new SecurityReference("signature", authorizationScopes));
return results;
}
}
......@@ -28,7 +28,7 @@ knife4j.enable=true
knife4j.setting.enableFooter=false
knife4j.setting.enableFooterCustom=false
knife4j.setting.footerCustomContent=fit2cloud 1.0-b9
knife4j.setting.enableSwaggerModels=false
#knife4j.setting.enableSwaggerModels=false
knife4j.setting.enableDocumentManage=false
knife4j.setting.enableSearch=false
knife4j.setting.enableOpenApi=false
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论