基於BOS系統的Shiro許可權框架基本使用
阿新 • • 發佈:2018-12-18
目錄
1.Shiro框架的基本概念
Shiro框架的核心功能有4個,即認證、授權、會話管理、加密,shiro基本使用這一方面我們主要討論認證與授權兩個基本用法。認證,顧名思義,即登陸時期資料庫使用者物件與表單的使用者物件比對,若對比成功,則登陸成功。授權,即登陸之後當前該使用者能訪問哪些請求,不能訪問哪些請求,這些請求也是從資料庫中查詢的。
Application Code:應用程式程式碼,由開發人員負責開發
Subject:框架提供的介面,代表當前認證物件
SecurityManager:框架提供的介面,代表安全管理器物件
Realm:可以開發人員編寫,框架也提供一些,類似於DAO,使用者訪問許可權資料
2.Shiro的maven依賴與spring配置
2.1shiro的maven依賴
<!-- 引入shiro框架的依賴 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-all</artifactId> <version>1.2.2</version> </dependency>
2.2Shiro的spring配置
(1)在web.xml中配置spring框架提供的用於整合shiro框架的過濾器
<!-- shiro過濾器 --> <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>
(2)整合Spring,配置bean:shiroFilter
<!-- 配置shiro框架的過濾器工廠物件 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 注入安全管理器物件 -->
<property name="securityManager" ref="securityManager" />
<!-- 注入相關頁面訪問URL -->
<property name="loginUrl" value="/login.jsp" />
<property name="successUrl" value="/index.jsp" />
<property name="unauthorizedUrl" value="/unauthorized.jsp" />
<!--注入URL攔截規則 -->
<property name="filterChainDefinitions">
<value>
/css/** = anon
/js/** = anon
/images/** = anon
/validatecode.jsp* = anon
/login.jsp = anon
/userAction_login.action = anon <!--禁止整理格式! -->
/page_base_staff.action = perms["staff-list"]
/* = authc
</value>
</property>
</bean>
(3)註冊安全管理器物件
<!-- 註冊安全管理器物件 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager" />
(4)Controller層編寫login方法,使用shiro提供的方式進行許可權認證
public String login() {
/**
* 校驗驗證碼
*/
//獲取正確的驗證碼
String trueCode = (String) ActionContext.getContext().getSession().get("key");
//驗證碼校驗不通過
if(trueCode != null && !trueCode.equals(checkCode)) {
this.addActionError("驗證碼錯誤");
return LOGIN;
}else {//驗證碼正確
//使用shiro提供的方式進行認證
Subject subject = SecurityUtils.getSubject();//獲取當前使用者物件,狀態為“未認證”
//建立使用者名稱密碼令牌物件
AuthenticationToken token = new UsernamePasswordToken(model.getUsername(), MD5Utils.md5(model.getPassword()));
try {
subject.login(token);
} catch (Exception e) {
e.printStackTrace();
return LOGIN;
}
return HOME;
}
}
如果認證不成功,Shiro會丟擲異常,此時我們在表現層需要處理異常。
(5)自定義Realm,配置bean並注入安全管理器
/**
* 自定義realm
* Title: BOSRealm <p>
* Description: <p>
* @author Tianyu Xiao
* @date 2018年10月23日
*/
public class BOSRealm extends AuthorizingRealm{
@Autowired
private IUserDao userDao;
/**
* 授權
*/
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
// TODO Auto-generated method stub
return null;
}
/**
* 認證
*/
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// TODO Auto-generated method stub
return null;
}
}
配置spring:
<!-- 註冊安全管理器物件 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager" >
<property name="realm" ref="bosRealm" />
</bean>
<!-- 註冊realm -->
<bean id="bosRealm" class="com.itheima.bos.realm.BOSRealm"></bean>
3.Shiro的認證
登陸時認證的java程式碼在2.2(4)中已經完成,我們只需要在Realm中完成Shiro的認證即可。
編寫Realm中的程式碼:
/**
* 認證
*/
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken myToken = (UsernamePasswordToken) token;
String username = myToken.getUsername();
//根據使用者名稱查詢密碼
User user = userDao.findUserByUsername(username);
if(user == null) {
//使用者不存在
return null;//shiro 會丟擲異常
}
//如果能查詢到,再由框架比對資料庫中查詢到的密碼和頁面提交的密碼是否一致
AuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());
return info;
}
4.Shiro的授權
4.1資料庫準備工作
4.2在Realm中完成授權
/**
* 授權
*/
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//獲取當前登陸的使用者物件
User user = (User) SecurityUtils.getSubject().getPrincipal();
//根據當前使用者查詢資料庫,獲取實際對應的許可權
List<Function> functionList = null;
//如果是系統的內建賬號(所有許可權都可以訪問)
if(user.getUsername().equals("admin")) {
functionList = functionDao.findAll();
}else {//是基本通用使用者
functionList = functionDao.findFunctionByUserId(user.getId());
}
//為當前的使用者授權
for (Function function : functionList) {
info.addStringPermission(function.getCode());
}
return info;
}
5.shiro框架提供的許可權控制方式
(1)URL攔截許可權控制(基於過濾器實現)
(2)方法註解許可權控制(基於代理技術實現)
(3)頁面標籤許可權控制(標籤技術實現)