摘要:框架提供的接口,是的核心,代表安全管理器對象。可以開發人員編寫,框架也提供一些。在中作為應用程序和安全數據之間的橋梁或連接器。例如要求中必須同時含有和的權限才能執行方法。
apache shiro框架簡介
Apache Shiro是一個強大而靈活的開源安全框架,它能夠干凈利落地處理身份認證,授權,企業會話管理和加密。現在,使用Apache Shiro的人越來越多,因為它相當簡單,相比比Spring Security,Shiro可能沒有Spring Security那么多強大的功能,但是在實際工作時可能并不需要那么復雜的東西,所以使用簡單的Shiro就足夠了。
以下是你可以用 Apache Shiro所做的事情:
Shiro的4大核心部分——身份驗證,授權,會話管理和加密
? Authentication:身份驗證,簡稱“登錄”。
? Authorization:授權,給用戶分配角色或者權限資源
? Session Management:用戶session管理器,可以讓CS程序也使用session來控制權限
? Cryptography:把JDK中復雜的密碼加密方式進行封裝。
除了以上功能,shiro還提供很多擴展?? ?
Web Support:主要針對web應用提供一些常用功能。
Caching:緩存可以使應用程序運行更有效率。
Concurrency:多線程相關功能。
Testing:幫助我們進行測試相關功能
Run As:一個允許用戶假設為另一個用戶身份(如果允許)的功能,有時候在管理腳本很有用。
Remember Me:記住用戶身份,提供類似購物車功能。
?
shiro框架認證流程
Application Code:應用程序代碼,由開發人員負責開發的
Subject:框架提供的接口,是與程序進行交互的對象,可以是人也可以是服務或者其他,通常就理解為用戶。所有Subject 實例都必須綁定到一個SecurityManager上。我們與一個 Subject 交互,運行時shiro會自動轉化為與 SecurityManager交互的特定 subject的交互。
SecurityManager:框架提供的接口,是 Shiro的核心,代表安全管理器對象。初始化時協調各個模塊運行。然而,一旦 SecurityManager協調完畢,SecurityManager 會被多帶帶留下,且我們只需要去操作Subject即可,無需操作SecurityManager 。 但是我們得知道,當我們正與一個 Subject 進行交互時,實質上是 SecurityManager在處理 Subject 安全操作。
Realm:可以開發人員編寫,框架也提供一些。Realms在 Shiro中作為應用程序和安全數據之間的“橋梁”或“連接器”。他獲取安全數據來判斷subject是否能夠登錄,subject擁有什么權限。他有點類似DAO。在配置realms時,需要至少一個realm。而且Shiro提供了一些常用的 Realms來連接數據源,如LDAP數據源的JndiLdapRealm,JDBC數據源的JdbcRealm,ini文件數據源的IniRealm,properties文件數據源的PropertiesRealm,等等。我們也可以插入自己的 Realm實現來代表自定義的數據源。 像其他組件一樣,Realms也是由SecurityManager控制。
更詳細的圖
?
?
下面就開始shiro與SSM工程的整合使用
下載地址:http://shiro.apache.org/download.html
下載下來這兩個個文件,一個jar包,一個源碼文件
首先,第一步,將jar包導入到工程中
然后,第二步,在web.xm l中配置spring框架提供的用于整合shiro框架的過濾器(一定要放到springmvc或struts框架過濾器的前面,為了保險起見,放到最上面就好了)
shiroFilter
org.springfr amework.web.filter.DelegatingFilterProxy
shiroFilter
/*
第三步,在spring配置文件中配置bean,id為shiroFilter(要和上面過濾器的名字要一樣)
/sc ript/** = anon
/st yle/** = anon
/index.jsp* = anon
/noPrivilegeUI.jsp* = anon
/user/login = anon
/role/findAllRoleList = perms["角色管理"]
/** = authc
securityManager:這個屬性是必須的。
loginUrl?:沒有登錄的用戶請求需要登錄的頁面時自動跳轉到登錄頁面,不是必須的屬性,不輸入地址的話會自動尋找項目web項目的根目錄下的”/login.jsp”頁面。(shiro默認的頁面就是login.jsp)
successUrl?:登錄成功默認跳轉頁面,可以不配置,不配置則跳轉至”/”。如果登陸前點擊的一個需要登錄的頁面,則在登錄自動跳轉到那個需要登錄的頁面。不跳轉到此。
unauthorizedUrl?:沒有權限默認跳轉的頁面。(只有使用xm l方式校驗權限時起作用)
anon: 例子/admins/** = anon 沒有參數,表示可以匿名使用(不需要認證(登錄))直接放行。
authc : 例如/admins/user/** = authc 表示需要認證(登錄)才能使用,沒有參數
roles:例子/admins/user/ = roles[admin] 參數可以寫多個,多個時必須加上引號,并且參數之間用逗號分割,當有多個參數時,例如admins/user/ = roles["adminguest"] 每個參數通過才算通過,相當于hasAllRoles()方法。
perms:例子/admins/user/ = perms[user:add:] 參數可以寫多個,多個時必須加上引號,并且參數之間用逗號分割,例如/admins/user/ = perms["user:add:user:modify:*"],當有多個參數時必須每個參數都通過才通過,想當于 isPermitedAll()方法。
Rest:例子/admins/user/ = rest[user];根據請求的方法,相當于/admins/user/ = perms[user:method] ;其中method為post,get,delete等。
port:例子/admins/user/** = port[8081]; 當請求的url的端口不是8081是跳轉到schemal://serverName:8081?queryString其中schmal是協議http或https等,serverName是你訪問的host8081是url配置里port的端口,queryString
是你訪問的url里的?后面的參數。
authcBasic:例如/admins/user/** = authcBasic; 沒有參數表示httpBasic認證
ssl:例子/admins/user/** = ssl;沒有參數,表示安全的url請求,協議為https
user:例如/admins/user/** = user; 沒有參數表示必須存在用戶,當登入操作時不做檢查
注:anon,authcBasic,auchc,user是認證過濾器,
perms,roles,ssl,rest,port是授權過濾器
?
第四步:配置安全管理器
?
第五步:寫一個login方法,使用shiro提供的方式進行認證操作
這是我之前的login方法,以這種方法,shiro是不知道登錄驗證通過了的,一直不通過,所以我們要以shiro提供的認證操作方式進行登錄操作
/**
* 登錄
*/
@RequestMapping("/login")
public String login(User user HttpServletRequest request Model model){
HttpSession session = request.getSession();
User newUser = userService.login(user);
if(newUser != null){
session.setAttribute("loginUser"newUser);
return "home/home";
}
model.addAttribute("errorMessage""用戶名或者密碼不正確!");
return "forward:/index.jsp";
}
? 修改后的login方法
/**
* 使用Shiro框架提供的方式進行認證登錄
*/
@RequestMapping("/login")
public String login(User user HttpServletRequest request Model model){
HttpSession session = request.getSession();
//使用Shiro框架提供的方式進行認證
Subject subject = SecurityUtils.getSubject(); //獲得subject,現在狀態為 “未認證”
//用戶名密碼令牌
AuthenticationToken token = new UsernamePasswordToken(user.getLoginName() MD5Utils.md5(user.getPassword()));
try{
subject.login(token); //執行你自定義的Realm
User user1 = (User) subject.getPrincipal();//獲得當前登錄用戶對象
session.setAttribute("loginUser"user1);
return "home/home";
}catch(UnknownAccountException e){
e.printStackTrace();
model.addAttribute("errorMessage""此用戶名不存在!");
}catch(IncorrectCredentialsException e){
e.printStackTrace();
model.addAttribute("errorMessage""密碼不正確!");
}catch(Exception e){
e.printStackTrace();
}
return "forward:/index.jsp";
}
?
第六步:自定義realm,并注入給安全管理器
創建一個UserRealm類,繼承AuthorizingRealm這個類
public class UserRealm extends AuthorizingRealm{
@Autowired
private UserDao userDao;
@Autowired
private PrivilegeDao privilegeDao;
//認證方法
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("realm中的認證方法執行了。。。。");
UsernamePasswordToken myToken = (UsernamePasswordToken) token;
String loginName = myToken.getUsername();
User user = new User();
//根據用戶名查詢數據庫中的用戶這個方法是自己寫的
if(loginName.equals("admin")){ //超級管理員擁有所有權限
user.setLoginName(loginName);
user.setName(loginName);
user.setPassword(MD5Utils.md5("1234"));
}else{
user = userDao.findUserByLoginName(loginName);
if(user == null){
//用戶名不存在
return null;
}
}
//如果能查詢到,再由框架比對數據庫中查詢到的密碼和頁面提交的密碼是否一致傳入的是數據庫中的密碼,shiro會自行對比
AuthenticationInfo info = new SimpleAuthenticationInfo(user user.getPassword() this.getName());
return info;
}
//授權方法
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals){
return null;
}
?
?
將自定義realm注入給安全管理器
? 到這里程序就可以正常運行了登錄后進入首頁
但是點擊角色管理,會進入沒有權限的頁面
?
這是因為我在spring配置文件中配置了? ?/role/findAllRoleList = perms["角色管理"],而我還沒有給當前用戶授權,所以當前用戶沒有權限訪問此路徑
所以要給該用戶授權,在UserRealm類中,編寫授權方法
//授權方法
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals){
System.out.println("realm中的授權方法執行了。。。。");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//兩種獲得已認證的登錄用戶的方法,效果一模一樣,用哪個都行
User user = (User) principals.getPrimaryPrincipal();
// User user = (User) SecurityUtils.getSubject().getPrincipal();
if(user.getLoginName().equals("admin")){ //超級管理員擁有所有權限
List privilegeList = privilegeDao.findAllPrivilegeList();
for (Privilege privilege : privilegeList) {
info.addStringPermission(privilege.getName());
}
}else{
for (Role role : user.getRoles()){
for (Privilege privilege : role.getPrivileges()){
info.addStringPermission(privilege.getName());
}
}
}
return info;
}
?
?
這樣,就可以正常訪問了,這個授權方法是在訪問/role/findAllRoleList這個路徑時,shiro框架自動調用的
我們之前進行權限控制是在spring配置文件中配置了? ?/role/findAllRoleList = perms["角色管理"] ,現在介紹另一種方式,也是我比較喜歡的方式,?使用注解方式進行權限控制
? 使用shiro的方法注解方式權限控制
第一步:在springmvc配置文件中開啟shiro注解支持(注意:springmvc框架,放到springmvc配置文件中,struts放到spring配置文件中)
?
第二步:在Controller的方法上使用shiro注解------ @RequiresPermissions("") 執行這個方法必須有相應的權限
/**
* 查詢崗位列表
*/
@RequiresPermissions("角色列表") //執行這個方法必須有角色列表這個權限
@RequestMapping("/findAllRoleList")
public String findAllRoleList(Model model){
List roleList = roleService.findAllRoleList();
model.addAttribute("roleList"roleList);
return "role/list";
}
@RequiresAuthentication
驗證用戶是否登錄,等同于方法subject.isAuthenticated()?結果為true時。
@ RequiresUser
驗證用戶是否被記憶,user有兩種含義:
一種是成功登錄的(subject.isAuthenticated()?結果為true);
另外一種是被記憶的( subject.isRemembered()結果為true)。
@ RequiresGuest
驗證是否是一個guest的請求,與@ RequiresUser完全相反。
??????? ? 換言之,RequiresUser? == ! RequiresGuest 。
? ?此時subject.getPrincipal() 結果為null.
@ RequiresRoles
例如:@RequiresRoles("aRoleName");
???????? ?????? ?? void someMethod();
如果subject中有aRoleName角色才可以訪問方法someMethod。如果沒有這個權限則會拋出異常AuthorizationException。
@RequiresPermissions
例如: @RequiresPermissions( {"file:read" "write:aFile.txt"} )
???????? ???????? void someMethod();
要求subject中必須同時含有file:read和write:aFile.txt的權限才能執行方法someMethod()。否則拋出異常AuthorizationException。
?
? 注解方式的權限控制就完成了,但這種方式沒有權限時不會自動跳轉到沒有權限的頁面,而是直接把異常拋到頁面了,所以我們要配置一個全局的異常處理
第三步:在springmvc配置文件中,進行如下配置,配置全局異常捕獲,當shiro框架拋出權限不足異常時,跳轉到權限不足提示頁面
redirect:/noPrivilegeUI.jsp
使用shiro提供的頁面標簽方式權限控制
再來,說一說shiro提供的頁面標簽
第一步:在jsp頁面中引入shiro的標簽庫
<%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro"%>
第二步:使用shiro的標簽控制頁面元素展示
?
最后,使用ehcache緩存權限數據
ehcache是專門緩存插件,可以緩存Java對象,提高系統性能。
首先,導入ehcache的jar包
然后,在項目中引入ehcache的配置文件
```
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/126008.html
摘要:安全框架是目前為止作為登錄注冊最常用的框架,因為它十分的強大簡單,提供了認證授權加密和會話管理等功能。本質上是一個特定安全的。當配置時,必須指定至少一個用來進行身份驗證和或授權。提供了多種可用的來獲取安全相關的數據。 web開發安全框架中的Apache Shiro的應用前階段就hadoop的分享了一些內容,希望對新手入門的朋友有點幫助吧!對于hadoop新手入門的,還是比較推薦大快搜索...
摘要:大家好,今天給大家分享一個權限管理的框架的,說實話本來我是準備看的,畢竟是家族的框架,和整合更加容易一些。官方給出的介紹是是一個強大且易用的安全框架執行身份驗證授權密碼學和會話管理。由此可知,的主要功能是認證授權加密密和會話管理。 showImg(https://segmentfault.com/img/bV1BsT?w=1726&h=256); 大家好,今天給大家分享一個權限管理的框...
摘要:大家好,今天給大家分享一個權限管理的框架的,說實話本來我是準備看的,畢竟是家族的框架,和整合更加容易一些。官方給出的介紹是是一個強大且易用的安全框架執行身份驗證授權密碼學和會話管理。由此可知,的主要功能是認證授權加密密和會話管理。 showImg(https://segmentfault.com/img/bV1BsT?w=1726&h=256); 大家好,今天給大家分享一個權限管理的框...
摘要:的很容易反映出常見的工作流程。權限檢查是執行授權的另一種方式。在安全框架領域提供了一些獨特的東西一致的會話,可用于任何應用程序和任何架構層。 Apache Shiro?是一個功能強大且易于使用的Java安全框架,可執行身份驗證,授權,加密和會話管理。借助Shiro易于理解的API,可以快速輕松地保護任何應用程序 - 從最小的移動應用程序到最大的Web和企業應用程序。 1. Apache S...
閱讀 3514·2023-04-25 20:09
閱讀 3720·2022-06-28 19:00
閱讀 3035·2022-06-28 19:00
閱讀 3058·2022-06-28 19:00
閱讀 3132·2022-06-28 19:00
閱讀 2859·2022-06-28 19:00
閱讀 3014·2022-06-28 19:00
閱讀 2610·2022-06-28 19:00