Shiro介紹
1.shiro介紹:Shirp是apache旗下一個開源框架,它將軟件系統的安全認證相關的功能抽取出來,實現用戶身份認證,權限授權,加密,會話管理等功能,組成一個通用的安全認證框架。
2.Shiro框架
3.對象:
a) Subject:主體,外部應用與subject進行交互,subject記錄了當前操作用戶,將用戶的概念理解為當前操作的主體,可能是通過瀏覽器請求的用戶,也可能是一個運行的程序。Subject在shiro中是一個接口,接口中定義了很多認證授權的相關方法,外部程序通過subject進行認證授權,而subject是通過SecurityManager安全管理器進行認證授權。
b) SecurityManager:安全管理器,對全部的subject進行安全管理,它是shiro的核心,負責對所有的subject進行安全管理。通過SecurityManager可以完成subject的認證,授權等,實質上SecurityManager是通過Authenticator進行認證,通過Authorizer進行授權,通過SessuionManager進行會話管理等。SecurityManager是一個接口,繼承了Authenticator,Authorizer,SessionManager三個接口。
c) Authenticator:認證器,對用戶身份進行認證。Authenticator是一個接口,shiro提供ModularRealmAuthenticator實現類,通過ModularRealmAuthenticator基本上可以滿足大部分需求,也可以自定義認證器。
d) Authorizer:授權器,用戶通過認證器認證后,在訪問功能時需要通過授權器判斷用戶是否有此功能的操作權限。
e) realm:領域,相當於datasource數據源,securityManager進行安全認證需要通過Realm獲取用戶數據,比如:如果用戶身份數據在數據庫那么realm就需要從數據庫獲取用戶身份信息。realm不僅僅時從數據源取數據,在realm中還有認證授權校驗的代碼。
f) sessionManager:會話管理,shiro框架定義了一套會話管理,它不依賴web容器的session,所以shiro可以使用在非web應用上,也可以將分布式應用的會話集中在一點管理,此特性可使它實現單點登錄。
g) SessionDAO:會話dao,是對session會話操作的一套接口,比如將session存儲到數據庫。可以通過jdbc將會話存儲到數據庫。
h) CacheManager:緩存管理,將用戶權限數據存儲到緩存里,這樣可以提高性能。
i) Cryptography:密碼管理,shiro提供一套加密/解密的組件,方便開發。比如提供常用的散列,加/解密等功能。
j) shiro的jar包(maven):
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.3</version> </dependency>
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.2.3</version> </dependency>
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.3</version> </dependency>
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.2.3</version> </dependency>
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-quartz</artifactId> <version>1.2.3</version> </dependency>
也可以通過引入shiro-all包括shiro所有的包: <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-all</artifactId> <version>1.2.3</version>
</dependency> |
Shiro使用(用maven)
認證的簡單使用
1.導入jar包,關於shiro的jar包的maven坐標
<!-- shiro的core包 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.4.0</version> </dependency>
<!-- --> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.9.3</version> </dependency> |
2.在resources下配置shiro.ini文件
[users] #用戶信息:賬號=密碼(shiro默認的realm是iniRealm) admin=admin user=user |
3.測試代碼
package com.zhiyou100.kfs.shiro;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory;
public class Shiro { public static void main(String[] args) { //1.根據IniSecurityManager類加ini文件創建SecurityManager factory Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:shiro.ini"); //2.根據factory的getInstance方法創建SecurityManager對象 SecurityManager securityManager=factory.getInstance(); //3.把securityManager放到運行環境中 SecurityUtils.setSecurityManager(securityManager); //4.獲取subject對象 Subject subject=SecurityUtils.getSubject(); //創建UsernamePasswordToken對象獲取輸入的身份信息(賬號密碼) UsernamePasswordToken token=new UsernamePasswordToken("admin","admin");
try { //認證登錄,該方法通過異常來區分登錄失敗和成功 subject.login(token); System.out.println("登錄成功"); }catch(Exception e){ System.out.println("登錄失敗"); }
} } |
認證使用自定義的realm
1.在resources配置shiroRealm.ini文件
[main] #定義自己的realm myrealm=com.zhiyou100.kfs.realm.MyRealm #把該realm綁定到securityManager上 securityManager.realms=$myrealm |
2.創建自定義的realm
package com.zhiyou100.kfs.realm;
import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection;
import com.zhiyou100.kfs.bean.User;
public class MyRealm extends AuthorizingRealm{
//授權 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { return null; }
//認證 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("開始執行認證"); //獲取輸入的賬號 String username = token.getPrincipal().toString(); //根據該賬號查詢數據庫(這邊用固定的值) User user=new User(); user.setUsername("admin"); user.setPassword("admin");
if(user==null) { return null; } /* * principal:輸入的賬號 * credentials:根據賬號查詢的密碼 * realName:隨便給,但企業習慣用 this.getName() * info:對象會幫你比較 密碼是否一致 * new SimpleAuthenticationInfo(principal, credentials, realmName); */ SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(username,user.getPassword(),getName()); return info; }
} |
授權的簡單使用
1.在resources下配置shiroPermission.ini文件
[main] #定義自己的realm myrealm=com.zhiyou100.kfs.realm.MyRealm #把該realm綁定到securityManager上 securityManager.realms=$myrealm |
2.測試代碼
package com.zhiyou100.kfs.shiro;
import java.util.ArrayList; import java.util.Arrays;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory;
public class ShiroPermission { public static void main(String[] args) { //1.根據IniSecurityManagerFactory類和ini文件創建SecurityManager的factory Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:shiroPermission.ini"); //2.根據factory的getInstance方法創建securityManager對象 SecurityManager securityManager = factory.getInstance(); //3.把securityManager對象放到運行環境 SecurityUtils.setSecurityManager(securityManager);
//4.獲取Subject對象 Subject subject = SecurityUtils.getSubject(); //5.獲取輸入的身份信息 UsernamePasswordToken token=new UsernamePasswordToken("admin","admin");
try { subject.login(token); System.out.println("登錄成功"); }catch (Exception e) { System.out.println("登錄失敗"); }
//判斷是否有某個角色 boolean isone = subject.hasRole("role1"); System.out.println("判斷是否有某個角色:"+isone); //判斷是否有某多個角色 boolean ismul = subject.hasAllRoles(Arrays.asList("role1","role2")); System.out.println("判斷是否有某多個角色:"+ismul);
//判斷是否有某個權限 boolean ispone = subject.isPermitted("user:create"); System.out.println("判斷是否有某個權限:"+ispone); //判斷是否有某多個權限 boolean ispmul = subject.isPermittedAll("user:create","user:delete"); System.out.println("判斷是否有某多個權限:"+ispmul);
} } |
授權使用自定義的realm
1.在resources中創建shiroPermission.ini文件
[users] #用戶信息:賬號=密碼,角色1,角色2...(shiro默認的realm是iniRealm) admin=admin,role1,role2
[roles] #角色名稱=權限1,權限2,... role1=user:create,user:delete role2=user:query |
2.創建自定義的realm
package com.zhiyou100.kfs.realm;
import java.util.ArrayList; import java.util.List;
import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection;
import com.zhiyou100.kfs.bean.Role; import com.zhiyou100.kfs.bean.User;
public class MyRealm extends AuthorizingRealm{
//授權 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { System.out.println("開始授權"); //獲取認證過的賬號 String username=principals.toString(); System.out.println(username);
//根據認證的賬號查詢該用戶具有的角色(這邊用固定值) List<Role> roles=new ArrayList<Role>(); if("admin".equals(username)) { Role role1 = new Role(); role1.setRolename("admin"); roles.add(role1); Role role2 = new Role(); role2.setRolename("user"); roles.add(role2); }else if("user".equals(username)) { Role role1 = new Role(); role1.setRolename("user"); roles.add(role1); } if(roles.isEmpty()) {//該用戶沒任何角色 return null; }
//該角色具有的權限 SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
for(Role role:roles) { //把角色名放到info里 info.addRole(role.getRolename()); //根據該角色查詢對應的權限 if("admin".equals(role.getRolename())) { info.addStringPermission("user:delete"); } if("user".equals(role.getRolename())) { info.addStringPermission("user:select"); } } return info; }
//認證 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("開始執行認證"); //獲取輸入的賬號 String username = token.getPrincipal().toString(); //根據該賬號查詢數據庫(這邊用固定的值) User user=new User(); user.setUsername("user"); user.setPassword("user");
if(user==null) { return null; } /* * principal:輸入的賬號 * credentials:根據賬號查詢的密碼 * realName:隨便給,但企業習慣用 this.getName() * info:對象會幫你比較 密碼是否一致 * new SimpleAuthenticationInfo(principal, credentials, realmName); */ SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(username,user.getPassword(),getName()); return info; }
} |
3.測試代碼
package com.zhiyou100.kfs.shiro;
import java.util.Arrays;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory;
public class ShiroRealm {
public static void main(String[] args) { //得到一個Factory對象 作用創建SecurityManager對象 Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiroRealm.ini"); //獲取SecurityManager對象 SecurityManager securityManager=factory.getInstance();
//把securityManager放到運行環境中 SecurityUtils.setSecurityManager(securityManager); //獲取Subject對象。 Subject subject=SecurityUtils.getSubject(); UsernamePasswordToken token=new UsernamePasswordToken("user","user"); //值可以從網頁中獲取 try { subject.login(token); //需要賬號和密碼 Token對象中 System.out.println("登錄成功"); }catch (Exception e) { e.printStackTrace(); System.out.println("登錄失敗"); }
//有沒有某個角色 boolean hasRole = subject.hasRole("admin"); System.out.println("有沒有某個角色:"+hasRole); //有沒有同時擁有某多個角色 boolean hasAllRoles = subject.hasAllRoles(Arrays.asList("admin","user")); System.out.println("有沒有某多個角色"+hasAllRoles);
//有沒有某個權限 boolean permitted = subject.isPermitted("user:select"); System.out.println("有沒有某個權限"+permitted); //有沒有同時擁有某多個權限 boolean permittedAll = subject.isPermittedAll("user:delete","user:select"); System.out.println("有沒有某多個權限"+permittedAll);
}
} |
自定義realm的認證和授權(固定值)
1.導入jar包(用的maven)
<!-- shiro的core包 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.4.0</version> </dependency>
<!-- --> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.9.3</version> </dependency> |
2.配置realm.ini文件
#自定義的realm
#定義自定義realm shiropermissionrealm=com.zhiyou100.kfs.realm.ShiroPermissionRealm
#把自定義的realm綁定到securityManager中 securityManager.realms=$shiropermissionrealm |
3.創建自定義realm類ShiroPermissionRealm類
package com.zhiyou100.kfs.realm;
import java.util.ArrayList; import java.util.List;
import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection;
import com.zhiyou100.kfs.bean.Role; import com.zhiyou100.kfs.bean.User;
public class ShiroPermissionRealm extends AuthorizingRealm{
//授權 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { System.out.println("開始授權");
//獲取認證通過的賬號 String username = principals.toString(); //根據賬號查詢數據庫的角色(這邊用固定值) List<Role> roles=new ArrayList<Role>(); Role role1 = new Role(); role1.setRilename("admin"); roles.add(role1); Role role2 = new Role(); role2.setRilename("user"); roles.add(role2);
//判斷根據賬號有沒有查到數據 if(roles.isEmpty()) { return null; }
//給對應的角色賦予對應的權限(資源) SimpleAuthorizationInfo info=new SimpleAuthorizationInfo(); for(Role role:roles) { //根據角色查詢數據庫的權限(這邊用固定值)
//添加角色名到info info.addRole(role.getRilename()); if(role.getRilename().equals("admin")) { //為角色賦予權限 info.addStringPermission("user:create"); }else if(role.getRilename().equals("user")) { info.addStringPermission("user:delete"); } }
return info; }
//認證 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("開始認證");
//獲取輸入的賬號 String username = token.getPrincipal().toString(); System.out.println(username);
//根據賬號查詢數據庫的用戶(這邊用固定值) User user=new User();//假設是數據庫的 user.setUsername("admin"); user.setPassword("admin");
//判斷用賬號有沒有查到數據 if(user==null) { return null; } System.out.println(user);
/* * 比較輸入的賬號密碼對不對,對沒有異常,錯誤有各種異常(賬號錯誤,密碼錯誤是不同的異常) * new SimpleAuthenticationInfo(principal, credentials, realmName); * principal:輸入的賬號 * credentials:根據賬號在數據庫查到的密碼 * realmName:隨便,但企業用this.getName() * */ SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(username,user.getPassword(),getName()); return info; }
} |
4.測試代碼
package com.zhiyou100.kfs.shiro;
import java.util.Arrays;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory;
public class ShiroPermission { public static void main(String[] args) { /* * Shiro的認證和授權 */
//認證 //1.根據IniSecurityManagerFactory類和ini文件獲取創建SecurityManager類的Factory Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:realm.ini"); //2.根據factory對象的getInstance方法創建securityManager對象 SecurityManager securityManager = factory.getInstance(); //3.根據SecurityUtils工具類的setSecurityManager把securityManager對象放到運行環境中 SecurityUtils.setSecurityManager(securityManager); //以上3步整合由框架完成
//4.根據SecurityUtils工具類的getSubject方法獲取subject對象 Subject subject = SecurityUtils.getSubject(); //5.把輸入的賬號密碼放到UsernamePasswordToken類的token對象中 UsernamePasswordToken token=new UsernamePasswordToken("admin", "admin");
try { //6.根據subject對象的login方法進行認證(認證成功不會有異常,認證失敗會有各種不同的異常,所有通過try,catch來判斷是否認證成功) subject.login(token); System.out.println("認證成功"); }catch (Exception e) { System.out.println("認證失敗"); }
//授權 //有沒有某個角色 boolean hasRole = subject.hasRole("admin"); System.out.println("有沒有某個角色:"+hasRole); //有沒有同時擁有某多個角色 boolean hasAllRoles = subject.hasAllRoles(Arrays.asList("admin","user")); System.out.println("有沒有某多個角色"+hasAllRoles);
//有沒有某個權限 boolean permitted = subject.isPermitted("user:select"); System.out.println("有沒有某個權限"+permitted); //有沒有同時擁有某多個權限 boolean permittedAll = subject.isPermittedAll("user:delete","user:create"); System.out.println("有沒有某多個權限"+permittedAll);
} } |
自定義realm和ssm整合再加數據庫的認證和授權
1.jar包(ssm的jar包、shiro的jar包和shiro-springjar包)用maven
<!-- shiro的core包 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.4.0</version> </dependency>
<!-- --> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.9.3</version> </dependency>
<!-- shiro-web --> <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-web --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.4.0</version> </dependency>
<!-- shiro-spring --> <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version> </dependency> |
2.mysql數據庫的5張表(user,role,permission,user_role,role_permission):
3.逆向工程生成對應bean實體類,dao操作類接口,mapper映射文件
4.ssm配置代碼
5.配置自定義的Realm類:ShiroRealm
package com.zhiyou100.kfs.realm;
import java.util.List;
import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.springframework.beans.factory.annotation.Autowired;
import com.zhiyou100.kfs.bean.Permission; import com.zhiyou100.kfs.bean.Role; import com.zhiyou100.kfs.bean.User; import com.zhiyou100.kfs.service.PermissionService; import com.zhiyou100.kfs.service.RoleService; import com.zhiyou100.kfs.service.UserService;
public class ShiroRealm extends AuthorizingRealm{ @Autowired private UserService userService; @Autowired private RoleService roleService; @Autowired private PermissionService permissionService;
//授權 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { System.out.println("開始授權");
//獲取認證通過的賬號 String username = principals.getPrimaryPrincipal().toString();
//根據賬號查詢角色 List<Role> roles = roleService.selectByUsername(username); System.out.println(roles);
if(roles.isEmpty()) {//判斷是否為空 return null; }
//遍歷並給對應的角色賦予對應的權限(資源) SimpleAuthorizationInfo info=new SimpleAuthorizationInfo(); for(Role role:roles) { //添加角色名到info info.addRole(role.getRolename());
//根據角色查詢對應的資源並添加到info里 List<Permission> permissions = permissionService.selectByRoleId(role.getRoleid()); for(Permission permission:permissions) { info.addStringPermission(permission.getUrl()); } } return info; }
//認證 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("開始認證");
//獲取輸入的賬號 String username = token.getPrincipal().toString(); System.out.println(username);
//根據賬號查詢用戶 User user=userService.selectByUsername(username); System.out.println(user); if(user==null) { return null; }
SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(username,user.getPassword(),getName()); return info; }
} |
6.測試認證的controller類:LoginController
package com.zhiyou100.kfs.controller;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView;
import com.zhiyou100.kfs.bean.User;
@Controller @RequestMapping("user") public class LoginController {
@RequestMapping("login") public ModelAndView login(ModelAndView mv,User user) { System.out.println(user); //通過shiro認證
//獲取subject Subject subject = SecurityUtils.getSubject(); //用UsernamePasswordToken對象yoken接輸入的賬號密碼 UsernamePasswordToken token=new UsernamePasswordToken(user.getUsername(),user.getPassword());
try { subject.login(token); System.out.println("認證成功"); mv.setViewName("index"); }catch (Exception e) { e.printStackTrace(); System.out.println("認證失敗"); mv.setViewName("login"); } return mv; }
@RequestMapping("logout") public ModelAndView logout(ModelAndView mv) { mv.setViewName("/login"); //用shiroFilter的logout過濾器可以完成注銷操作 return mv; } } |
7.測試授權的controller類:UserController
package com.zhiyou100.kfs.controller;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView;
import com.zhiyou100.kfs.service.UserService;
@Controller @RequestMapping("user") public class UserController { @Autowired private UserService userService;
@RequestMapping("insertUser") public ModelAndView insertUser(ModelAndView mv) { mv.setViewName("");
return mv; }
@RequestMapping("deleteUser") public ModelAndView deleteUser(ModelAndView mv) { mv.setViewName("");
return mv; }
@RequestMapping("updateUser") public ModelAndView updateUser(ModelAndView mv) { mv.setViewName("");
return mv; } } |
8.測試的jsp
//login.jsp:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>login</title> </head> <body> <form action="<c:url value='user/login'/>" method="post"> 賬號:<input type="text" name="username" /><br/> 密碼:<input type="text" name="password" /><br/> <input type="submit" value="登錄" /><br/> </form> </body> </html>
//index.jsp:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>index</title> </head> <body> index<br/> 歡迎,<a href="<c:url value='/user/logout'/>">注銷</a><br/>
<a>user</a><br/> <a href="<c:url value='/user/insertUser'/>">user:create</a><br/> <a href="<c:url value='/user/deleteUser'/>">user:delete</a><br/> <a href="<c:url value='/user/updateUser'/>">user:update</a><br/> <a>good</a><br/> <a href="<c:url value='/user/insertGood'/>">good:create</a><br/> </body> </html> |
9.shiro和spring的整合xml:applicationContext-shiro.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 把shiro配置在spring里 -->
<!-- 配置自定義的realm類 --> <bean id="shiroRealm" class="com.zhiyou100.kfs.realm.ShiroRealm"/>
<!-- 配置DefaultWebSecurityManager,並把realm放到運行環境里 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="shiroRealm"/> </bean>
<!-- 請求過濾器,id要和web.xml的過濾器名一樣 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- 過濾器和securityManager關聯 --> <property name="securityManager" ref="securityManager"/>
<!-- 登錄界面login.jsp放行 --> <property name="loginUrl" value="/login.jsp"/>
<!-- 權限不足的跳轉頁面 --> <property name="unauthorizedUrl" value="/error.jsp"/>
<!-- 設置攔截規則 --> <property name="filterChainDefinitions"> <value> /js/*=anon /css/*=anon /images/*=anon
<!-- 給登錄的控制層方法放行,否則進不去 --> /user/login=anon
<!-- 基於角色攔截 --> <!-- /user/insertUser=roles[user] /user/updateUser=roles['admin','user'] /user/deleteUser=roles[admin] -->
<!-- 基於資源攔截 --> /user/insertUser=perms[user:create] /user/updateUser=perms[user:update] /user/deleteUser=perms[user:delete]
<!-- 注銷 --> /user/logout=logout
/**=authc </value> </property> </bean>
</beans> |
- 以上是shiro和ssm的整合,
- 繼續授權的三種方式(用以上的整合的代碼繼續)
a) 用配置文件配置攔截器來授權(以上就是用配置文件完成授權的)
b) 注解式:用注解式就不用配置上面applicationContext-shiro.xml中的filterChainDefinitions。
i. web.xml還是以上配置,但是springContext-shiro.xml需要把<property name="filterChainDefinitions">給去掉,然后在controller層加相應注解。
ii. springContext-shiro.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 把shiro配置在spring里 -->
<!-- 配置自定義的realm類 --> <bean id="shiroRealm" class="com.zhiyou100.kfs.realm.ShiroRealm"/>
<!-- 配置DefaultWebSecurityManager,並把realm放到運行環境里 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="shiroRealm"/> </bean>
<!-- 請求過濾器,id要和web.xml的過濾器名一樣 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- 過濾器和securityManager關聯 --> <property name="securityManager" ref="securityManager"/>
<!-- 登錄界面login.jsp放行 --> <property name="loginUrl" value="/login.jsp"/>
<!-- 權限不足的跳轉頁面 --> <property name="unauthorizedUrl" value="/error.jsp"/>
<!-- 設置攔截規則:用配置文件式授權用,若用注解式授權則不用 --> <!-- <property name="filterChainDefinitions"> <value> /js/*=anon /css/*=anon /images/*=anon
給登錄的控制層方法放行,否則進不去 /user/login=anon
基於角色攔截 /user/insertUser=roles[user] /user/updateUser=roles['admin','user'] /user/deleteUser=roles[admin]
基於資源攔截 /user/insertUser=perms[user:create] /user/updateUser=perms[user:update] /user/deleteUser=perms[user:delete]
注銷 /user/logout=logout
/**=authc </value> </property> --> </bean>
</beans> |
iii. controller層
package com.zhiyou100.kfs.controller;
import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresRoles; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView;
@Controller @RequestMapping("user") public class UserController {
@RequestMapping("insertUser") @RequiresPermissions(value="user:create") public ModelAndView insertUser(ModelAndView mv) { mv.setViewName("");
return mv; }
@RequestMapping("deleteUser") /* * @RequiresRoles:注解式授權,表示基於角色的授權,logical.OR表示或的關系,不寫表示與,value里的就是需要的角色 * @RequiresPermissions:注解式授權,表示基於資源的授權 */ @RequiresRoles(value= {"admin","user"},logical=Logical.OR) @RequiresPermissions(value="user:delete") public ModelAndView deleteUser(ModelAndView mv) { mv.setViewName("");
return mv; }
@RequestMapping("updateUser") @RequiresPermissions(value="user:update") public ModelAndView updateUser(ModelAndView mv) { mv.setViewName("");
return mv; } } |
c) 標簽式:在網頁加入shiro的標簽來授權
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>index</title> </head> <body> index<br/> 歡迎,<a href="<c:url value='/user/logout'/>">注銷</a><br/>
<a>user</a><br/>
<!-- 有user:create資源的角色才看的見 --> <shiro:hasPermission name="user:create"> <a href="<c:url value='/user/insertUser'/>">user:create</a><br/> </shiro:hasPermission> <a href="<c:url value='/user/deleteUser'/>">user:delete</a><br/> <a href="<c:url value='/user/updateUser'/>">user:update</a><br/> <a>good</a><br/>
<!-- 有角色admin才看得見 --> <shiro:hasRole name="admin"> <a href="<c:url value='/user/insertGood'/>">good:create</a><br/> </shiro:hasRole> </body> </html> |