Shiro多專案許可權集中管理平臺
專案起源:
公司隨著業務的增長,各業務進行水平擴充套件面臨拆分;隨著業務的拆分各種管理系統撲面而來,為了方便許可權統一管理,不得不自己開發或使用分散式許可權管理(Spring Security)。Spring Security依賴Spring和初級開發人員學習難度大,中小型公司不推薦使用;Apache Shiro是一個強大易用的安全框架,Shiro的API方便理解。經過網上各路大神對shiro與spring security的比較,最終決定使用shiro開發一個獨立的許可權管理平臺。
該專案是在張開濤跟我學shiro Demo基礎上進行開發、功能完善和管理頁面優化,已上傳GitHub歡迎fork、start及提出改進意見。
公用模組:shiro-distributed-platform-core
自定義註解-CurrentUser
通過註解獲取當前登入使用者
請求攔截器-SysUserFilter
攔截所有請求
1.通過shiro Subject 獲取當前使用者的使用者名稱
2.通過使用者名稱獲取使用者資訊
3.將使用者資訊儲存ServletRequest物件中
程式碼示例:
/**
*
* @ClassName: SysUserFilter
* @Description: 請求攔截器
* @author yangzhao
* @date 2017年12月20日 下午2:10:23
*
*/
public class SysUserFilter extends PathMatchingFilter {
@Autowired
private UserService userService;
@Override
protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
String username = (String)SecurityUtils.getSubject().getPrincipal();
User user = userService.findByUsername(username);
request.setAttribute(Constant.CURRENT_USER,user);
return true;
}
}
Spring方法攔截器引數繫結-CurrentUserMethodArgumentResolver
通過SpringAOP攔截容器內所有Java方法引數是否有CurrentUser註解,若果有註解標識從NativeWebRequest中獲取user資訊進行引數繫結
程式碼示例:
/**
*
* @ClassName: CurrentUserMethodArgumentResolver
* @Description: Spring方法攔截器引數繫結
* @author yangzhao
* @date 2017年12月20日 下午2:07:55
*
*/
public class CurrentUserMethodArgumentResolver implements HandlerMethodArgumentResolver {
public CurrentUserMethodArgumentResolver() {
}
@Override
public boolean supportsParameter(MethodParameter parameter) {
if (parameter.hasParameterAnnotation(CurrentUser.class)) {
return true;
}
return false;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
CurrentUser currentUserAnnotation = parameter.getParameterAnnotation(CurrentUser.class);
return webRequest.getAttribute(currentUserAnnotation.value(), NativeWebRequest.SCOPE_REQUEST);
}
}
認證攔截器-ServerFormAuthenticationFilter
shiro許可權認證通過後進行頁面跳轉
程式碼示例:
/**
*
* @ClassName: ServerFormAuthenticationFilter
* @Description: 認證攔截器-頁面跳轉
* @author yangzhao
* @date 2017年12月20日 下午2:10:18
*
*/
public class ServerFormAuthenticationFilter extends FormAuthenticationFilter {
@Override
protected void issueSuccessRedirect(ServletRequest request, ServletResponse response) throws Exception {
String fallbackUrl = (String) getSubject(request, response)
.getSession().getAttribute("authc.fallbackUrl");
if(StringUtils.isEmpty(fallbackUrl)) {
fallbackUrl = getSuccessUrl();
}
WebUtils.redirectToSavedRequest(request, response, fallbackUrl);
}
公用介面:shiro-distributed-platform-api
許可權系統核心API
AppService-應用API
AreaService-區域API
OrganizationService-組織結構API
ResourceService-資源API
RoleService-角色API
UserService-使用者API
客戶端:shiro-distributed-platform-client
客戶端認證攔截-ClientAuthenticationFilter
1.判斷是否認證通過 若未認證進入下一步
2.從ServletRequest獲取回撥url
3.獲取預設回撥url(客戶端IP和埠)
4.將預設回撥url儲存到session中
5.將第2步中的回撥url儲存到ClientSavedRequest中(方便server回撥時返回到當前請求url)
5.當前請求重定向到server端登入頁面
程式碼示例:
/**
*
* @ClassName: AppService
* @Description: 客戶端認證攔截
* @author yangzhao
* @date 2017年12月20日 下午2:03:43
*
*/
public class ClientAuthenticationFilter extends AuthenticationFilter {
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
Subject subject = getSubject(request, response);
return subject.isAuthenticated();
}
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
String backUrl = request.getParameter("backUrl");
saveRequest(request, backUrl, getDefaultBackUrl(WebUtils.toHttp(request)));
redirectToLogin(request, response);
return false;
}
protected void saveRequest(ServletRequest request, String backUrl, String fallbackUrl) {
Subject subject = SecurityUtils.getSubject();
Session session = subject.getSession();
HttpServletRequest httpRequest = WebUtils.toHttp(request);
session.setAttribute("authc.fallbackUrl", fallbackUrl);
SavedRequest savedRequest = new ClientSavedRequest(httpRequest, backUrl);
session.setAttribute(WebUtils.SAVED_REQUEST_KEY, savedRequest);
}
private String getDefaultBackUrl(HttpServletRequest request) {
String scheme = request.getScheme();
String domain = request.getServerName();
int port = request.getServerPort();
String contextPath = request.getContextPath();
StringBuilder backUrl = new StringBuilder(scheme);
backUrl.append("://");
backUrl.append(domain);
if("http".equalsIgnoreCase(scheme) && port != 80) {
backUrl.append(":").append(String.valueOf(port));
} else if("https".equalsIgnoreCase(scheme) && port != 443) {
backUrl.append(":").append(String.valueOf(port));
}
backUrl.append(contextPath);
backUrl.append(getSuccessUrl());
return backUrl.toString();
}
}
ClientRealm
ClientRealm繼承自Shiro AuthorizingRealm
該類忽略doGetAuthenticationInfo方法實現,所有認證操作會轉到Server端實現
程式碼示例:
/**
*
* @ClassName: ClientRealm
* @Description: 客戶端shiro Realm
* @author yangzhao
* @date 2017年12月20日 下午2:03:43
*
*/
public class ClientRealm extends AuthorizingRealm {
private RemoteService remoteService;
private String appKey;
public void setRemoteService(RemoteService remoteService) {
this.remoteService = remoteService;
}
public void setAppKey(String appKey) {
this.appKey = appKey;
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = (String) principals.getPrimaryPrincipal();
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
PermissionContext context = remoteService.getPermissions(appKey, username);
authorizationInfo.setRoles(context.getRoles());
authorizationInfo.setStringPermissions(context.getPermissions());
return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//永遠不會被呼叫
throw new UnsupportedOperationException("永遠不會被呼叫");
}
}
客戶端Session管理-ClientSessionDAO
客戶端與服務端Session同步
客戶端shiro攔截器工廠管理類-ClientShiroFilterFactoryBean
新增兩個方法setFiltersStr、setFilterChainDefinitionsStr,方便在properties檔案中配置攔截器和定義過濾鏈
程式碼示例:
/**
*
* @ClassName: ClientShiroFilterFactoryBean
* @Description: 新增兩個方法setFiltersStr、setFilterChainDefinitionsStr,方便在properties檔案中配置攔截器和定義過濾鏈
* @author yangzhao
* @date 2017年12月20日 下午2:03:43
*
*/
public class ClientShiroFilterFactoryBean extends ShiroFilterFactoryBean implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
public void setFiltersStr(String filters) {
if(StringUtils.isEmpty(filters)) {
return;
}
String[] filterArray = filters.split(";");
for(String filter : filterArray) {
String[] o = filter.split("=");
getFilters().put(o[0], (Filter)applicationContext.getBean(o[1]));
}
}
public void setFilterChainDefinitionsStr(String filterChainDefinitions) {
if(StringUtils.isEmpty(filterChainDefinitions)) {
return;
}
String[] chainDefinitionsArray = filterChainDefinitions.split(";");
for(String filter : chainDefinitionsArray) {
String[] o = filter.split("=");
getFilterChainDefinitionMap().put(o[0], o[1]);
}
}
}
服務端:shiro-distributed-platform-server
介面暴露
通過Spring HttpInvokerServiceExporter工具將shiro-distributed-platform-api模組部分API暴露(remoteService、userService、resourceService),請參考spring-mvc-export-service.xml配置檔案
配置ShiroFilterFactoryBean filterChainDefinitions屬性將以上三個介面許可權設定為遊客、匿名(anon),請參考spring-config-shiro.xml配置檔案
以上屬於原創文章,轉載請註明作者@怪咖
QQ:208275451
Email:[email protected]
相關推薦
Shiro多專案許可權集中管理平臺
專案起源: 公司隨著業務的增長,各業務進行水平擴充套件面臨拆分;隨著業務的拆分各種管理系統撲面而來,為了方便許可權統一管理,不得不自己開發或使用分散式許可權管理(Spring Security)。Spring Security依賴Spring和初級開發人員學習
Linux企業生產環境使用者許可權集中管理專案方案案例
企業生產環境使用者許可權集中管理專案方案案例: 1 問題現狀 當前我們公司裡伺服器上百臺,各個伺服器上的管理人員很多(開發+運維+架構+DBA+產品+市場),在大家登入使用Linux伺服器時,不同職能的員工水平不同,因此導致操作很不規範
ansible:集中管理平臺
mysql comm 服務 表示 regex defaults sel let ask 無服務、無agent、采用ssh管理遠程主機、多線程1、配置文件/etc/ansible/ansible.cfg2、管理方式(1)ad-hoc 臨時命令(2)playbook劇本 遠程管
svn對專案許可權進行管理
昨日一篇有關svn的文章,對Repository理解有偏差,今天重新整理髮表。一 建立Repositories每一個Repositorty是一個倉庫,這個倉庫裡可以放入多個專案。可以對每個專案分別管理,也可以對整個倉庫管理。二 建立Users 三 建立Group 四 分配許可權
使用svn對專案許可權進行管理
一 建立Repositories 每一個Repositorty是一個倉庫,這個倉庫裡可以放入多個專案。可以對每個專案分別管理,也可以對整個倉庫管理。 二 建立Users 三 建立Group 四 分配許可權(對於倉庫) 我們可以對整個Repo
手把手教你用SonarQube+Jenkins搭建--前端專案--程式碼質量管理平臺 (Window系統)
前言 網上教程大多介紹的是Linux系統下SonarQube+Jenkins如何使用,這是因為這兩款軟體一般都是部署在伺服器上,而大多數伺服器,採用的都是Linux系統。大多數伺服器用Linux的原因是: Linux伺服器上的許多軟體都是免費的,Window伺服器的軟體大多是付費的 基於Linux伺服器的解
多專案集中許可權管理系統 採用cas +shiro+spring mvc+mbatis+bootstrap單點登入
流程架構圖: 這裡許可權系統也可以理解為cas client專案 系統效果圖: 業務場景:多專案統一認證登入,許可權統一管理,許可權系統管理使用者資料,其他業務系統只維護業務資料,使用者資料一律來自許可權系統 該功能目前經過半個多月的努力 在巨大壓力下終於完成了! 目前國內
Shiro 第二十三章 多專案集中許可權管理及分散式會話
在做一些企業內部專案時或一些網際網路後臺時;可能會涉及到集中許可權管理,統一進行多專案的許可權管理;另外也需要統一的會話管理,即實現單點身份認證和授權控制。學習本章之前,請務必先學習《第十章 會話管理》和《第十六章 綜合例項》,本章程式碼都是基於這兩章的程式碼基礎上完成的。本
spring+shiro+jasig-cas+cxf 單點登入多點登出簡單統一許可權管理平臺一
本文簡單實現在spring框架下對apache shiro與jasig-cas 整合 實現單點登入多點登出統一許可權管理平臺,功能簡單,主要大致講講入門配置。 一、環境: 1、後臺框架:spring3.2+struts2+hibernate4+apache-shiro1
Docker集中化web界面管理平臺-Shipyard部署記錄
安裝docker 順序 ice osi 大致 打開 epo aliyun ges 之前介紹了DOcker的web管理工具DockerUI,下面介紹下Docker的另一個web界面管理工具Shipyard的使用。Shipyard(github)是建立在docker集群管理工具
4、python自動化運維——集中化管理平臺Saltstack
python Saltstack linux 自動化運維; 集中化管理平臺——Saltstack Saltstck作為服務器基礎架構集中化管理平臺,具備配置管理,遠程執行,監控等功能。可以簡單地理解為簡化版的puppet,加強版的func。廢話不多說,直接上手。 Saltstack安裝以及配置
5、python自動化運維——集中化管理平臺Ansible
python Linux Ansible 自動化運維 集中化管理平臺Ansible 簡介:Ansible是一種集成IT系統的配置管理、應用部署、執行特定任務的開源平臺特點:1、部署簡單,只需在主控端部署Ansible環境,被控端不用進行任何操作2、默認使用SSH協議對設備進行管理3、主從集中化
stf-多設備管理平臺搭建
rap png 完成 pen tar 環境 public 需要 body 項目地址: https://github.com/openstf/stf 安裝、使用命令 # 安裝stfbrew install rethinkdb graphicsmagick zeromq pr
快速搭建ELK集中化日誌管理平臺
command uri tun sock one cau else inf span 由於我們的項目是分布式,服務分布於多個服務器上,每次查看日誌都要登錄不同服務器查看,而且查看起來還比較麻煩,老大讓搭一個集中化日誌管理的東西,然後就在網上找到了這個東西ELK E
集中化管理平臺saltstack--原理及安裝
斷開連接 master ons 需要 安裝salt groups 客戶端 grep -v 主機 SaltStack原理: Saltstack由master和minion構成,master是服務器端,表示一臺服務器;minion是客戶端,表示有多臺服務器。在master上發
集中化管理平臺Ansible詳解(一)
test cfengine key 構建 ron 接口 gid linux平臺 文檔 什麽是ansible? ansible是一種集成IT系統的配置管理、應用部署、執行特定任務的開源平臺.它是基於python語言,由Paramiko和PyYAML兩個關鍵模塊構建。集合了眾多
maven管理平臺專案結構分析
後臺管理平臺專案結構: 1 JAX-WS Web Service(不用,是maven自動生成的) 2 java Resources(最常用,也是maven自動生成的,不是手動建立的) 3 JavaScript Resources(不用,是maven自動生成的,不是手動建立的) 4 Deployed
小型專案SSM+Maven實戰講解:APP資訊管理平臺-developer版
APP管理平臺是一個小型專案,是一個CMS系統,最主要的就是對於SSM(Spring、SpringMVC、Mybatis)框架的整合和Maven的理解,以及GIT託管平臺的使用,另外和有一個BootStrap的使用,在這裡做寫這個心得主要是因為自身對於SSM框架的不熟練,以此來檢驗自己的大腦和開拓自
大資料專案實戰之 --- 某App管理平臺的手機app日誌分析系統(三)
一、建立hive分割槽表 ---------------------------------------------------- 1.建立資料庫 $hive> create database applogsdb; 2.建立分割槽表 編寫指令碼。
docker集中化管理平臺--shipyard部署
均衡 特點 -- 方案 ont ack 集群管理 mage 管理工具 Shipyard是建立在docker集群管理工具Citadel之上的可以管理容器、主機等資源的web圖形化工具,包括core和extension兩個版本,core即shipyard主要是把多個 host上