史上最全 Zuul 网关鉴权 范文
背景:
本次需求 有个testdemo的项目,我们需要通过走zuul搭建的网关来实现网关的鉴权。如果权限校验通过,则将请求分发到testdemo上,如果不通过就直接报401 无权限的错误
步骤:
1、自定义Filter类(AuthFilter)继承ZuulFilter类。
2、重写方法:
String filterType() //过滤器类型
int filterOrder() //过滤器执行顺序
boolean shouldFilter() //是否执行,这里可以写一些条件,比如特殊的引流,灰度发布等。。。
Object run() //核心类,我们的本次授权案例中,权限校验就是在这里做的。
3、然后就直接可以测试了
过滤器:
package com.yumingjiang.servicezuul.controller;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.http.HttpStatus;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 基于Zuul实现的鉴权
* <p>
* 继承ZuulFilter即可实现鉴权功能。
*/
@Component
public class AuthFilter extends ZuulFilter {
/**
* Filter 类型,
*
* @return
*/
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
/**
* 执行顺序。
* 需要最小的,执行的最靠前
*
* @return
*/
@Override
public int filterOrder() {
return 0;
}
/**
* 是否执行
* 注意这里的 true,false 是当前的filter是否跳过。并不是说直接在这里报错,刚才我这边也犯了这个毛病,导致了
* @return true 执行,false 不执行。
*/
@Override
public boolean shouldFilter() {
return true;
}
/**
* 执行内容
* 本案例以授权为主
* @return
* @throws ZuulException
*/
@Override
public Object run() throws ZuulException {
RequestContext context = RequestContext.getCurrentContext();
HttpServletRequest request = context.getRequest();
String token = request.getHeader("Cookie");
if ("pass".equals(token)){
return null;
}
//
context.setSendZuulResponse(false);
//设置响应状态码,这里是设置的未授权401错误吗
context.setResponseStatusCode(HttpStatus.SC_UNAUTHORIZED);
return null;
}
}
yml配置:
spring:
application:
name: service-zuul
server:
port: 8001
zuul:
routes:
custerm-service-name:
path: /zuul-custom-name/**
url: http://localhost/
testdemo测试用例:
@RestController
@RequestMapping("/cache")
public class GuavaCacheController {
/**
* 谷歌guava缓存
*/
LoadingCache<String, String> cache = CacheBuilder.newBuilder()
.expireAfterWrite(5, TimeUnit.SECONDS)
.build(new CacheLoader<String, String>() {
/**
* 这个load 方法为当缓存中没有数据的时候执行下面load方法。
* @param s
* @return
* @throws Exception
*/
@Override
public String load(String s) throws Exception {
return "load:" + new Random().nextInt(100);
}
});
@GetMapping("/get/{id}")
public String getFromCache(@PathVariable("id")String id){
String value = null;
try {
value = cache.get(id);
} catch (ExecutionException e) {
e.printStackTrace();
}
return value;
}
@PostMapping("/post/{id}")
public String putToCache(@PathVariable("id")String id){
cache.put(id,"put:"+new Random().nextInt(100));
return "success";
}
}
testdemo-yml配置:
server:
port: 80
spring:
application:
name: test-demo