关于spring整合shiro的方法

shiro简介

shiro是权限控制的一个框架
是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理功能,可为任何应用提供安全保障 - 从命令行应用、移动应用到大型网络及企业应用。

权限控制的方式

权限有四种实现方式
注解(基于代理),url拦截(基于过滤器),shiro标签库(基于标签),编写代码(及其不推荐)
不论哪种方式:都需要引入spring用于整合shiro的过滤器
web.xml中:DelegatingFilterProxy=>spring整合shiro
配置spring提供的用于整合shiro框架的过滤器

  <filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy
   </fileter>

filet-name需要和spring配置文件中的一个BEAN对象的id保持一致非常重要

配置

I. 注解方式,注解是利用生成的代理对象来完成权限校验:
spring框架会为当前action对象(加注解的action)创建一个代理对象,如果有权限,就执行这个方法,不然就会报异常
(将spring,Strust配置文件丰富:添加权限的注解,struts添加捕获异常,跳转页面)
1. 需要在spring配置文件中进行配置开启注解DefaultAdvisorAutoProxyCreator,
并配置成cjlib方式的注解

<property name="proxyTargetClass" value="true">\</property>

注解实现权限当为jdk模式的时候
方法注解实现权限过滤
抛异常的原因:因为如果是jdk方式的话,实现的接口modelDriven只有一个getModel方法
所以不能进行对除该方法外其他方法进行注解

  1. 定义切面类AuthorizationAttributeSourceAdvisor

    <bean id="authorizationAttributeSourceAdvisor" class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"></bean>
  2. 在需要权限才能访问的方法上添加注解

    @RequiresPermissions("relo_delete这是权限名称")   

II. url拦截(springxml)
基于过滤器或者拦截器实现

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
        <property name="loginUrl" value="/login.jsp"/>
        <property name="unauthorizedUrl" value="/unauthorized.jsp"/>
        <property name="filterChainDefinitions">
            <value>
                /css/** = anon
                /js/** = anon
                /images/** = anon
                /validatecode.jsp* = anon
                /login.jsp* = anon
                /userAction_login.action = anon
                /page_base_staff.action = perms["staff"]
                /** = authc
                <!--/** = authc-->
            </value>
        </property>
    </bean>
    <!--开启自动代理,并且将代理代理模式设置为cjlib-->
    <bean id="defaultAdvisorAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
        <!--设置成cglib方式-->
        <property name="proxyTargetClass" value="true"></property>
    </bean>

shiro各种过滤器简写

shiro的使用

  1. 在web.xml中引入用于创建shiro框架的过滤器
    web.xml中:DelegatingFilterProxy=>spring整合shiro
    注意引入的位置:要在struts核心过滤器的前面,StrutsPrepareAndExcutFilter,不然,所有请求会通过struts过滤器获直接访问得到,shiro的过滤器将不会起到作用

  2. 在Spring中整合shiro
    2.1). shiro框架过滤器:ShiroFilterFactoryBean 需要声明那些过滤器,那些资源需要匹配那些过滤器,采用url拦截方式进行的路径对应的拦截器
    2.2). 配置安全管理器:DefaultWebSecurityManager 需要注入 自定义的Realm bean对象

    <!--配置一个shiro框架的过滤器工厂bean,用于创建shiro框架的过滤器-->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
        <property name="loginUrl" value="/login.jsp"/>
        <property name="unauthorizedUrl" value="/unauthorized.jsp"/>
        <property name="filterChainDefinitions">
            <value>
                /css/** = anon
                /js/** = anon
                /images/** = anon
                /validatecode.jsp* = anon
                /login.jsp* = anon
                /userAction_login.action = anon
                /page_base_staff.action = perms["staff"]
                /** = authc
                <!--/** 表示所有/下所有路径,包括下面的所有路径-->
        <!--/validatecode.jsp*
         表示所有除了validatecode.jsp,还包括jsp后追加其他内容的.如validatecode.jsp?'+Math.random();防止验证码读取缓存
            </value>
        </property>
    </bean>
    <!--开启自动代理,并且将代理代理模式设置为cjlib
    动态代理分为两类
    基于jdk 创建的类必须要实现一个接口,这是面向接口的动态代理   
    基于cjlib 创建的类不能用final修饰
    -->
    <bean id="defaultAdvisorAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
        <!--设置成cglib方式-->
        <property name="proxyTargetClass" value="true"></property>
    </bean>
    <!--定义aop通知+切入点-->
    <bean id="authorizationAttributeSourceAdvisor" class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"></bean>
    
    <!--注入安全管理器-->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="bosRealm"></property>
        <property name="cacheManager" ref="ehCacheManager"></property>
    </bean>
  3. 在登陆认证的方法中加入subject controller中的login方法

public String login(){
Subject subject = SecurityUtils.getSubject();
  //创建一个用户名密码令牌
  AuthenticationToken token = new UsernamePasswordToken(getModel().getUsername(), MD5Utils.md5(
          getModel().getPassword()));
  try {
    //认证
      subject.login(token);
  } catch (Exception e) {
      this.addActionError("用户名或者密码错误");
      return LOGIN;
  }
  /*当通过认证,跳入主页*/
  User user = (User) subject.getPrincipal();
  /*将用户信息存入session*/
  ServletActionContext.getRequest().getSession().setAttribute("currentUser", user);
  /*返回主页*/
  return "";
}
  1. 自定义Realm(用于权限的具体实施,即认证和授权)一般实现Realm接口的 AuthorizingRealm 实例
    4.1实现认证 重写doGetAuthenticationInfo方法
    必须继承AuthorizingRealm
    在需要交付给spring生成,并需要在安全注册管理器中注入属性Realm
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

UsernamePasswordToken mytoken = (UsernamePasswordToken) token;
       String username = mytoken.getUsername();
       DetachedCriteria dc = DetachedCriteria.forClass(User.class);
       dc.add(Restrictions.eq("username",username));
       List<User> list = userDao.findByCriteria(dc);
       if(list != null && list.size() >0){
           User user = list.get(0);
           String dbPassword = user.getPassword();
           AuthenticationInfo info = new SimpleAuthenticationInfo(user,dbPassword,this.getName());
           return info;
       }else{
           return null;
       }
   }

4.2实现授权 重写doGetAuthorizationInfo方法

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
/*获的简单授权对象,用于授权的*/
  SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
    /*授权staff权限*/
    //info.addStringPermission("staff");
    //步骤获得授权对象,获得当前用户,获得当前用户的权限(若为admin即授予所有权限),当前用户授权
    //获得对象
    User user = (User)principals.getPrimaryPrincipal();
    List<Function> fList = null;
    //获得权限
    if(user.getUsername().equals("admin")){
        fList = functionDao.findAll();
    }else{
        fList = functionDao.findFunctionByUserId(user.getId());
    }
    //授予权限
    for(Function f : fList){
        info.addStringPermission(f.getCode());
}

关于Shiro中使用 encache

1.引入包
在spring配置文件中配置以下
2.配置文件ehcache.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="true"
            maxElementsOnDisk="10000000"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"
            />
</ehcache>
 <!--eternal是否永久有效-->

3.引入缓存管理器EhCacheManager(shiro包中的),并设置配置文件;
4.将缓存管理器注入安全管理器DefaultWebSecurityManager

<!--注册安全管理器-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="bosRealm"></property>
        <property name="cacheManager" ref="ehCacheManager"></property>
    </bean>
    <bean id="bosRealm" class="org.yao.bos.web.action.realm.BOSRealm"></bean>

    <!--注入缓存管理器-->
    <bean id="ehCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"></property>
    </bean>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值