Browse Source

Merge branch 'dev_externalappauth' into dev_screen_data_2.0

dev_shibei_match
wxz 5 years ago
parent
commit
9ced7bf3fd
  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. 122
      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. 6
      epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/exception/EpmetErrorCode.java
  7. 2
      epmet-module/data-report/data-report-server/src/main/java/com/epmet/datareport/controller/screen/KcScreenController.java
  8. 10
      epmet-module/data-report/data-report-server/src/main/resources/bootstrap.yml

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 {
}

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

@ -1,14 +1,24 @@
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.alibaba.fastjson.JSON;
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;
@ -19,12 +29,14 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Parameter;
import java.util.Map;
/**
* 外部应用请求认证切面
@ -36,6 +48,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";
@ -45,15 +58,121 @@ 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))) {
// 走内部应用认证
internalAppAuth(signature, point, request);
} else {
logger.error("根据header无法找到适用的认证方式");
throw new RenException(EpmetErrorCode.ERR401.getCode(), EpmetErrorCode.ERR401.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()));
if (CollectionUtils.isEmpty(tokenMap)) {
logger.error("内部应用认证,redis中没有找到登录缓存信息");
throw new RenException(EpmetErrorCode.ERR10006.getCode(), EpmetErrorCode.ERR10006.getMsg());
}
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);
@ -90,7 +209,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"));
}
}

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

@ -107,9 +107,9 @@ public enum EpmetErrorCode {
OPER_EXTERNAL_APP_AUTH_ERROR(8709, "外部应用认证失败"),
OPER_EXTERNAL_CUSTOMER_NOT_EXISTS(8710, "该客户不存在"),
OPER_EXTERNAL_APP_EXISTS(8711, "应用已存在"),
OPER_CUSTOMER_FOOTBAR_EXISTS(8712, "footbar已存在"),
OPER_CUSTOMER_FOOTBAR_NOT_FOUND(8713, "footbar不存在"),
OPER_EXT_APP_SECRET_RESET_FAIL(8713, "秘钥更新失败"),
OPER_CUSTOMER_FOOTBAR_EXISTS(8712, "footbar已存在"),
OPER_CUSTOMER_FOOTBAR_NOT_FOUND(8713, "footbar不存在"),
OPER_EXT_APP_SECRET_RESET_FAIL(8714, "秘钥更新失败"),
// 党建声音 前端提示 88段
DRAFT_CONTENT_IS_NULL(8801, "至少需要添加一个段落"),

2
epmet-module/data-report/data-report-server/src/main/java/com/epmet/datareport/controller/screen/KcScreenController.java

@ -1,6 +1,7 @@
package com.epmet.datareport.controller.screen;
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.tools.utils.Result;
import com.epmet.commons.tools.validator.ValidatorUtils;
@ -75,6 +76,7 @@ public class KcScreenController {
* @return
*/
@ExternalAppRequestAuth
@InternalAppRequestAuth
@PostMapping("issue/summary")
public Result getIssueSummary(ExternalAppRequestParam externalAppRequestParam) {
String customerId = externalAppRequestParam.getCustomerId();

10
epmet-module/data-report/data-report-server/src/main/resources/bootstrap.yml

@ -140,4 +140,12 @@ pagehelper:
dingTalk:
robot:
webHook: @dingTalk.robot.webHook@
secret: @dingTalk.robot.secret@
secret: @dingTalk.robot.secret@
jwt:
token:
#秘钥
secret: 7016867071f0ebf1c46f123eaaf4b9d6[elink.epmet]
#token有效时长,默认7天,单位秒
expire: 604800
Loading…
Cancel
Save