Shiro權限控制(五):整合thymeleaf做細粒度的權限校驗

一、前言
在Shiro的官方文檔中,默認介紹的是與JSP整合來做頁面上的權限控制,Shiro有一套自己的標籤庫,能與JSP無縫整合,只需要在JSP頁面上引入Shiro的標籤庫即可

<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

但是越來越多的WEB應用已經慢慢棄用JSP,改成用HTML(因爲HTML比JSP快呀),但是在HTML中,就不能使用Shiro默認的標籤庫,那是否有可替代的標籤庫呢?當然了,thymeleaf就可以在HTML中使用,thymeleaf可以輕鬆自如的自定義標籤並配合權限控制網頁上的組件顯示與否

二、引入thymeleaf
引入thymeleaf,分爲3步
1、在pom.xml文件中引入thymeleaf相關Jar包

    <!-- thymeleaf包 -->
    <dependency>
	    <groupId>com.github.theborakompanioni</groupId>
	    <artifactId>thymeleaf-extras-shiro</artifactId>
	    <version>2.0.0</version>
	</dependency>
	<dependency>
         <groupId>org.thymeleaf</groupId>
         <artifactId>thymeleaf-spring4</artifactId>
         <version>3.0.9.RELEASE</version>
     </dependency>

2、在spring-servlet.xml文件中起用thymeleaf模板引擎

	<!--viewResolver-->
    <bean id="viewResolver" class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
        <property name="order" value="1"/>
        <property name="characterEncoding" value="UTF-8"/>
        <property name="templateEngine" ref="templateEngine"/>
    </bean>
    <!-- templateEngine -->
    <bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
        <property name="templateResolver" ref="templateResolver"/>
        <property name="enableSpringELCompiler" value="true" />
        <property name="additionalDialects">  
		    <set> 
		      <bean class="at.pollux.thymeleaf.shiro.dialect.ShiroDialect"/>  
		    </set>
    	</property>
    </bean>
    <bean id="templateResolver" class="org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver">
        <property name="prefix" value="/html/"/>
        <property name="suffix" value=".html"/>
        <property name="templateMode" value="HTML"/>
        <property name="characterEncoding" value="UTF-8"/>
    </bean>

因爲我使用的是Spring MVC,在web.xml文件中,配置了DispatcherServlet會攔截所有請求,包括靜態資源如html,css,js等,因此需要在spring-servlet.xml文件中指定靜態資源文件路徑,才能訪問到靜態資源

	<!-- 靜態資源 -->
	<mvc:resources location="/WEB-INF/js/" mapping="/js/**"/>
	<mvc:resources location="/WEB-INF/css/" mapping="/css/**"/>
	<mvc:resources location="/WEB-INF/image/" mapping="/image/**"/>
	<mvc:resources location="/html/" mapping="/html/**"/>

3、在html中引入thymeleaf的標籤庫

<html xmlns:th="http://www.thymeleaf.org"
      xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"> 

三、驗證
在測試之前,先介紹幾個重要的標籤
shiro:guest:判斷是否是未登錄,即遊客
shiro:hasRole:判斷是否有xxx角色
shiro:hasPermission:判斷是否有xxx權限
shiro:hasAnyRoles:判斷是否有任何一個指定的權限

1、在/html/user/目錄下新增userManager.html文件,內容如下

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">  
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<p shiro:guest=""><a href="../login.html">遊客訪問,請登錄</a></p>
	
	<p shiro:hasRole="USER"> 有  USER 角色權限</p>
	
	<button shiro:hasPermission="USER:DELETE"  type="button">刪除用戶</button>
	
	<button shiro:hasPermission="USER:CREATE"  type="button">新增用戶</button>
	
	<div shiro:hasAnyRoles="SALES,USER"><li><a href="javascript:;" id="shouhuo">用戶管理</a></li></div>
	
</body>
</html>

2、在UserController中增加對外訪問服務userManager

	@RequestMapping(value="/userManager",method = RequestMethod.GET)
	public String userManager() {
		return "user/userManager";
	}

3、在自定義的UserShiroRealm的doGetAuthorizationInfo方法中,配置用戶有USER角色及USER:DELETE權限

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		String username = (String)principals.getPrimaryPrincipal();
		if(username == null) {
			throw new BugException("未登錄");
		}
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		Set<String> roles = new HashSet<String>();
		Set<String> stringPermissions = new HashSet<String>();
		roles.add("USER");
		stringPermissions.add("USER:DELETE");//角色:刪除權限
		info.setRoles(roles);
		info.setStringPermissions(stringPermissions);
		
		return info;
	}

未登錄,直接訪問http://localhost:8080/bug.web/user/userManager,頁面顯示遊客訪問,請登錄
在這裏插入圖片描述
登錄後再次訪問http://localhost:8080/bug.web/user/userManager,頁面顯示如下
在這裏插入圖片描述
shiro:hasRole:因爲用USER角色,所以“有 USER 角色權限”顯示了

shiro:hasPermission:
因爲沒有USER:CREATE權限,所以“新增用戶”按鈕未顯示
因爲有USER:DELETE權限,所以“刪除用戶”按鈕顯示

shiro:hasAnyRoles:雖然沒有SALES角色,但是有USER角色,所以“用戶管理”顯示

從以上結果可看出,通過與thymeleaf的整合,在HTML頁面上也可以做細粒度的權限控制,可以很方便我們按鈕哪些按鈕需要顯示,哪些按鈕不顯示

四、問題
上面我是訪問Controller層,Spring自動找到需要渲染的html頁面返回給用戶,但是在大部分項目中,是先訪問HTML,然後通過ajax方式請求後臺獲得數據渲染到頁面上,問題來了,通過先訪問HTML的方式,在HTML中配置的shiro標籤就不生效了,暫時未找到好的方法解決,如果你有好的解決方案,歡迎留言討論,謝謝!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章