From 343d6e4c86085d3025b554fea1c06817a3c74795 Mon Sep 17 00:00:00 2001 From: songyunpeng Date: Wed, 3 Feb 2021 09:59:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=97=A5=E5=BF=97=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../esua/epdc/filter/WorkLogAuthFilter.java | 139 ++++++++++++++++++ .../esua/epdc/jwt/JwtTokenProperties.java | 33 +++++ .../elink/esua/epdc/jwt/JwtTokenUtils.java | 71 +++++++++ .../src/main/resources/application.yml | 7 + 4 files changed, 250 insertions(+) create mode 100644 epdc-cloud-gateway/src/main/java/com/elink/esua/epdc/filter/WorkLogAuthFilter.java create mode 100644 epdc-cloud-gateway/src/main/java/com/elink/esua/epdc/jwt/JwtTokenProperties.java create mode 100644 epdc-cloud-gateway/src/main/java/com/elink/esua/epdc/jwt/JwtTokenUtils.java diff --git a/epdc-cloud-gateway/src/main/java/com/elink/esua/epdc/filter/WorkLogAuthFilter.java b/epdc-cloud-gateway/src/main/java/com/elink/esua/epdc/filter/WorkLogAuthFilter.java new file mode 100644 index 0000000..b056aaf --- /dev/null +++ b/epdc-cloud-gateway/src/main/java/com/elink/esua/epdc/filter/WorkLogAuthFilter.java @@ -0,0 +1,139 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.elink.esua.epdc.filter; + +import com.alibaba.fastjson.JSON; +import com.elink.esua.epdc.commons.tools.constant.Constant; +import com.elink.esua.epdc.commons.tools.exception.RenException; +import com.elink.esua.epdc.commons.tools.security.user.UserDetail; +import com.elink.esua.epdc.commons.tools.utils.Result; +import com.elink.esua.epdc.feign.ResourceFeignClient; +import com.elink.esua.epdc.jwt.JwtTokenUtils; +import io.jsonwebtoken.Claims; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.util.AntPathMatcher; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.nio.charset.StandardCharsets; +import java.util.List; + +/** + * 权限过滤器 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Configuration +@ConfigurationProperties(prefix = "worklog") +public class WorkLogAuthFilter implements GlobalFilter { + + private final AntPathMatcher antPathMatcher = new AntPathMatcher(); + + @Autowired + private ResourceFeignClient resourceFeignClient; + + @Autowired + private JwtTokenUtils jwtUtils; + + /** + * 拦截的工作日志接口 + */ + private List urls; + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + ServerHttpRequest request = exchange.getRequest(); + String requestUri = request.getPath().pathWithinApplication().value(); + + //请求放行,无需验证权限 + if(pathMatcher(requestUri)){ + return chain.filter(exchange); + } + + //获取AccessToken 并进行验证 + String accessToken = request.getHeaders().getFirst(Constant.ACCESS_TOKEN); + if(StringUtils.isBlank(accessToken)){ + // 表示请求信息中没有携带AccessToken,前端需要修改上送数据 + throw new RenException("AccessToken为空"); + } + + Claims claims = jwtUtils.getClaimByToken(accessToken); + + if (claims == null) { + throw new RenException("AccessToken验证不通过"); + } + //验证结束 + + //获取用户token + String token = request.getHeaders().getFirst(Constant.TOKEN_HEADER); + if(StringUtils.isBlank(token)){ + token = request.getHeaders().getFirst(Constant.AUTHORIZATION_HEADER); + if (StringUtils.isBlank(token)) { + token = request.getQueryParams().getFirst(Constant.TOKEN_HEADER); + } + } + + //资源访问权限 + String language = request.getHeaders().getFirst(HttpHeaders.ACCEPT_LANGUAGE); + Result result = resourceFeignClient.resource(language, token, requestUri, request.getMethod().toString()); + //没权限访问,直接返回 + if(!result.success()){ + return response(exchange, result); + } + + //获取用户信息 + UserDetail userDetail = result.getData(); + if(userDetail != null){ + //当前登录用户userId,添加到header中 + ServerHttpRequest build = exchange.getRequest().mutate().header(Constant.USER_KEY, userDetail.getId()+"").build(); + return chain.filter(exchange.mutate().request(build).build()); + } + + return chain.filter(exchange); + } + + private Mono response(ServerWebExchange exchange, Object object) { + String json = JSON.toJSONString(object); + DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(json.getBytes(StandardCharsets.UTF_8)); + exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON_UTF8); + exchange.getResponse().setStatusCode(HttpStatus.OK); + return exchange.getResponse().writeWith(Flux.just(buffer)); + } + + private boolean pathMatcher(String requestUri){ + + for (String url : urls) { + if(antPathMatcher.match(url, requestUri)){ + return false; + } + } + return true; + } + + public List getUrls() { + return urls; + } + + public void setUrls(List urls) { + this.urls = urls; + } + +} diff --git a/epdc-cloud-gateway/src/main/java/com/elink/esua/epdc/jwt/JwtTokenProperties.java b/epdc-cloud-gateway/src/main/java/com/elink/esua/epdc/jwt/JwtTokenProperties.java new file mode 100644 index 0000000..13faf89 --- /dev/null +++ b/epdc-cloud-gateway/src/main/java/com/elink/esua/epdc/jwt/JwtTokenProperties.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.elink.esua.epdc.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; + + public String getSecret() { + return secret; + } + + public void setSecret(String secret) { + this.secret = secret; + } + +} diff --git a/epdc-cloud-gateway/src/main/java/com/elink/esua/epdc/jwt/JwtTokenUtils.java b/epdc-cloud-gateway/src/main/java/com/elink/esua/epdc/jwt/JwtTokenUtils.java new file mode 100644 index 0000000..e358728 --- /dev/null +++ b/epdc-cloud-gateway/src/main/java/com/elink/esua/epdc/jwt/JwtTokenUtils.java @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + *

+ * https://www.renren.io + *

+ * 版权所有,侵权必究! + */ + +package com.elink.esua.epdc.jwt; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +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.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; + + /** + * 生成上报接口accessToken + * + * @param claims + * @return java.lang.String + * @author Liuchuang + * @since 2020/9/7 14:11 + */ + public String getEpmetAccessToken(Map claims){ + return Jwts.builder() + .setHeaderParam("typ", "JWT") + .setClaims(claims) + .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; + } + } + + /** + * token是否过期 + * + * @return true:过期 + */ + public boolean isTokenExpired(Date expiration) { + return expiration.before(new Date()); + } +} diff --git a/epdc-cloud-gateway/src/main/resources/application.yml b/epdc-cloud-gateway/src/main/resources/application.yml index 0df0964..05eefca 100644 --- a/epdc-cloud-gateway/src/main/resources/application.yml +++ b/epdc-cloud-gateway/src/main/resources/application.yml @@ -241,6 +241,13 @@ ribbon: ReadTimeout: 300000 ConnectTimeout: 300000 +jwt: + token: + #秘钥 + secret: 033ac399fde8ae357b8455e03cad1d23[elink.epdc] + #APPID + appid: 03238e644c1bf4f4b349e3a68f6449a0 + renren: urls: - /auth/captcha