1. 程式人生 > >shiro安全框架擴充套件教程--如何擴充套件非同步(ajax)請求認證失敗處理

shiro安全框架擴充套件教程--如何擴充套件非同步(ajax)請求認證失敗處理

        上一個章節我們學習瞭如何自定義自己的filter,這個只是為了這一章打基礎;相信我們這一群shiro使用者比較關注非同步請求認證失敗會如何處理這個問題,確實我們現在的專案很大一部分請求都是非同步的,所以這個問題是無可避免,我看了網上很多資料都是沒有完整地給出擴充套件方案,下面我把自己的處理方案給展示下,如有不爽,請勿跨省,家無水錶,不收快遞...

直接進入主題,先看看我們之前的配置,自定義一個RoleAuthorizationFilter

<!-- 過濾鏈配置 -->
	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<property name="securityManager" ref="securityManager" />
		<property name="loginUrl" value="/" />
		<property name="successUrl" value="/cms/index.do" />
		<property name="unauthorizedUrl" value="/" />
		<property name="filters">
			<map>
				<entry key="role">
					<bean
						class="com.silvery.security.shiro.filter.RoleAuthorizationFilter" />
				</entry>
				<entry key="authc">
					<bean
						class="com.silvery.security.shiro.filter.SimpleFormAuthenticationFilter" />
				</entry>
			</map>
		</property>
	</bean>

	<!-- 許可權資源配置 -->
	<bean id="filterChainDefinitionsService"
		class="com.silvery.security.shiro.service.impl.SimpleFilterChainDefinitionsService">
		<property name="definitions">
			<value>
				/static/** = anon
				/admin/user/login.do = anon
				/test/** = role[admin]
				/abc/** = authc
			</value>
		</property>
	</bean>
public class RoleAuthorizationFilter extends AuthorizationFilter {

	public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
			throws IOException {

		Subject subject = getSubject(request, response);
		String[] rolesArray = (String[]) mappedValue;

		if (rolesArray == null || rolesArray.length == 0) {
			// no roles specified, so nothing to check - allow access.
			return true;
		}

		Set<String> roles = CollectionUtils.asSet(rolesArray);
		for (String role : roles) {
			if (subject.hasRole(role)) {
				return true;
			}
		}
		return false;
	}

}

我們先看看這個原始碼,發現是繼承了AuthorizationFilter類,然後只重寫了isAccessAllowed方法,然後我們就想isAccessAllowed是判斷是否擁有許可權,那肯定會有一個方法是認證失敗回撥的方法,這是框架一貫的做法,來驗證下我們的想當然是不是正確的,我們開啟AuthorizationFilter類的原始碼看看

public abstract class AuthorizationFilter extends AccessControlFilter
{

    public AuthorizationFilter()
    {
    }

    public String getUnauthorizedUrl()
    {
        return unauthorizedUrl;
    }

    public void setUnauthorizedUrl(String unauthorizedUrl)
    {
        this.unauthorizedUrl = unauthorizedUrl;
    }

    protected boolean onAccessDenied(ServletRequest request, ServletResponse response)
        throws IOException
    {
        Subject subject = getSubject(request, response);
        if(subject.getPrincipal() == null)
        {
            saveRequestAndRedirectToLogin(request, response);
        } else
        {
            String unauthorizedUrl = getUnauthorizedUrl();
            if(StringUtils.hasText(unauthorizedUrl))
                WebUtils.issueRedirect(request, response, unauthorizedUrl);
            else
                WebUtils.toHttp(response).sendError(401);
        }
        return false;
    }

    private String unauthorizedUrl;
}

看到原始碼的時候我就很開心地賤笑了,果然是我想的那樣,我們很明顯地看到一個方法onAccessDenied,認證失敗處理,邏輯就是如果登入實體為null就儲存請求和跳轉登入頁面,否則就跳轉無許可權配置頁面

我們開始動手改造這個方法,把這個方法也在我們自己的RoleAuthorizationFilter裡重寫下

/**
 * 
 * 1.自定義角色鑑權過濾器(滿足其中一個角色則認證通過) 2.擴充套件非同步請求認證提示功能;
 * 
 * @author shadow
 * 
 */
public class RoleAuthorizationFilter extends AuthorizationFilter {

	protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {

		HttpServletRequest httpRequest = (HttpServletRequest) request;
		HttpServletResponse httpResponse = (HttpServletResponse) response;

		Subject subject = getSubject(request, response);

		if (subject.getPrincipal() == null) {
			if (com.silvery.utils.WebUtils.isAjax(httpRequest)) {
				com.silvery.utils.WebUtils.sendJson(httpResponse, JsonUtils.toJSONString(new ViewResult(false,
						"您尚未登入或登入時間過長,請重新登入!")));
			} else {
				saveRequestAndRedirectToLogin(request, response);
			}
		} else {
			if (com.silvery.utils.WebUtils.isAjax(httpRequest)) {
				com.silvery.utils.WebUtils.sendJson(httpResponse, JsonUtils.toJSONString(new ViewResult(false,
						"您沒有足夠的許可權執行該操作!")));
			} else {
				String unauthorizedUrl = getUnauthorizedUrl();
				if (StringUtils.hasText(unauthorizedUrl)) {
					WebUtils.issueRedirect(request, response, unauthorizedUrl);
				} else {
					WebUtils.toHttp(response).sendError(401);
				}
			}
		}
		return false;
	}

	public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
			throws IOException {

		Subject subject = getSubject(request, response);
		String[] rolesArray = (String[]) mappedValue;

		if (rolesArray == null || rolesArray.length == 0) {
			// no roles specified, so nothing to check - allow access.
			return true;
		}

		Set<String> roles = CollectionUtils.asSet(rolesArray);
		for (String role : roles) {
			if (subject.hasRole(role)) {
				return true;
			}
		}
		return false;
	}

}

其實改造也很簡單,只是再加一層ajax的判斷,至於如何判斷ajax就是自己個人的方式,有的專案喜歡加一個標識引數,有的人喜歡直接用header裡面的X-Requested-With引數,這個看自己的需求咯,我個人喜歡是ajax請求認證失敗是返回一串標準的json格式字串,頁面相容處理也方便

下面我們測試下如何效果,先寫一個html,配置/test/a.do是不夠許可權請求的

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
		<title>test ajax request</title>
	<script type="text/javascript" src="/static/plugin/jquery/core.js"></script>
	<script>
		function test(){
			$.post('/test/a.do','',function(result){
				alert(result);
			});
		}
	</script>
	</head>
<body>
	<input type="button" value="click" onclick="test();" />
</body>
</html>

html寫完,就跑起專案,然後先別登入系統,直接開啟html點選下這個按鈕,發現alert提示{"message":"您尚未登入或登入時間過長,請重新登入!","success":false,"value":null};

然後再登入系統,再點選這個按鈕請求一次看看發現alert提示{"message":"您沒有足夠的許可權執行該操作!","success":false,"value":null};很明顯尚未登入和許可權不足的ajax時候提示都完美地出現,然後這章節我就可以功成身退了

最後總結下擴充套件方案,其實shiro的所有filter都是有統一的介面方法,你們可以看看這真實過濾器都是繼承了相同的父級filter,所以其他的filter也可以通過繼承重寫onAccessDenied方法提供我們的非同步請求分支處理

歡迎拍磚...

相關推薦

shiro安全框架擴充套件教程--如何擴充套件非同步(ajax)請求認證失敗處理

        上一個章節我們學習瞭如何自定義自己的filter,這個只是為了這一章打基礎;相信我們這一群shiro使用者比較關注非同步請求認證失敗會如何處理這個問題,確實我們現在的專案很大一部分請求都是非同步的,所以這個問題是無可避免,我看了網上很多資料都是沒有完整地給出

【原創】基於Spring-SpringMVC-Mybatis 的 Shiro 安全框架使用教程--轉載請註明出處

Shiro使用說明文件 宣告: 我們所使用的框架為SSM框架+Shiro許可權控制框架,在以下部分中,將會描述如何使用一個Shiro框架。 框架使用概述: Shiro安全框架為我們提供了一個較為完善的許可權管理系統。我們將使用該框架提供的使用者登入,登出,使用者許可權

Shiro安全框架第五篇| 使用JdbcRealm進行認證授權

  JdbcRealm 這裡使用JdbcRealm,那麼需要在pom.xml引入mysql驅動以及alibaba資料來源。 1    <!--mysql驅動--> 2    &nbs

shiro安全框架擴充套件教程--整合cas框架擴充套件自定義CasRealm

       這次我給大家講講如何在shiro中整合cas框架,以及擴充套件自定義的角色和資源體系,囉嗦話不多說了,直接上程式碼說明第一步,搭建cas伺服器,我也不說拉,這個大家用現有的cas服務就行了第二步,先加入cas-client的包到我們的專案,然後再下載個shiro

shiro安全框架擴充套件教程--設計資料物件校驗器,如何防止xss以及csrf攻擊

       很多時候我們都知道,xss,csrf都需要通過我們前臺傳入的資料,然後再輸出到頁面,渲染成可執行指令碼,導致載入頁面即可執行或者被動型的讓使用者點選各種常用的按鈕來觸發指令碼效果,所以我們需要嚴格篩選以及控制過濾資料物件的各個屬性欄位值,我相信很多人都用vali

Shiro安全框架簡介以及身份驗證

退出 ica 報錯 資源 帳戶 rac localhost file 手機號 一、Shiro簡介 官網 http://shiro.apache.org/download.html Apache Shiro是一個強大且易用的Java安全框架,執行身份驗證、授權、密碼學和會話

Shiro安全框架之權限認證(授權)

實例 reat trace () onf 而不是 ocs log logout 第一講、權限認證核心要素 權限認證,也就是訪問控制,即在應用中控制誰能訪問哪些資源。 在權限認證中,最核心的三個要素是:權限,角色和用戶; Authorization has three co

shiro安全框架

cto 也會 用戶信息 三個參數 protected 編寫 hash算法 doc cond 應用: 認證 授權 加密 會話管理(單點登錄) 緩存 與web集成 Subject:主體,代表了當前“用戶”,這個用戶不一定是一個具體的人,與當前應用交互的任何東西都是S

Shiro安全框架入門

指定端口 名稱 getc lte zed w3cschool trace aci ali 完整學習網址:https://www.w3cschool.cn/shiro 一、Shiro簡介 1、Shiro的概念 Apache Shiro是一個強大易用的Java安全框架,提供了認

在Spring MVC中使用Apache Shiro安全框架

修改 ctype var format href 文件的 來看 one name 我們在這裏將對一個集成了Spring MVC+Hibernate+Apache Shiro的項目進行了一個簡單說明。這個項目將展示如何在Spring MVC 中使用Apache Shiro來構

簡介Shiro安全框架簡單流程

shiro安全框架流程: 1.Apache Shiro (更輕量, 使用更簡單, 並不完全依賴 spring,可以獨立使用 ),Spring Security (使用複雜, 依賴 Spring) 2.體系結構分為6大類: Authentication 認證 ---- 使用者登入,

shiro安全框架學習筆記

   現在才發現原來安全其實是比較有趣的一個話題。  由於之前已經練過了spring-security的相關內容。所以這裡的shiro只是作為一個知識補充,用作對比學習理解。   由於這個框架相較而言內容比較多一點,所以希望學習的相對詳細一點。&nb

Shiro安全框架第四篇| Shiro自定義Realm進行認證授權

  SHiro自定義Realm 首先在resource下新建user.ini 1[users] 2jiuyue=12345,admin 3[roles] 4admin=user:delete,user:update 然後測試類下新建IniRealmTest測試類,跟前面不

Shiro安全框架第一篇| 什麼是Apache Shiro

什麼是Apache Shiro? Apache  Shiro是一個強大靈活的Java安全框架,提供了認證、授權、會話管理和安全加密等功能,對於任何一個應用程式,Shiro都可以提供全面的安全管理服務、更易於理解的API。並且相對於其他安全框架,Shiro要簡單的多。 Ap

Shiro安全框架第三篇| Shiro認證,授權

  Shiro的認證 接下來是在IDEA進行Shiro的學習,新建一個Springboot工程,除了一些預設的依賴,這裡需要引入apache.shiro安全框架依賴,以及做單元測試的依賴。 1<dependencies> 2   &

Shiro安全框架第二篇|Shiro的整體架構

  Shiro架構 上一節介紹了什麼是Apache Shiro,接下來我們分別從外部和內部來看看Apache Shiro 的架構。 首先,我們從外部來看 Shiro,即從應用程式角度的來觀察如何使用 Shiro 完成工作。如下圖:   可以看到:應用程

SSM整合shiro安全框架(多個realms)

說明: shiro.xml檔案: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi

複習之shiro安全框架(三)——通過jdbcRealm連線資料庫

shiro提供jdbcRealm連線資料庫 這裡要連線資料庫所有要依賴一些jar包 <dependency> <groupId>org.apache.shiro</groupId>

(springboot)shiro安全框架自定義過濾器出現的幾個疑難雜症解決方案

問題一:多次重複重定向問題(匹配多個過濾器鏈重複呼叫其對應過濾器) 問題二:shiro認證時Realm會執行兩次 在使用springboot框架整合shiro安全認證框架時踩了很多坑,每次出問題網上都找不到其中的解決方案,這裡貼兩個我遇到的坑,以及其解決方案給大家,希望大

Shiro安全框架簡介

一 什麼是Shiro Apache是強大靈活的開源安全框架。 提供了認證、授權、企業會話管理、安全加密、快取管理。 二 Shiro與Spring Security對比 三 Shiro整體架構