Browse Source

增加内部应用认证注解

dev_shibei_match
wxz 5 years ago
parent
commit
2b988de560
  1. 6
      epmet-commons/epmet-commons-extapp-auth/pom.xml
  2. 32
      epmet-commons/epmet-commons-extapp-auth/src/main/java/com/epmet/commons/extappauth/annotation/InternalAppRequestAuth.java
  3. 117
      epmet-commons/epmet-commons-extapp-auth/src/main/java/com/epmet/commons/extappauth/aspect/ExternalAppRequestAuthAspect.java
  4. 41
      epmet-commons/epmet-commons-extapp-auth/src/main/java/com/epmet/commons/extappauth/jwt/JwtTokenProperties.java
  5. 130
      epmet-commons/epmet-commons-extapp-auth/src/main/java/com/epmet/commons/extappauth/jwt/JwtTokenUtils.java
  6. 2
      epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/exception/EpmetErrorCode.java
  7. 19
      epmet-module/data-report/data-report-server/src/main/java/com/epmet/controller/test/TestController.java

6
epmet-commons/epmet-commons-extapp-auth/pom.xml

@ -27,6 +27,12 @@
</properties>
<dependencies>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>

32
epmet-commons/epmet-commons-extapp-auth/src/main/java/com/epmet/commons/extappauth/annotation/InternalAppRequestAuth.java

@ -0,0 +1,32 @@
/**
* Copyright 2018 人人开源 http://www.renren.io
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.epmet.commons.extappauth.annotation;
import java.lang.annotation.*;
/**
* 需要认证的内部请求
* @Author wxz
* @Description
* @Date 2020/4/23 16:17
**/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface InternalAppRequestAuth {
}

117
epmet-commons/epmet-commons-extapp-auth/src/main/java/com/epmet/commons/extappauth/aspect/ExternalAppRequestAuthAspect.java

@ -1,13 +1,23 @@
package com.epmet.commons.extappauth.aspect;
import cn.hutool.core.bean.BeanUtil;
import com.epmet.commons.extappauth.annotation.ExternalAppRequestAuth;
import com.epmet.commons.extappauth.annotation.InternalAppRequestAuth;
import com.epmet.commons.extappauth.bean.ExternalAppRequestParam;
import com.epmet.commons.extappauth.jwt.JwtTokenUtils;
import com.epmet.commons.tools.exception.EpmetErrorCode;
import com.epmet.commons.tools.exception.RenException;
import com.epmet.commons.tools.redis.RedisKeys;
import com.epmet.commons.tools.redis.RedisUtils;
import com.epmet.commons.tools.security.dto.BaseTokenDto;
import com.epmet.commons.tools.security.dto.GovTokenDto;
import com.epmet.commons.tools.security.dto.TokenDto;
import com.epmet.commons.tools.utils.Result;
import com.epmet.dto.form.ExternalAppAuthFormDTO;
import com.epmet.dto.result.ExternalAppAuthResultDTO;
import com.epmet.feign.EpmetCommonServiceOpenFeignClient;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
@ -24,6 +34,7 @@ import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Parameter;
import java.util.Map;
/**
* 外部应用请求认证切面
@ -35,6 +46,7 @@ public class ExternalAppRequestAuthAspect {
private static Logger logger = LoggerFactory.getLogger(ExternalAppRequestAuthAspect.class);
public static final String AUTHORIZATION_TOKEN_HEADER_KEY = "Authorization";
public static final String ACCESS_TOKEN_HEADER_KEY = "AccessToken";
public static final String APP_ID_HEADER_KEY = "appId";
public static final String APP_ID_TIMESTAMP_KEY = "ts";
@ -44,15 +56,117 @@ public class ExternalAppRequestAuthAspect {
@Autowired
private EpmetCommonServiceOpenFeignClient commonServiceOpenFeignClient;
@Autowired
private JwtTokenUtils jwtTokenUtils;
@Autowired
private RedisUtils redisUtils;
/**
* 拦截加了ExternalRequestAuth注解的方法
*
* @param point
* @throws Throwable
*/
@Before("@annotation(com.epmet.commons.extappauth.annotation.ExternalAppRequestAuth)")
@Before("@annotation(com.epmet.commons.extappauth.annotation.ExternalAppRequestAuth) " +
"|| @annotation(com.epmet.commons.extappauth.annotation.InternalAppRequestAuth)")
public void auth(JoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
HttpServletRequest request = getRequest();
if (signature.getMethod().getAnnotation(ExternalAppRequestAuth.class) != null
&& StringUtils.isNotBlank(request.getHeader(ACCESS_TOKEN_HEADER_KEY))) {
// 走外部应用认证
extAppAuth(signature, point, request);
} else if (signature.getMethod().getAnnotation(InternalAppRequestAuth.class) != null
&& StringUtils.isNotBlank(request.getHeader(AUTHORIZATION_TOKEN_HEADER_KEY))) {
// 走内部应用认证
String customerId = null;
internalAppAuth(signature, point, request);
} else {
throw new RenException(EpmetErrorCode.UNSUPPORT_AUTH_TYPE.getCode(), EpmetErrorCode.UNSUPPORT_AUTH_TYPE.getMsg());
}
}
/**
* 内部应用认证
* @param signature
* @param point
* @param request
* @return
*/
private void internalAppAuth(MethodSignature signature, JoinPoint point, HttpServletRequest request) {
String authorization = request.getHeader(AUTHORIZATION_TOKEN_HEADER_KEY);
BaseTokenDto tokenDTO = getTokenDTO(authorization);
Map<String, Object> tokenMap = redisUtils.hGetAll(RedisKeys.getCpUserKey(tokenDTO.getApp(), tokenDTO.getClient(), tokenDTO.getUserId()));
BaseTokenDto baseTokenDto = null;
String customerId;
if ("gov".equals(tokenDTO.getApp())) {
GovTokenDto govTokenDto = BeanUtil.mapToBean(tokenMap, GovTokenDto.class, true);
customerId = govTokenDto.getCustomerId();
baseTokenDto = govTokenDto;
} else {
TokenDto tokenDto = BeanUtil.mapToBean(tokenMap, TokenDto.class, true);
customerId = tokenDto.getCustomerId();
baseTokenDto = tokenDTO;
}
if (baseTokenDto == null) {
logger.error("内部应用认证,redis中没有找到登录缓存信息");
throw new RenException(EpmetErrorCode.ERR10006.getCode(), EpmetErrorCode.ERR10006.getMsg());
}
if (!authorization.equals(baseTokenDto.getToken())) {
logger.error("内部应用认证,redis中找到的token与header里面传入的不一致,可能发生了别处登录");
throw new RenException(EpmetErrorCode.ERR10007.getCode(), EpmetErrorCode.ERR10007.getMsg());
}
// header参数赋值
Parameter[] parameters = signature.getMethod().getParameters();
if (parameters != null && parameters.length != 0) {
for (int i = 0; i < parameters.length; i++) {
if (parameters[i].getType() == ExternalAppRequestParam.class) {
ExternalAppRequestParam requestParam = (ExternalAppRequestParam) point.getArgs()[i];
requestParam.setCustomerId(customerId);
}
}
}
}
private BaseTokenDto getTokenDTO(String authorization) {
if (StringUtils.isBlank(authorization)) {
logger.error("内部应用认证,没有携带authorization头信息");
throw new RenException(EpmetErrorCode.ERR401.getCode(), EpmetErrorCode.ERR401.getMsg());
}
//是否过期
Claims claims = jwtTokenUtils.getClaimByToken(authorization);
if (claims == null) {
logger.error("内部应用认证,Claims为空");
throw new RenException(EpmetErrorCode.ERR401.getCode(), EpmetErrorCode.ERR401.getMsg());
}
if (jwtTokenUtils.isTokenExpired(claims.getExpiration())) {
logger.error("内部应用认证,token过期");
throw new RenException(EpmetErrorCode.ERR10006.getCode(), EpmetErrorCode.ERR10006.getMsg());
}
//获取用户ID
String app = (String) claims.get("app");
String client = (String) claims.get("client");
String userId = (String) claims.get("userId");
return new BaseTokenDto(app, client, userId, authorization);
}
/**
* 外部应用认证
*
* @param signature
* @param point
*/
public void extAppAuth(MethodSignature signature, JoinPoint point, HttpServletRequest request) {
String token = request.getHeader(ACCESS_TOKEN_HEADER_KEY);
String appId = request.getHeader(APP_ID_HEADER_KEY);
String ts = request.getHeader(APP_ID_TIMESTAMP_KEY);
@ -89,7 +203,6 @@ public class ExternalAppRequestAuthAspect {
// header参数赋值
MethodSignature signature = (MethodSignature) point.getSignature();
Parameter[] parameters = signature.getMethod().getParameters();
if (parameters != null && parameters.length != 0) {
for (int i = 0; i < parameters.length; i++) {

41
epmet-commons/epmet-commons-extapp-auth/src/main/java/com/epmet/commons/extappauth/jwt/JwtTokenProperties.java

@ -0,0 +1,41 @@
/**
* Copyright (c) 2018 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有侵权必究
*/
package com.epmet.commons.extappauth.jwt;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* Jwt
*
* @author Mark sunlightcs@gmail.com
* @since 1.0.0
*/
@Configuration
@ConfigurationProperties(prefix = "jwt.token")
public class JwtTokenProperties {
private String secret;
private int expire;
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
public int getExpire() {
return expire;
}
public void setExpire(int expire) {
this.expire = expire;
}
}

130
epmet-commons/epmet-commons-extapp-auth/src/main/java/com/epmet/commons/extappauth/jwt/JwtTokenUtils.java

@ -0,0 +1,130 @@
/**
* Copyright (c) 2018 人人开源 All rights reserved.
* <p>
* https://www.renren.io
* <p>
* 版权所有侵权必究
*/
package com.epmet.commons.extappauth.jwt;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* Jwt工具类
*
* @author Mark sunlightcs@gmail.com
* @since 1.0.0
*/
@Component
public class JwtTokenUtils {
private static final Logger logger = LoggerFactory.getLogger(JwtTokenUtils.class);
@Autowired
private JwtTokenProperties jwtProperties;
/**
* 生成jwt token 弃用
*/
@Deprecated
public String generateToken(String userId) {
return Jwts.builder()
.setHeaderParam("typ", "JWT")
.setSubject(userId)
.setIssuedAt(new Date())
.setExpiration(DateTime.now().plusSeconds(jwtProperties.getExpire()).toDate())
.signWith(SignatureAlgorithm.HS512, jwtProperties.getSecret())
.compact();
}
public Claims getClaimByToken(String token) {
try {
return Jwts.parser()
.setSigningKey(jwtProperties.getSecret())
.parseClaimsJws(token)
.getBody();
} catch (Exception e) {
logger.debug("validate is token error, token = " + token, e);
return null;
}
}
/**
* @return java.util.Date
* @param token
* @Author yinzuomei
* @Description 获取token的有效期截止时间
* @Date 2020/3/18 22:17
**/
public Date getExpiration(String token){
try {
return Jwts.parser()
.setSigningKey(jwtProperties.getSecret())
.parseClaimsJws(token)
.getBody().getExpiration();
} catch (Exception e) {
logger.debug("validate is token error, token = " + token, e);
return null;
}
}
/**
* @param map
* @return java.lang.String
* @Author yinzuomei
* @Description 根据app+client+userId生成token
* @Date 2020/3/18 22:29
**/
public String createToken(Map<String, Object> map) {
return Jwts.builder()
.setHeaderParam("typ", "JWT")
.setClaims(map)
.setIssuedAt(new Date())
.setExpiration(DateTime.now().plusSeconds(jwtProperties.getExpire()).toDate())
.signWith(SignatureAlgorithm.HS512, jwtProperties.getSecret())
.compact();
}
/**
* token是否过期
*
* @return true过期
*/
public boolean isTokenExpired(Date expiration) {
return expiration.before(new Date());
}
public static void main(String[] args) {
Map<String, Object> map=new HashMap<>();
map.put("app","gov");
map.put("client","wxmp");
map.put("userId","100526ABC");
String tokenStr=Jwts.builder()
.setHeaderParam("typ", "JWT")
.setClaims(map)
.setIssuedAt(new Date())
.setExpiration(DateTime.now().plusSeconds(604800).toDate())
.signWith(SignatureAlgorithm.HS512, "7016867071f0ebf1c46f123eaaf4b9d6[elink.epmet]")
.compact();
System.out.println(tokenStr);
Claims claims= Jwts.parser()
.setSigningKey("7016867071f0ebf1c46f123eaaf4b9d6[elink.epmet]")
.parseClaimsJws(tokenStr)
.getBody();
System.out.println("app="+ claims.get("app"));
System.out.println("client="+ claims.get("client"));
System.out.println("userId="+ claims.get("userId"));
}
}

2
epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/exception/EpmetErrorCode.java

@ -95,7 +95,6 @@ public enum EpmetErrorCode {
SIGN_IN_TIME_NO(8513, "签到时间还未到~"),
SIGN_IN_TIME_END(8514, "签到时间已结束~"),
// 该错误不会提示给前端,只是后端传输错误信息用。
ACCESS_SQL_FILTER_MISSION_ARGS(8701, "缺少生成权限过滤SQL所需参数"),
OPER_ADD_CUSTOMER_ROOT_AGENCY_ERROR(8702, "添加客户根级组织失败"),
OPER_ADD_CUSTOMER_ROOT_AGENCY_EXISTS(8703, "添加客户根级组织失败,根级组织已存在"),
@ -108,6 +107,7 @@ public enum EpmetErrorCode {
OPER_EXTERNAL_CUSTOMER_NOT_EXISTS(8710, "该客户不存在"),
OPER_EXTERNAL_APP_EXISTS(8711, "应用已存在"),
OPER_EXT_APP_SECRET_RESET_FAIL(8713, "秘钥更新失败"),
UNSUPPORT_AUTH_TYPE(8714, "不支持的认证方式"),
// 党建声音 前端提示 88段
DRAFT_CONTENT_IS_NULL(8801, "至少需要添加一个段落"),

19
epmet-module/data-report/data-report-server/src/main/java/com/epmet/controller/test/TestController.java

@ -1,19 +0,0 @@
package com.epmet.controller.test;
import com.epmet.commons.extappauth.annotation.ExternalAppRequestAuth;
import com.epmet.commons.extappauth.bean.ExternalAppRequestParam;
import com.epmet.commons.tools.utils.Result;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("test")
public class TestController {
@ExternalAppRequestAuth
@RequestMapping("/test")
public Result test(ExternalAppRequestParam externalAppRequestParam, String ext) {
return new Result().ok("调用成功,客户信息:"+externalAppRequestParam);
}
}
Loading…
Cancel
Save