springcloud zuul shiro网关鉴权并向服务传递用户信息
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网关鉴权并向服务传递用户信息的更多相关文章
- 使用网关zuul过滤器登录鉴权
使用网关zuul过滤器登录鉴权 1.新建一个filter包 filte有很多种 pre.post. 2.新建一个类LoginFilter,实现ZuulFilter,重写 ...
- 网关鉴权后下游统一filter获取用户信息
1. 场景描述 最近有点忙,在弄微服务nacos+springcloud gateway这块工作,以前只是简单应用,这次因为要对接10几个系统或者平台,还的鉴权,等后续稍微闲点了,把这块东西总结下. ...
- Shiro的鉴权方式
一. 怎么用 Shiro 支持三种方式的授权 编程式:通过写 if/else 授权代码块完成: Subject subject = SecurityUtils.getSubject(); if(sub ...
- Java架构笔记:用JWT对SpringCloud进行认证和鉴权
写在前面 喜欢的朋友可以关注下专栏:Java架构技术进阶.里面有大量batj面试题集锦,还有各种技术分享,如有好文章也欢迎投稿哦. image.png JWT(JSON WEB TOKEN)是基于RF ...
- 微服务架构下使用Spring Cloud Zuul作为网关将多个微服务整合到一个Swagger服务上
注意: 如果你正在研究微服务,那必然少不了服务之间的相互调用,哪么服务之间的接口以及api就必须生成系统的管理文档了.如果你希望更好的管理你的API,你希望有一个工具能一站式地解决API相关的所有事情 ...
- shiro jwt 构建无状态分布式鉴权体系
一:JWT 1.令牌构造 JWT(json web token)是可在网络上传输的用于声明某种主张的令牌(token),以JSON 对象为载体的轻量级开放标准(RFC 7519). 一个JWT令牌的定 ...
- shiro,基于springboot,基于前后端分离,从登录认证到鉴权,从入门到放弃
这个demo是基于springboot项目的. 名词介绍: ShiroShiro 主要分为 安全认证 和 接口授权 两个部分,其中的核心组件为 Subject. SecurityManager. Re ...
- SpringCloud学习系列之七 ----- Zuul路由网关的过滤器和异常处理
前言 在上篇中介绍了SpringCloud Zuul路由网关的基本使用版本,本篇则介绍基于SpringCloud(基于SpringBoot2.x,.SpringCloud Finchley版)中的路由 ...
- 从零开始学YC-Framework之鉴权
一.YC-Framework鉴权是基于哪一个开源框架做的? YC-Framework鉴权主要基于Dromara开源社区组织下的Sa-Token. 1.什么是Sa-Token? Sa-Token是一个轻 ...
随机推荐
- 虚拟机安装配置centos7
安装 https://blog.csdn.net/babyxue/article/details/80970526 主机环境预设 更换国内yum源 epel源 https://www.cnblogs. ...
- P3175-[HAOI2015]按位或【min-max容斥,FWT】
正题 题目链接:https://www.luogu.com.cn/problem/P3175 题目大意 开始有一个\(n\)位二进制数\(s=0\),每次有\(p_i\)概率选取数字\(i\)让\(s ...
- Java——多线程编程学习/01
原文章:http://www.cnblogs.com/QG-whz/p/8351298.html 注:建议去看原博主的文章,单就这个知识点而论,比书本讲的透彻,如有违规,联系必删! 并发环境下进行编 ...
- 4-让线程睡眠的sleep方法
让线程睡眠的sleep方法 Thread类有一个静态的sleep方法,当一个执行中的线程调用了Thread的sleep方法,调用线程就会让出指定时间的执行权,也就是在这期间不参与CPU调度,但是该线程 ...
- Cookie实现是否第一次登陆/显示上次登陆时间
Cookie实现是否第一次登陆/显示上次登陆时间 最近刚好看到Cookie这方面知识,对Servlet部分知识已经生疏,重新翻出已经遗弃角落的<JavaWeb开发实战经典>,重新温习了Co ...
- 自然语言处理标注工具——Brat(安装、测试、使用)
一.Brat标注工具安装 1.安装条件: (1)运行于Linux系统(window系统下虚拟机内linux系统安装也可以) (2)目前brat最新版本(v1.3p1)仅支持python2版本运行使用( ...
- MySQL MHA 运行状态监控
一 项目描述 1.1 背景 MHA(Master HA)是一款开源的 MySQL 的高可用程序,它为 MySQL 主从复制架构提供了 automating master failover 功能.MHA ...
- 试题 历届试题 核桃的数量 java题解
资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 小张是软件项目经理,他带领3个开发组.工期紧,今天都在加班呢.为鼓舞士气,小张打算给每个组发一袋核桃(据传言能补脑).他的要求是: ...
- Sentinel-Go 源码系列(一)|开篇
大家好呀,打算写一个 Go 语言组件源码分析系列,一是为了能学习下 Go 语言,看下别人是怎么写 Go 的,二是也掌握一个组件. 本次选择了 Sentinel-Go,一是对 Java 版本的 Sent ...
- 使用YApi搭建API接口管理工具(docker安装)
使用YApi搭建API接口管理工具(docker安装) 工具描述 YApi 是高效.易用.功能强大的 api 管理平台,旨在为开发.产品.测试人员提供更优雅的接口管理服务.可以帮助开发者轻松创建.发布 ...