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. nextcloud 中文乱码解决方案

    参考地址 :https://www.yht7.com/news/13909 我是使用的第二种方法, 修改/nextcloud/lib/public/AppFramework/Http/FileDisp ...

  2. FastAPI(45)- JSONResponse

    背景 创建 FastAPI 路径操作函数时,通常可以从中返回任何数据:字典.列表.Pydantic 模型.数据库模型等 默认情况下,FastAPI 会使用 jsonable_encoder 自动将该返 ...

  3. Mac里存储空间不足,该怎么删垃圾数据?

    说明:在mac设备运行一段时间后,电脑空间很小了,对于开发者来说,清清Xcode缓存,腾出几十G的空间还是有可能的.在升级Xcode适配新系统.新手机也是得给电脑减减压. 一.Xcode缓存文件(co ...

  4. 数据结构与算法——弗洛伊德(Floyd)算法

    介绍 和 Dijkstra 算法一样,弗洛伊德(Floyd)算法 也是一种用于寻找给定的加权图中顶点间最短路径的算法.该算法名称以创始人之一.1978 年图灵奖获得者.斯坦福大学计算机科学系教授罗伯特 ...

  5. WPF实现聚光灯效果

    WPF开发者QQ群: 340500857  | 微信群 -> 进入公众号主页 加入组织 前言 效果仿照 CSS聚光灯效果 实现思路: 1. 设置底部Canvas背景色 #222222 . 2. ...

  6. SpringBoot配置文件application

    配置文件 SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的,有两种文件格式: application.properties 语法结构 :key=value application. ...

  7. 双系统升win11(grub启动问题修复与讲解)?!?

    起 最近win11不是出来了吗.(着急修复的可以直接跳到最后一步) 于是我就突发奇想给我半年没进去的windows升个级........ 于是我找到了我win11的升级包(从我一个同学哪儿) 工具都集 ...

  8. JVM详解(五)——运行时数据区-方法区

    一.概述 1.介绍 <Java虚拟机规范>中明确说明:尽管所有的方法区在逻辑上属于堆的一部分,但一些简单的实现可能不会选择去进行垃圾收集或者进行压缩.但对于HotSpot JVM而言,方法 ...

  9. 【错误分析】NX error status: 32

    在进行NX 制图里面的表格注释合并单元格时,总是报错NX error status: 32,找了很久都不知道问题所在. 报错提示如下: NXOpen.NXException: NX error sta ...

  10. Mybatis初始化机制

    对于任何框架而言,在使用前都要进行一系列的初始化,MyBatis也不例外.本章将通过以下几点详细介绍MyBatis的初始化过程. 1.MyBatis的初始化做了什么 2. MyBatis基于XML配置 ...