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. [转载]CentOS 7 用户怎样安装 LNMP(Nginx+PHP+MySQL)

    关于 Nginx (发音 "engine x")这是一款免费.开源.高效的 HTTP 服务器,Nginx是以稳定著称,丰富的功能,结构简单,低资源消耗.本教程演示如何在CentOS ...

  2. YbtOJ#763-攻城略池【线段树合并】

    正题 题目链接:http://www.ybtoj.com.cn/problem/763 题目大意 给出\(n\)个点的一棵树,每个\(d_i=0\)的点每秒会产生一个士兵往根节点走,走到一个节点让一个 ...

  3. oracle常见命令

    1.权限 (1)系统权限 系统权限是指对数据库系统的权限和对象结构控制的权限. 如grant create session to 用户名 -赋予用户登录的权限 (2)对象权限 访问其它用户对象的权利 ...

  4. serialVersionUID序列化版本号与ObjectOutputStream对象输入输出流

    1. 观察ObjectOutputStream 我们观察ObjectOutputStream就可以发现该类没有无参构造,只有有参构造,所以他是一个包装流 2. 具体使用: public static ...

  5. JDK源码阅读(4):HashMap类阅读笔记

    HashMap public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>, ...

  6. display:none、visibility:hidden,opacity:0三者区别

    1. display:none 设置display:none,让这个元素消失 消失不占据原本任何位置 连带子元素一起消失 元素显示:display:block 2. visibility:hidden ...

  7. VS Code环境配置

    1.语言配置 2.Node.js安装配置 系统变量中NODE_PATH,变量值为nodejs的安装路径. 用户变量Path包含%NODE_PATH% 如果说通过CMD打开的命令行可以执行node -v ...

  8. pycharm上的python虚拟环境移到离线机器上

    Pycharm的Terminal 中执行: 查看现有的包到requirements.txt中 pip freeze > requirements.txt 生成依赖包 D:\machangwei\ ...

  9. Linux系统安装MySql5.7并通过sql脚本导入数据

    为了下载到的MySQL版本和目标系统相互兼容,在开启之前,最好了解目标系统的相关信息. 查询系统版本: cat /etc/issue 查看系统位数 getconf LONG_BIT 选择MySQL 根 ...

  10. Spring启动过程源码分析基本概念

    Spring启动过程源码分析基本概念 本文是通过AnnotationConfigApplicationContext读取配置类来一步一步去了解Spring的启动过程. 在看源码之前,我们要知道某些类的 ...