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. 检验appium环境是否正常:使用appium自动给手机安装app(注意:如果已存在该app,再执行会将原来的卸载再重装,需谨慎)

    (注意:如果已存在该app,再执行会将原来的卸载再重装.泪的教训,我的微信被卸载重装了o(╥﹏╥)o,自动安装app这个步骤需谨慎操作) hi,前面几篇已经讲了appium环境的搭建.设备的连接, 那 ...

  2. requests访问页面时set-cookie获取cookie

    import requests headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/ ...

  3. 如何通过云效Flow完成自动化部署—主机部署

    如何通过云效Flow完成自动化部署-主机部署,云效流水线Flow是持续交付的载体,通过构建自动化.集成自动化.验证自动化.部署自动化,完成从开发到上线过程的持续交付.通过持续向团队提供及时反馈,让交付 ...

  4. 2021“MINIEYE杯”中国大学生算法设计超级联赛(7)部分题解

    前言 找大佬嫖到个号来划水打比赛了,有的题没写或者不是我写的就不放了. 目前只有:1004,1005,1007,1008,1011 正题 题目链接:https://acm.hdu.edu.cn/con ...

  5. Redis之品鉴之旅(七)

    分布式锁 1)阻塞锁: 尝试在redis中创建一个字符串结构缓存,方法传入的key,value为锁的过期时间timeout的时间戳. 若redis中没有这个key,则创建成功(即抢到锁),然后立即返回 ...

  6. 在Anaconda环境下安装Tensorflow

    安装Anaconda 下载Anaconda 个人版Individual Edition.如果下载速度慢,可以复制下载链接到迅雷或者在清华大学开源镜像站TUNA中找合适的版本. 注意在安装过程中的&qu ...

  7. Kubernetes集群(RKE)安装ArgoCD排坑

    Photo by Pixabay from Pexels Argo CD是一个声明式的,基于Kubernetes的GitOps持续交付工具.更多的细节参考 ArgoCD官网 的说明,这里记录了一些实践 ...

  8. oracle查看和修改session和最大连接数

    第一步,在cmd命令行,输入sqlplus 第二步,根据提示输入用户名与密码 1. 查看processes和sessions参数 SQL> show parameter processes NA ...

  9. 【Docker】(9)---每天5分钟玩转 Docker 容器技术之镜像

    镜像是 Docker 容器的基石,容器是镜像的运行实例,有了镜像才能启动容器.为什么我们要讨论镜像的内部结构? 如果只是使用镜像,当然不需要了解,直接通过 docker 命令下载和运行就可以了. 但如 ...

  10. 2020.10.16--vj个人赛补题

    D - Drinks Choosing Old timers of Summer Informatics School can remember previous camps in which eac ...