shiro權限管理(認證和授權)


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>

 

  1. 以上是shiro和ssm的整合,
  2. 繼續授權的三種方式(用以上的整合的代碼繼續)

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>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM