4 changed files with 250 additions and 0 deletions
@ -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<String> urls; |
|||
|
|||
@Override |
|||
public Mono<Void> 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<UserDetail> 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<Void> 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<String> getUrls() { |
|||
return urls; |
|||
} |
|||
|
|||
public void setUrls(List<String> urls) { |
|||
this.urls = urls; |
|||
} |
|||
|
|||
} |
@ -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; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,71 @@ |
|||
/** |
|||
* Copyright (c) 2018 人人开源 All rights reserved. |
|||
* <p> |
|||
* https://www.renren.io
|
|||
* <p> |
|||
* 版权所有,侵权必究! |
|||
*/ |
|||
|
|||
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<String,Object> 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()); |
|||
} |
|||
} |
Loading…
Reference in new issue