• 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>

  • 相关阅读:
    前端性能优化:Add Expires headers
    HTTP请求header信息讲解
    虚拟机的三种网络模式
    loadrunner中pacing设置01
    loadrunner中pacing的设置
    mysql安全策略
    Linux安装配置apache
    同步加载、异步加载、延迟加载
    monitorix(linux)系统和网络监控公工具
    HTTP与HTTPS对访问速度(性能)的影响
  • 原文地址:https://www.cnblogs.com/kfsrex/p/11635593.html
Copyright © 2020-2023  润新知