项目地址:https://github.com/hx1098/leyou
最近开发中有一个鉴权的操作,最后需要进行添加白名单的,废话不多说,直接上代码吧,
这是我的项目结构
applicaton启动类:
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
/**
* Created with IDEA
* author:hanxiao
* Date:2019/12/9
* Time:21:44
*/
@EnableZuulProxy
@SpringCloudApplication //代表springbootapplication 熔断器
public class LyGateWayApplication {
public static void main(String[] args) {
SpringApplication.run(LyGateWayApplication.class,args);
}
}
2.application.yml
server:
port: 10010
spring:
application:
name: api-gateway
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
zuul:
prefix: /api # 添加路由前缀
routes:
item-service: /item/** # 商品微服务的映射路径
search-service: /search/** # 搜索微服务
user-service: /user/** # 用户微服务
auth-service: /auth/** # 授权中心微服务
upload-service:
path: /upload/**
serviceId: upload-service
strip-prefix: false
add-host-header: true #添加头
sensitive-headers: #覆盖敏感头信息,是cookie可以正常写入。
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMillisecond: 5000 # 熔断超时时长:10000ms
ribbon:
ConnectTimeout: 250 # 连接超时时间(ms)
ReadTimeout: 2000 # 通信超时时间(ms)
MaxAutoRetriesNextServer: 1 # 同一服务不同实例的重试次数
MaxAutoRetries: 0 # 同一实例的重试次数
leyou:
jwt:
pubKeyPath: C:\\tmp\\rsa\\rsa.pub # 公钥地址
cookieName: LY_TOKEN
filter: #需要进行过滤的白名单
allowPaths:
- /api/search
- /api/auth
- /api/user/register
- /api/user/check
- /api/user/code
- /api/item
这几行是白名单。
3.FilterProperties.class
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.List;
/**
* @author hx
* @Title:
* @Package
* @Description: 网关白名单
* @date 2020/2/1914:03
*/
@Data
@ConfigurationProperties(prefix = "leyou.filter")
public class FilterProperties {
private List allowPaths;
}
4.GlobalCors.class
package com.leyou.gateway.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
* Created with IDEA
* author:hanxiao
* Date:2019/12/12
* Time:11:01
*/
@Configuration
public class GlobalCorsConfig {
@Bean
public CorsFilter corsFilter() {
//1.添加CORS配置信息
CorsConfiguration config = new CorsConfiguration();
//1) 允许的域,不要写*,否则cookie就无法使用了
config.addAllowedOrigin("http://manage.leyou.com");
config.addAllowedOrigin("http://www.leyou.com");
config.addAllowedOrigin("http://api.leyou.com");
//config.addAllowedOrigin("*");
//2) 是否发送Cookie信息
config.setAllowCredentials(true);
//3) 允许的请求方式
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");
// 4)允许的头信息
config.addAllowedHeader("*");
// 4)有效时间
config.setMaxAge(3600L);
//2.添加映射路径,我们拦截一切请求
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
configSource.registerCorsConfiguration("/**", config);
//3.返回新的CorsFilter.
return new CorsFilter(configSource);
}
}
4.JwtProperties.calss
package com.leyou.gateway.config;
import com.leyou.auth.utils.RsaUtils;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import javax.annotation.PostConstruct;
import java.io.File;
import java.security.PrivateKey;
import java.security.PublicKey;
@Data
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "leyou.jwt")
public class JwtProperties {
private String pubKeyPath;// 公钥
private String cookieName;
private PublicKey publicKey; // 公钥
// 对象一旦实例化后,就应该读取公钥和私钥
@PostConstruct // 构造函数执行完毕后就执行
public void init(){
// 获取公钥和私钥
try {
this.publicKey = RsaUtils.getPublicKey(pubKeyPath);
} catch (Exception e) {
e.printStackTrace();
}
}
}
5.AuthFilter.calss
package com.leyou.gateway.filters;
import com.leyou.auth.entity.UserInfo;
import com.leyou.auth.utils.JwtUtils;
import com.leyou.common.utils.CookieUtils;
import com.leyou.gateway.config.FilterProperties;
import com.leyou.gateway.config.JwtProperties;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
/**
* @author hx
* @Title:
* @Package
* @Description: 拦截登录
* @date 2020/2/1913:25
*/
@Component
@EnableConfigurationProperties({JwtProperties.class, FilterProperties.class})
public class AuthFilter extends ZuulFilter {
@Autowired
private JwtProperties prop;
@Autowired
private FilterProperties filterProperties;
/**
* filter类型
* @return
*/
@Override
public String filterType() {
return FilterConstants.PRE_TYPE; //前置过滤
}
/**
* filter执行顺序,值越小优先级越高
* 官方推荐使用x-1方式优先排序
* @return
*/
@Override
public int filterOrder() {
return FilterConstants.PRE_DECORATION_FILTER_ORDER - 1;
}
/**
* filter 开启关闭
* @return
*/
@Override
public boolean shouldFilter() {
/* return true;*/
//获取上下文
RequestContext ctx = RequestContext.getCurrentContext();
//获取request
HttpServletRequest request = ctx.getRequest();
//获取请求的url路径
String path = request.getRequestURI();
//判断是否是白名单进行放行 放行返回false
return !isAllowPath(path);//是否过滤
}
private boolean isAllowPath(String path) {
//遍历白名单
for (String allowPath : filterProperties.getAllowPaths()) {
//判断是否允许
if(path.startsWith(allowPath)){
return true;
}
}
return false;
}
/**
* 实现filter逻辑
* @return
* @throws ZuulException
*/
@Override
public Object run() throws ZuulException {
//获取上下文
RequestContext ctx = RequestContext.getCurrentContext();
//获取request
HttpServletRequest request = ctx.getRequest();
//获取cookie总的token,
// Cookie[] cookies = request.getCookies();
//获取token
String token = CookieUtils.getCookieValue(request, prop.getCookieName());
//解析token
try {
UserInfo userInfo = JwtUtils.getInfoFromToken(token, prop.getPublicKey());
//Todo 校验权限
//校验用户的权限
}catch (Exception e){
//解析失败,未登录,进行拦截
ctx.setSendZuulResponse(false);
//返回状态码
ctx.setResponseStatusCode(403);
}
return null;
}
}
pom.xml
leyou
com.leiyou.parent
1.0-SNAPSHOT
4.0.0
com.leyou.common
ly-gateway
org.springframework.cloud
spring-cloud-starter-netflix-zuul
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.boot
spring-boot-starter-actuator
com.leiyou.parent
ly-auth-interface
1.0-SNAPSHOT
com.leiyou.common
ly-common
1.0-SNAPSHOT
ok完毕!
不过在代码写完的时候,我的网关总是在登录之后突然跳到了登录页面,调试了好久才发现,
这个地方一直是返回的true,所以他是都进行拦截的,根本没有拦截的效果。/衰/衰