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>

猜你喜欢

转载自www.cnblogs.com/kfsrex/p/11635593.html