Shiro 授權(權限)

一、授權(權限)

1.1 什麼是權限

授權,也叫訪問控制,即在應用中控制誰能訪問哪些資源(如訪問頁面/編輯數據/頁面操作等)。

1.2 權限框架

shiro
spring security

Apache Shiro是Java的一個安全框架。目前,使用Apache Shiro的人越來越多,因爲它相當簡單,
對比Spring Security,可能沒有Spring Security做的功能強大,但是在實際工作時可能並不需要那麼
複雜的東西,所以使用小而簡單的Shiro就足夠了。對於它倆到底哪個好,這個不必糾結,能更簡單
的解決項目問題就好了。


二、身份驗證Subject(配置文件版)

2.1 導入依賴

    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-core</artifactId>
        <version>1.2.2</version>
    </dependency>

2.2 shiro.ini

記錄用戶賬戶密碼的配置文件
在shiro中可以配置文件,也可以連接數據庫
其實在shiro中被稱爲Subject:主體
代表了當前 “用戶”,這個用戶不一定是一個具體的人,與當前應用交互的任何東西都是

[users]
zhang=123
wang=123

2.3 權限驗證(登錄)

	//1、獲取SecurityManager工廠,此處使用Ini配置文件初始化SecurityManager
		Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
		SecurityManager manager = factory.getInstance();
		//2、得到SecurityManager實例 並綁定給SecurityUtils   
		SecurityUtils.setSecurityManager(manager);
		Subject subject = SecurityUtils.getSubject();
		 //3、Subject用戶名/密碼身份驗證Token憑證
		UsernamePasswordToken token = new UsernamePasswordToken("zhang","123");
		try {
			subject.login(token);
			
		} catch (UnknownAccountException e) {
			System.out.println("賬號不存在");
			e.printStackTrace();
		} catch (IncorrectCredentialsException e) {
			System.out.println("密碼錯誤");
			e.printStackTrace();
		} catch (AuthenticationException e) {
			System.out.println("其他賬號登錄失敗異常");
			e.printStackTrace();
		}
		System.out.println(subject.isAuthenticated());
	    //6、退出
		subject.logout();
		

tips:

1.SecurityManager權限驗證工廠
2.SecurityManager 一個全局唯一的安全管理器
3.SecurityUtils可以通過這個工具類獲取全局的SecurityManager 
	但是需要我們首先設置一下
4.Subject我們當前登錄的賬號(用戶),通過isAuthenticated方法知道是否登錄了
5.UsernamePasswordToken是登錄的憑證,用戶輸入的賬號密碼放進去,讓subject判斷是否登錄成功
6.login登錄的時候通過異常判斷是哪種登錄失敗
7.如果身份驗證失敗請捕獲 AuthenticationException 或其子類,常見的如: 
DisabledAccountException(禁用的帳號)、LockedAccountException(鎖定的帳號)、UnknownAccountException(錯誤的帳號)、ExcessiveAttemptsException(登錄失敗次數過多)、IncorrectCredentialsException (錯誤的憑證)、ExpiredCredentialsException(過期的憑證)等,
具體請查看其繼承關係;對於頁面的錯誤消息展示,最好使用如 “用戶名 / 密碼錯誤” 而不是 “用戶名錯誤”/“密碼錯誤”,防止一些惡意用戶非法掃描帳號庫;

2.4 身份認證流程

在這裏插入圖片描述

流程如下:

首先調用 Subject.login(token) 進行登錄,其會自動委託給 Security Manager,調用之前必須通過 SecurityUtils.setSecurityManager() 設置;
SecurityManager 負責真正的身份驗證邏輯;它會委託給 Authenticator 進行身份驗證;
Authenticator 纔是真正的身份驗證者,Shiro API 中核心的身份認證入口點,此處可以自定義插入自己的實現;
Authenticator 可能會委託給相應的 AuthenticationStrategy 進行多 Realm 身份驗證,默認 ModularRealmAuthenticator 會調用 AuthenticationStrategy 進行多 Realm 身份驗證;
Authenticator 會把相應的 token 傳入 Realm,從 Realm 獲取身份驗證信息,如果沒有返回 / 拋出異常表示身份驗證失敗了。此處可以配置多個 Realm,將按照相應的順序及策略進行訪問。

三、角色Role\權限Permission

3.1 角色Role

角色代表的是當前賬號所在的身份
比如:在一家公司裏面,每個人都有屬於自己的角色:老闆、主管、財務、人事、工程師、後臺、運維、前臺

而我們認爲可以給賬號分配一個或者多個角色:
比如:項目經理又是主管、又是工程師
財務主管:又是主管、又是工程師
研發只是工程師

3.2 權限Permission

我們根據不同的角色分配不同的權限
比如:
老闆:管理所有員工流動、管理所有員工的工資
主管:管理所在部門員工流動、管理所在部門員工的工資
工程師:公司上班

那麼我們根據每個賬號subject可以獲取不同的角色role,而根據不同的角色獲取不同的權限
最後決定當前登錄的賬號是否有權限進行對應的操作

3.3 ini文件

[users]
#用戶名=密碼,角色1,角色2
zhangSan=123,admin,user
liSi=123,user

[roles]
#角色=權限
admin=*
admin2=*:select
user=video:*,chapter:*
user2=video:select,chapter:select
user3=video:insert,video:update,video:select,video:delete

# 上面角色就有amdin,admin2,user,user2,user3

3.3 Java代碼

		Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:Shiro_privilege.ini");
		SecurityManager manager = factory.getInstance();
		SecurityUtils.setSecurityManager(manager);
		Subject subject = SecurityUtils.getSubject();
		UsernamePasswordToken token = new UsernamePasswordToken("liSi","123");
		try {
			subject.login(token);
		} catch (Exception e) {
			e.printStackTrace();
		}
		boolean b=subject.isAuthenticated();
		System.out.println("是否認證成功"+b);
		//判斷是否有某個角色
		boolean a= subject.hasRole("admin");
		//判斷是否有某些角色
		List<String> roles = new ArrayList<String>();
		roles.add("admin");
		roles.add("user");
		System.out.println("admin和user角色:"+subject.hasAllRoles(roles));
		//判斷是否有權限
		boolean b=subject.isPermitted("user:insert");
		//檢查是否有權限,沒有的話會報異常
		subject.checkPermission("video:insert");

四、Realm域

4.1 什麼是Realm

域,Shiro 從從 Realm 獲取安全數據(如用戶、角色、權限),就是說 SecurityManager 要驗證用戶身份,
那麼它需要從 Realm 獲取相應的用戶進行比較以確定用戶身份是否合法;
也需要從 Realm 得到用戶相應的角色 / 權限進行驗證用戶是否能進行操作;
可以把 Realm 看成 DataSource,即安全數據源。


也就是說對於我們而言,最簡單的一個 Shiro 應用:

應用代碼通過 Subject 來進行認證和授權,而 Subject 又委託給 SecurityManager;

我們需要給 Shiro 的 SecurityManager 注入 Realm,從而讓 SecurityManager 能得到合法的用戶及其權限進行判斷。
從以上也可以看出,Shiro 不提供維護用戶 / 權限,而是通過 Realm 讓開發人員自己注入。


Realm個人其實理解爲就是來判斷當前的subject用戶是登錄成功、失敗的一個東西

4.2 MyRealm 自定義Realm

前面我們寫的一個代碼中,我們把subject用戶的,賬號密碼通過token傳遞過去,
執行login方法就得到結果,當時的Realm就是shiro自己寫的
這次就是我們自己寫自定義的Realm域
package com.zhiyou100.realm;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.realm.Realm;

public class MyRealm implements Realm{
//判斷登錄的方法
	public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		String username = (String) token.getPrincipal();
		String password = new String((char[])token.getCredentials());
		if (!"zhang1".equals(username)) {
			throw new UnknownAccountException();
		}
		if (!"123".equals(password)) {
			  throw new IncorrectCredentialsException(); //如果密碼錯誤
		}
		
		return new SimpleAuthenticationInfo(username,password,getName());
	}
//得到當前的realm名稱
	public String getName() {
		// TODO Auto-generated method stub
		return "user";
	}
//支持哪種登錄方式
	public boolean supports(AuthenticationToken token) {
		// TODO Auto-generated method stub
		return token instanceof UsernamePasswordToken;
	}

}

4.3 shiro.ini

告訴

myRealm1=com.zhiyou100.realm.MyRealm
securityManager.realms=$myRealm1

4.4 Realm的繼承關係

在這裏插入圖片描述

1)在這個圖片中我們可以看見‘I’代表的是接口,‘c’代表的抽象類和普通類
2)Realm是最上層的接口,所有的東西都需要我們自己實現
3)IniRealm是我們之前沒有自定義realm使用的
4)JdbcRealm是鏈接數據庫使用的,但是因爲屬於shiro自己寫的,所以他對數據庫表的格式要求有規範的
5)所以我們更多的使用的是AuthorizingRealm

4.5 權限驗證(登錄)

同2.3一樣

五、自定義域Realm和 權限Permission

5.1 shiro.ini

myRealm1=com.zhiyou100.realm.MyRealm
securityManager.realms=$myRealm1

5.2 MyRealm

package com.zhiyou100.realm;

import java.util.HashSet;
import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.subject.PrincipalCollection;

public class MyRealm extends AuthorizingRealm {
	//權限\角色返回
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
		String username = (String) arg0.getPrimaryPrincipal();
		SimpleAuthorizationInfo  info = new SimpleAuthorizationInfo ();
		if (username.equals("zhangSan")) {
			Set<String> roles = new HashSet();
			roles.add("admin");
			roles.add("user");
			info.setRoles(roles);
		
			Set<String> permissions = new HashSet<String>();
			permissions.add("video:select");
			permissions.add("video:insert");
			permissions.add("video:delete");
			permissions.add("video:update");
			info.setStringPermissions(permissions);
			
		}else if (username.equals("liSi")) {
			info.addRole("user");
			info.addStringPermission("video:select");
		}
		return info;
	}
	//登錄判斷
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
		
		
		return new SimpleAuthenticationInfo(arg0.getPrincipal(),arg0.getCredentials(),"myrealm");
	}


}

5.3 使用

		Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
		SecurityManager manager = factory.getInstance();
		// 2、得到SecurityManager實例 並綁定給SecurityUtils
		SecurityUtils.setSecurityManager(manager);
		Subject subject = SecurityUtils.getSubject();
		// 3、Subject用戶名/密碼身份驗證Token憑證
		UsernamePasswordToken token = new UsernamePasswordToken("zhangSan", "123");
		try {
			subject.login(token);

		} catch (UnknownAccountException e) {
			System.out.println("賬號不存在");
			e.printStackTrace();
		} catch (IncorrectCredentialsException e) {
			System.out.println("密碼錯誤");
			e.printStackTrace();
		} catch (AuthenticationException e) {
			System.out.println("其他賬號登錄失敗異常");
			e.printStackTrace();
		}
		System.out.println("登錄:"+subject.isAuthenticated());
		
		System.out.println("admin:"+subject.hasRole("admin"));
		System.out.println("user:"+subject.hasRole("user"));
		System.out.println("user:select:"+subject.isPermitted("user:insert"));
		// 6、退出
		subject.logout();

六、鏈接數據庫

6.1 JdbcRealm

在這裏我們因爲使用的是系統定義好的JdbcRealm,所以表的內容都規定好了必須這麼使用

/*
Navicat MySQL Data Transfer

Source Server         : localhost_3306
Source Server Version : 50535
Source Host           : localhost:3306
Source Database       : shiro

Target Server Type    : MYSQL
Target Server Version : 50535
File Encoding         : 65001

Date: 2020-01-09 09:23:29
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `roles_permissions`
-- ----------------------------
DROP TABLE IF EXISTS `roles_permissions`;
CREATE TABLE `roles_permissions` (
  `id` int(11) NOT NULL DEFAULT '0',
  `role_name` varchar(20) DEFAULT NULL,
  `permission` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of roles_permissions
-- ----------------------------
INSERT INTO `roles_permissions` VALUES ('1', 'system', 'system');

-- ----------------------------
-- Table structure for `users`
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(20) DEFAULT NULL,
  `password` varchar(20) DEFAULT NULL,
  `password_salt` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of users
-- ----------------------------
INSERT INTO `users` VALUES ('1', 'admin', '123', null);

-- ----------------------------
-- Table structure for `user_roles`
-- ----------------------------
DROP TABLE IF EXISTS `user_roles`;
CREATE TABLE `user_roles` (
  `id` int(11) NOT NULL DEFAULT '0',
  `username` varchar(20) DEFAULT NULL,
  `role_name` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user_roles
-- ----------------------------
INSERT INTO `user_roles` VALUES ('1', 'admin', 'system');

6.2 pom.xml

		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-all</artifactId>
			<version>1.2.2</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.26</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>5.1.6.RELEASE</version>
		</dependency>

6.3 ini

myRealm1=org.apache.shiro.realm.jdbc.JdbcRealm

dataSource1=org.springframework.jdbc.datasource.DriverManagerDataSource
dataSource1.driverClassName=com.mysql.jdbc.Driver
dataSource1.url=jdbc:mysql://localhost:3306/shiro
dataSource1.username=root
dataSource1.password=123
myRealm1.dataSource=$dataSource1
# 解決權限不開啓的問題
myRealm1.permissionsLookupEnabled=true

securityManager.realms=$myRealm1

6.4 Java

	Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
		SecurityManager manager = factory.getInstance();
		SecurityUtils.setSecurityManager(manager);
		Subject subject = SecurityUtils.getSubject();
		AuthenticationToken token = new UsernamePasswordToken("admin","123");
		try {
			subject.login(token);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		System.out.println("是否登錄:"+subject.isAuthenticated());
		System.out.println("是否擁有角色admin:"+subject.hasRole("system"));
//		System.out.println("是否擁有角色user:"+subject.hasRole("user"));
		System.out.println("是否擁有權限select:"+subject.isPermitted("video"));
		
		
		
		subject.logout();
		

七、Shiro Web 集成

7.1 與 Web 集成


Shiro 提供了與 Web 集成的支持,其通過一個 ShiroFilter 入口來攔截需要安全控制的 URL,然後進行相應的控制,
ShiroFilter 類似於如 Strut2/SpringMVC 這種 web 框架的前端控制器,其是安全控制的入口點,
其負責讀取配置(如 ini 配置文件),然後判斷 URL 是否需要登錄 / 權限等工作。

7.2 pom.xml

		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper</artifactId>
			<version>5.1.8</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-all</artifactId>
			<version>1.2.2</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring-version}</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring-version}</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring-version}</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.26</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.4.5</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>2.0.1</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.4</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.3.1</version>
		</dependency>

7.3 springmvc.xml

	<bean id="myRealm" class="com.zhiyou100.realm.UserRealm"></bean>
	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<property name="realm" ref="myRealm"></property>
	</bean>


	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<property name="securityManager" ref="securityManager"></property>
		<!-- 跳轉到登錄頁面 -->
		<property name="loginUrl" value="/login.jsp"></property>
		<!-- 成功頁面 -->
		<property name="successUrl" value="/index.jsp"></property>
		<!-- 權限不足的錯誤提示頁面 -->
		<property name="unauthorizedUrl" value="/error.jsp"></property>
		<!-- 是所有的請求都要經過登錄過濾器,如果沒有登錄就會跳 轉到登錄界面,所以靜態資源同樣會被攔截 anon過濾器處理原則 :隨便訪問 authc需要進行權限認證 -->
		<property name="filterChainDefinitions">
			<value>
				/css/** = anon
				/images/** = anon
				/js/** = anon
				/lib/** = anon
				/login.jsp = anon
				/index.jsp = anon
				/error.jsp = anon
				/user/login.do = anon
				/** = authc
			</value>
		</property>

	</bean>
	
	 <!-- 開啓shiro自動代理 -->
 	<bean name="defaultAdvisorAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
		 <!-- 指定強制使用cglib爲action創建代理對象 -->
		<property name="proxyTargetClass" value="true"></property>
	</bean>
	<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"></bean>
 

7.4 web.xml

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:spring/*.xml</param-value>
	</context-param>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<servlet>
		<servlet-name>springmvc</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring/*.xml</param-value>
		</init-param>
		<load-on-startup>2</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>springmvc</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>
	<filter>
		<filter-name>characterEncodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>characterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>


	<filter>
		<filter-name>shiroFilter</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
		
	</filter>
	<filter-mapping>
		<filter-name>shiroFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

7.5 UserRealm


public class UserRealm extends AuthorizingRealm{
	
	
	
	
	@Resource
	private UserService userService;
	//獲取用戶的角色和權限
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection collection) {
		User user = (User) collection.getPrimaryPrincipal();
		SimpleAuthorizationInfo  info = new SimpleAuthorizationInfo ();
		user = userService.findByAccout(user.getAccount());
		for(Role role : user.getRoles()){
			info.addRole(role.getName());
		}
		System.out.println(user);
		for(Permission permission : user.getPermissions()){
			info.addStringPermission(permission.getName());
		}
		return info;
	}
	//判斷賬號密碼是否正確
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		String account = (String) token.getPrincipal();
		String password = new String((char[])token.getCredentials());
		System.out.println(token.getCredentials());
		
		User user = userService.findByAccout(account);
		System.out.println("myrealm:"+password);
		if (user == null) {
			throw new UnknownAccountException("賬號不存在");
		}
		
		if (!password.equals(user.getPassword())) {
			throw new IncorrectCredentialsException("密碼錯誤");			
		}
		return new SimpleAuthenticationInfo(user, password,getName());
	}

}

7.6 jsp

# 導入標籤
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags"%>

# 判斷是否有角色
<shiro:hasRole name="管理員">
</shiro:hasRole>
# 判斷是否有權限
<shiro:hasPermission name="user:select">
</shiro:hasPermission>
# 獲取當前登錄的賬號,account代表調用account屬性
<shiro:principal property="account" />


(1)@RequiresAuthentication :表示當前Subject已經通過login 進行了身份驗證;即Subject. isAuthenticated()返回true
(2)@RequiresUse:表示當前Subject已經身份驗證或者通過記住我登錄的
(3)@RequiresGuest :表示當前Subject沒有身份驗證或通過記住我登錄過,即是遊客身份
(4)@RequiresRoles(value={“admin”, “user”}, logical= Logical.AND)
(5)@RequiresPermissions (value={“user:a”, “user:b”}, logical= Logical.OR) :表示當前Subject需要權限user:a或user:b

7.7 Controller

@RequiresPermissions("user:delete")
@RequiresRoles("管理員")

7.8 sql


-- ----------------------------
-- Table structure for `permission`
-- ----------------------------
DROP TABLE IF EXISTS `permission`;
CREATE TABLE `permission` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of permission
-- ----------------------------
INSERT INTO `permission` VALUES ('1', 'user:select');
INSERT INTO `permission` VALUES ('2', 'user:insert');
INSERT INTO `permission` VALUES ('3', 'user:update');
INSERT INTO `permission` VALUES ('4', 'user:delete');
INSERT INTO `permission` VALUES ('5', '*');
INSERT INTO `permission` VALUES ('6', 'role:select');
INSERT INTO `permission` VALUES ('7', 'role:insert');
INSERT INTO `permission` VALUES ('8', 'role:update');
INSERT INTO `permission` VALUES ('9', 'role:delete');
INSERT INTO `permission` VALUES ('10', 'user:*');
INSERT INTO `permission` VALUES ('11', 'role:*');
INSERT INTO `permission` VALUES ('12', '*:select');

-- ----------------------------
-- Table structure for `role`
-- ----------------------------
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of role
-- ----------------------------
INSERT INTO `role` VALUES ('3', '普通用戶');
INSERT INTO `role` VALUES ('5', '王五');
INSERT INTO `role` VALUES ('2', '管理員');
INSERT INTO `role` VALUES ('1', '超級管理員');
INSERT INTO `role` VALUES ('4', '運維');

-- ----------------------------
-- Table structure for `role_permission`
-- ----------------------------
DROP TABLE IF EXISTS `role_permission`;
CREATE TABLE `role_permission` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `role_id` int(11) NOT NULL,
  `permission_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `role_id` (`role_id`),
  KEY `permission_id` (`permission_id`),
  CONSTRAINT `role_permission_ibfk_1` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`),
  CONSTRAINT `role_permission_ibfk_2` FOREIGN KEY (`permission_id`) REFERENCES `permission` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of role_permission
-- ----------------------------
INSERT INTO `role_permission` VALUES ('14', '1', '5');
INSERT INTO `role_permission` VALUES ('17', '4', '12');

-- ----------------------------
-- Table structure for `user`
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `account` varchar(20) NOT NULL,
  `password` varchar(200) NOT NULL,
  `review_num` int(11) NOT NULL,
  `head` varchar(250) DEFAULT NULL,
  `qq` int(11) DEFAULT NULL,
  `email` varchar(50) DEFAULT NULL,
  `phone` mediumtext,
  `login_time` varchar(20) DEFAULT NULL,
  `ip` varchar(20) NOT NULL,
  `status` int(11) NOT NULL,
  `index` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `account` (`account`)
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('4', 'admin1', '123', '0', null, null, null, null, null, '0.0.0.0', '0', '4');
INSERT INTO `user` VALUES ('5', 'q4', '123', '0', null, null, null, null, null, '0.0.0.0', '0', '5');
INSERT INTO `user` VALUES ('6', 'q5', '123', '0', null, null, null, null, null, '0.0.0.0', '0', '6');
INSERT INTO `user` VALUES ('7', 'q6', '123', '0', null, null, null, null, null, '0.0.0.0', '0', '7');
INSERT INTO `user` VALUES ('8', 'q7', '123', '0', null, null, null, null, null, '0.0.0.0', '0', '8');

-- ----------------------------
-- Table structure for `user_role`
-- ----------------------------
DROP TABLE IF EXISTS `user_role`;
CREATE TABLE `user_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `role_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `user_id` (`user_id`),
  KEY `role_id` (`role_id`),
  CONSTRAINT `user_role_ibfk_2` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user_role
-- ----------------------------
INSERT INTO `user_role` VALUES ('10', '1', '1');
INSERT INTO `user_role` VALUES ('12', '6', '3');
INSERT INTO `user_role` VALUES ('13', '8', '3');
INSERT INTO `user_role` VALUES ('14', '9', '3');
INSERT INTO `user_role` VALUES ('15', '10', '3');
INSERT INTO `user_role` VALUES ('16', '11', '3');
INSERT INTO `user_role` VALUES ('17', '12', '3');
INSERT INTO `user_role` VALUES ('18', '13', '3');
INSERT INTO `user_role` VALUES ('19', '14', '3');
INSERT INTO `user_role` VALUES ('20', '3', '1');
INSERT INTO `user_role` VALUES ('22', '2', '1');
INSERT INTO `user_role` VALUES ('23', '4', '4');

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