如图所示,
1、我的用户登录之后,并不是直接访问微服务,是由网关去分发跳转指定的微服务【用户登陆我没有做认证,只要你登陆了,我就把头信息原封不动的传下去】
2、后台人员登陆怎么办呢,我在ManagerFilter拦截器里面去判断他是不是管理员,如果是,头信息原封不动的往下传,如果不是,判处异常权限不足,往下的步骤直接不执行
废话不多说,上代码
前台网关
pom依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>com.pure</groupId>
<artifactId>pure_common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
application.yml
server:
port: 9012
spring:
application:
name: pure-web #指定服务名
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:7878/eureka/
instance:
prefer-ip-address: true #是为了在线上时模块之间能够跨域访问
zuul:
routes:
pure-user: #用户
path: /user/** #配置请求URL的请求规则
serviceId: pure-user #指定Eureka注册中心中的服务id
pure-Article: #文章
path: /article/** #配置请求URL的请求规则
serviceId: pure-Article #指定Eureka注册中心中的服务id
pure-base: #基础
path: /base/** #带有这个路径,自动往pure-base这里跳转,【zuul网关操作】
serviceId: pure-base #指定Eureka注册中心中的服务id
启动类
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableEurekaClient
@EnableZuulProxy
public class WebApplication {
public static void main ( String[] args ) {
SpringApplication.run ( WebApplication.class,args );
}
}
拦截器
//web的Zuul拦截器只要转发头信息就可以,这是用户的操作,不需要验证是否管理员权限
@Component
public class WebFilter extends ZuulFilter {
@Override
public String filterType () {
return "pre";
}
@Override
public int filterOrder () {
return 0;
}
@Override
public boolean shouldFilter () {
return true;
}
@Override
public Object run () throws ZuulException {
System.out.println ( "经过前台Zuul过滤器" );
//先得到Request上下文
RequestContext currentContext = RequestContext.getCurrentContext ( );
//得到Request域
HttpServletRequest request = currentContext.getRequest ( );
//得到头信息
String header = request.getHeader ( "Authorization" );
//判断是否有头信息
if (StringUtils.isNotEmpty ( header ) && StringUtils.isNotEmpty ( " " )) {
//把头信息继续往下传
currentContext.addZuulRequestHeader ( "Authorization",header );
}
return null;
}
}
后台网关
pom依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>com.pure</groupId>
<artifactId>pure_common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
application.yml
server:
port: 9012
spring:
application:
name: pure-web #指定服务名
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:7878/eureka/
instance:
prefer-ip-address: true #是为了在线上时模块之间能够跨域访问
zuul:
routes:
pure-user: #用户
path: /user/** #配置请求URL的请求规则
serviceId: pure-user #指定Eureka注册中心中的服务id
pure-Article: #文章
path: /article/** #配置请求URL的请求规则
serviceId: pure-Article #指定Eureka注册中心中的服务id
pure-base: #基础
path: /base/** #带有这个路径,自动往pure-base这里跳转,【zuul网关操作】
serviceId: pure-base #指定Eureka注册中心中的服务id
启动类
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableEurekaClient
@EnableZuulProxy
public class ManagerApplication {
public static void main ( String[] args ) {
SpringApplication.run ( ManagerApplication.class,args );
}
@Bean
public JwtUtil jwtUtil(){
return new JwtUtil ();
}
}
后台拦截器
/**
* @author 刘乐锋
* @create 2021/3/18 15:20
*/
//Manager的Zuul拦截器,要执行转发头信息,并且要验证权限
@Component
public class ManagerFilter extends ZuulFilter {
@Autowired
private JwtUtil jwtUtil;
@Override
public String filterType () {
//pre表示执行之前过滤
//post表示执行之后进行过滤
return "pre";
}
@Override
public int filterOrder () {//排序,0表示优先执行
return 0;
}
@Override
public boolean shouldFilter () {
return true;
}
@Override
public Object run () throws ZuulException {
System.out.println ( "经过后台zuul过滤器" );
//先得到Request上下文
RequestContext requestContext = RequestContext.getCurrentContext ( );
HttpServletRequest request = requestContext.getRequest ( ); //获取request
/**
* 在转发的时候,内部有一个OPTIONS方法,这个方法负责找具体的请分支跳转
* 任何经过网关的请求都是两次,分发路径的请求,第一次没有携带Authorization
*/
if (request.getMethod ( ).equals ( "OPTIONS" )) {
return null;
}
/**
* 登陆放行
*/
//当前这个单词在路径中出现的位置,出现在哪个位置,就返回哪个位置下标,如果没有就是等于 0,有就是大于0即登陆请求
if (request.getRequestURI ( ).indexOf ( "admin/login" ) > 0) {
return null;
}
//得到头信息
String header = request.getHeader ( "Authorization" );
if (StringUtils.isNotEmpty ( header ) && StringUtils.isNotEmpty ( " " )) {
if (header.startsWith ( "Bearer" )) {
String token = header.substring ( 7 );
try {
Claims claims = jwtUtil.parseJWT ( token );
String roles = (String) claims.get ( "roles" );
if (roles.equals ( "admin" )) {
//转发头信息,并且放行
requestContext.addZuulRequestHeader ( "Authorization",header );
System.out.println ( "token验证通过,添加了头信息"+header );
return null; // return null就是转发
}
} catch (Exception e) {
requestContext.setSendZuulResponse ( false ); //终止运行
}
}
}
requestContext.setSendZuulResponse ( false ); //终止运行
requestContext.setResponseStatusCode ( 403 ); //权限不足
requestContext.setResponseBody ( "权限不足" );
requestContext.getResponse ( ).setContentType ( "text/html;charset=utf-8" ); //这不是JSON如果是json【application/json】
return null;
}
}
技术有待欠缺,请指导!!!!