1.pom文件

<dependencies>
<!--eureka客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--zuul网关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.ihrm</groupId>
<artifactId>ihrm_common</artifactId>
<version>1.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</exclusion>
</exclusions>
</dependency>

2.将shiro配置移至网关

package com.ihrm.gate.shiro.config;

import com.ihrm.common.shiro.CustomSessionManager;
import com.ihrm.common.shiro.IhrmRealm;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import java.util.LinkedHashMap;
import java.util.Map; @Configuration
public class ShiroConfig {
@Bean
public IhrmRealm ihrmRealm() {
return new IhrmRealm();
}
@Bean
public DefaultWebSecurityManager getSecurityManager(DefaultWebSessionManager sessionManager, RedisCacheManager cacheManager) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(ihrmRealm()); //将自定义的会话管理器注册到安全管理器中
securityManager.setSessionManager(sessionManager);
//将自定义的redis缓存管理器注册到安全管理器中
securityManager.setCacheManager(cacheManager); return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager) {
//1.创建过滤器工厂
ShiroFilterFactoryBean filterFactory = new ShiroFilterFactoryBean();
//2.设置安全管理器
filterFactory.setSecurityManager(securityManager);
//3.通用配置(跳转登录页面,未授权跳转的页面)
filterFactory.setLoginUrl("/autherror?code=1");//跳转url地址
filterFactory.setUnauthorizedUrl("/autherror?code=2");//未授权的url
//4.设置过滤器集合
Map<String,String> filterMap = new LinkedHashMap<>();
//anon -- 匿名访问
filterMap.put("/sys/login","anon");
filterMap.put("/autherror","anon");
//注册
//authc -- 认证之后访问(登录)
filterMap.put("/**","authc");
//perms -- 具有某中权限 (使用注解配置授权)
filterFactory.setFilterChainDefinitionMap(filterMap); return filterFactory;
}
/**
* 再web程序中,shiro进行权限控制全部是通过一组过滤器集合进行控制
*
*/ @Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private Integer port;
/**
* 1.redis的控制器,操作redis
*/
public RedisManager redisManager() {
RedisManager redisManager = new RedisManager();
redisManager.setHost(host+ ":" + port);
return redisManager;
} /**
* 2.sessionDao
*/
public RedisSessionDAO redisSessionDAO() {
RedisSessionDAO sessionDAO = new RedisSessionDAO();
sessionDAO.setRedisManager(redisManager());
return sessionDAO;
} /**
* 3.会话管理器
*/
@Bean
public DefaultWebSessionManager sessionManager() {
CustomSessionManager sessionManager = new CustomSessionManager();
//shiro 的session默认放在cookie中 禁用
sessionManager.setSessionIdCookieEnabled(false);
//禁用url 重写 url; shiro请求时默认 jsessionId=id
sessionManager.setSessionIdUrlRewritingEnabled(false);
sessionManager.setSessionDAO(redisSessionDAO());
return sessionManager;
} /**
* 4.缓存管理器
*/
@Bean
public RedisCacheManager cacheManager() {
RedisCacheManager redisCacheManager = new RedisCacheManager();
redisCacheManager.setRedisManager(redisManager());
return redisCacheManager;
} //开启对shior注解的支持
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
}

3.realm,此realm只负责鉴权不负责认证

package com.ihrm.common.shiro;

import com.ihrm.domain.system.response.ProfileResult;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection; import java.util.Set; public class IhrmRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
ProfileResult result = (ProfileResult)getAvailablePrincipal(principalCollection);
Set<String> apis = (Set<String>)result.getRoles().get("apis");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setStringPermissions(apis);
return info;
} @Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
return null;
}
}

4.启动类

package com.ihrm.gate;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy; @SpringBootApplication(scanBasePackages = "com.ihrm")
@EnableDiscoveryClient
@EnableZuulProxy
public class GateApplication {
public static void main(String[] args) {
SpringApplication.run(GateApplication.class,args);
}
}

5.配置信息

server:
port: 9696
spring:
application:
name: ihrm-gate #指定服务名
eureka:
client:
service-url:
defaultZone: http://localhost:6868/eureka
instance:
prefer-ip-address: true
zuul:
routes:
ihrm-company:
path: /company/**
# url: http://127.0.0.1:9001 #映射路径对应的实际url地址
serviceId: ihrm-company
stripPrefix: false
sentiviteHeaders: #将指定路由的敏感头设置为空
customSensitiveHeaders: true #对指定路由开启自定义敏感头
ihrm-system:
path: /sys/**
# url: http://127.0.0.1:9001 #映射路径对应的实际url地址
serviceId: ihrm-system
stripPrefix: false
sentiviteHeaders: #将指定路由的敏感头设置为空
customSensitiveHeaders: true #对指定路由开启自定义敏感头

6.向服务传递登陆用户信息

package com.ihrm.gate.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.ihrm.domain.system.response.ProfileResult;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.Serializable;
import java.net.URLEncoder; @Component
public class LoginFilter extends ZuulFilter {
/**
* pre: 在请求路径之前执行
* routing: 在请求路径时执行
* post: 在请求路径后执行
* error: 在请求发生错误时执行
* @return
*/
public String filterType() {
return "pre";
} /**
* 优先级为0,数字越大,优先级越低
* @return
*/
public int filterOrder() {
return 0;
} /**
*是否执行该过滤器,此处为true,说明需要过滤
* 一些不需要过滤的请求返回false
* @return
*/
public boolean shouldFilter() {
return true;
} /**
* 过滤器执行的具体逻辑
* @return
* @throws ZuulException
*/
@SneakyThrows
public Object run() throws ZuulException {
// System.out.println("LoginFilter执行了");
RequestContext context = RequestContext.getCurrentContext();
HttpServletRequest req = context.getRequest();
Subject subject = SecurityUtils.getSubject();
//获取用户信息
PrincipalCollection principals = subject.getPrincipals();
if (principals != null) {
ProfileResult result = (ProfileResult) principals.getPrimaryPrincipal();
//将用户信息json并编码(不编码服务取出时中文乱码)
String resultJson = new Gson().toJson(result);
resultJson = new String(Base64.encode(resultJson.getBytes("UTF-8")));
//放入
context.addZuulRequestHeader("key1", resultJson);
} return null;
} }

7.服务获取用户信息

     HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String userJson = req.getHeader("key1");
userJson = new String(Base64.decode(userJson.getBytes("UTF-8")));
result = new Gson().fromJson( userJson,ProfileResult.class);

springcloud zuul shiro网关鉴权并向服务传递用户信息的更多相关文章

  1. 使用网关zuul过滤器登录鉴权

    使用网关zuul过滤器登录鉴权     1.新建一个filter包         filte有很多种 pre.post.     2.新建一个类LoginFilter,实现ZuulFilter,重写 ...

  2. 网关鉴权后下游统一filter获取用户信息

    1. 场景描述 最近有点忙,在弄微服务nacos+springcloud gateway这块工作,以前只是简单应用,这次因为要对接10几个系统或者平台,还的鉴权,等后续稍微闲点了,把这块东西总结下. ...

  3. Shiro的鉴权方式

    一. 怎么用 Shiro 支持三种方式的授权 编程式:通过写 if/else 授权代码块完成: Subject subject = SecurityUtils.getSubject(); if(sub ...

  4. Java架构笔记:用JWT对SpringCloud进行认证和鉴权

    写在前面 喜欢的朋友可以关注下专栏:Java架构技术进阶.里面有大量batj面试题集锦,还有各种技术分享,如有好文章也欢迎投稿哦. image.png JWT(JSON WEB TOKEN)是基于RF ...

  5. 微服务架构下使用Spring Cloud Zuul作为网关将多个微服务整合到一个Swagger服务上

    注意: 如果你正在研究微服务,那必然少不了服务之间的相互调用,哪么服务之间的接口以及api就必须生成系统的管理文档了.如果你希望更好的管理你的API,你希望有一个工具能一站式地解决API相关的所有事情 ...

  6. shiro jwt 构建无状态分布式鉴权体系

    一:JWT 1.令牌构造 JWT(json web token)是可在网络上传输的用于声明某种主张的令牌(token),以JSON 对象为载体的轻量级开放标准(RFC 7519). 一个JWT令牌的定 ...

  7. shiro,基于springboot,基于前后端分离,从登录认证到鉴权,从入门到放弃

    这个demo是基于springboot项目的. 名词介绍: ShiroShiro 主要分为 安全认证 和 接口授权 两个部分,其中的核心组件为 Subject. SecurityManager. Re ...

  8. SpringCloud学习系列之七 ----- Zuul路由网关的过滤器和异常处理

    前言 在上篇中介绍了SpringCloud Zuul路由网关的基本使用版本,本篇则介绍基于SpringCloud(基于SpringBoot2.x,.SpringCloud Finchley版)中的路由 ...

  9. 从零开始学YC-Framework之鉴权

    一.YC-Framework鉴权是基于哪一个开源框架做的? YC-Framework鉴权主要基于Dromara开源社区组织下的Sa-Token. 1.什么是Sa-Token? Sa-Token是一个轻 ...

随机推荐

  1. 『Python』matplotlib坐标轴应用

    1. 设置坐标轴的位置和展示形式 import numpy as np import matplotlib.pyplot as plt import matplotlib as mpl mpl.use ...

  2. P7737-[NOI2021]庆典【tarjan,虚树】

    正题 题目链接:https://www.luogu.com.cn/problem/P7737 题目大意 给出一张无向图满足若\(x\Rightarrow z,y\Rightarrow z\)那么有\( ...

  3. P1791-[国家集训队]人员雇佣【最大权闭合图】

    正题 题目链接:https://www.luogu.com.cn/problem/P1791 题目大意 有\(n\)个人,雇佣第\(i\)个需要\(A_i\)的费用,对于\(E_{i,j}\)表示如果 ...

  4. CF618F-Double Knapsack【结论】

    正题 题目链接:https://www.luogu.com.cn/problem/CF618F 题目大意 给出大小为\(n\),值域为\([1,n]\)的两个可重集合\(A,B\) 需要你对它们各求出 ...

  5. Vue router中携带参数与获取参数

    Vue router中携带参数与获取参数 携带参数 query方式,就是?+&结构,例如/login?id=1 <router-link :to="{ name:'login' ...

  6. 突破GD渲染的图片马

    <?php /* The algorithm of injecting the payload into the JPG image, which will keep unchanged aft ...

  7. pdb的插拔测试

    pdb的插拔测试:将pdb从一个cdb中,插拔到另一个cdb中. 源端pdb unplug SQL> select instance_name from v$instance; INSTANCE ...

  8. 【Azure 云服务】Azure Cloud Service 为 Web Role(IIS Host)增加自定义字段 (把HTTP Request Header中的User-Agent字段增加到IIS输出日志中)

    问题描述 把Web Role服务发布到Azure Cloud Service后,需要在IIS的输出日志中,把每一个请求的HTTP Request Header中的User-Agent内容也输出到日志中 ...

  9. EPUB文件格式简单解析

    最近热衷于看轻小说,奈何某些网站样式排版属实糟糕,移动端体验极度不友好,实在无法忍受,于是希望能将网站内容爬取下来制作成EPUB格式的电子书. 抛开爬取网站内容不谈,通过解析EPUB文件后,大致掌握了 ...

  10. Win10开启剪贴板

    点击任务栏下方右侧的会话窗口 点击所有设置 在搜索栏中输入剪贴板,点击进入剪贴板设置 开启剪贴板历史记录 按下组合键win + v即可呼出剪贴板