shiro安全框架的使用

来源:互联网 发布:nvh有限元软件 编辑:程序博客网 时间:2024/05/01 14:41

Shiro的使用

在WEB.XML中配置:shiro核心控制器 DelegatingFilterProxy

applicationContext.xml 事务管理声明之前配置:开启cglib动态代理方式

配置shiro的配置文件:基于spring

Shiro配置文件:

 

         description>Shiro的配置</description>

  

   <!-- SecurityManager配置 -->

   <!-- 配置Realm -->

   <!-- 密码比较器 -->

   <!-- 代理如何生成?用工厂来生成Shiro的相关过滤器-->

   <!-- 配置缓存:ehcache缓存 -->

   <!-- 安全管理 -->

    <beanid="securityManager"class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">

        <!--Single realm app.  If you have multiplerealms, use the 'realms' property instead. -->

        <propertyname="realm"ref="authRealm"/><!--引用自定义的realm -->

        <!-- 缓存 -->

        <propertyname="cacheManager"ref="shiroEhcacheManager"/>

    </bean>

 

    <!-- 自定义权限认证 -->

    <beanid="authRealm"class="cn.itcast.jk.shiro.AuthRealm[a1] ">

      <propertyname="userService"ref="userService"/>

      <!-- 自定义密码加密算法 -->

      <propertyname="credentialsMatcher"ref="passwordMatcher"/>

   </bean>

  

   <!-- 设置密码加密策略 md5hash -->

   <beanid="passwordMatcher"class="cn.itcast.jk.shiro.CustomCredentialsMatcher[a2] "/>

 

    <!-- filter-name这个名字的值来自于web.xmlfilter的名字 -->

    <beanid="shiroFilter"class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">

        <propertyname="securityManager"ref="securityManager"/>

        <!--登录页面 -->

        <propertyname="loginUrl"value="/index.jsp"></property>

        <!-- 登录成功后 -->     

        <propertyname="successUrl"value="/home.action"></property>

        <propertyname="filterChainDefinitions">

            <!-- /**代表下面的多级目录也过滤 -->

            <value>

            /index.jsp* = anon

            /home* = anon

            /sysadmin/login/login.jsp* = anon

            /sysadmin/login/logout.jsp* = anon

            /login* = anon

            /logout* = anon

            /components/** = anon

            /css/** = anon

            /images/** = anon

            /js/** = anon

            /make/** = anon

            /skin/** = anon

            /stat/** = anon

            /ufiles/** = anon

            /validator/** = anon

            /resource/** = anon

            /** = authc

            /*.* = authc

            </value>

        </property>

    </bean>

 

    <!-- 用户授权/认证信息Cache,采用EhCache 缓存 -->

    <beanid="shiroEhcacheManager"class="org.apache.shiro.cache.ehcache.EhCacheManager">

        <propertyname="cacheManagerConfigFile"value="classpath:ehcache-shiro.xml[a3] "/>

    </bean>

 

    <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->

    <beanid="lifecycleBeanPostProcessor"class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

 

    <!-- 生成代理,通过代理进行控制 -->

    <beanclass="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"

          depends-on="lifecycleBeanPostProcessor">

        <propertyname="proxyTargetClass"value="true"/>

    </bean>

   

    <!-- 安全管理器 -->

    <beanclass="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">

        <propertyname="securityManager"ref="securityManager"/>

    </bean>

 


 

授权&管理 类

public class AuthRealm extends AuthorizingRealm{

   private UserServiceuserService;

   public voidsetUserService(UserService userService) {

      this.userService =userService;

   }

   /**

    * 授权

    */

   @Override

   protectedAuthorizationInfo doGetAuthorizationInfo(PrincipalCollectionpc) {

      User user = (User)pc.fromRealm(this.getName()).iterator().next();[a4] 

      //获取对象导航

      Set<Role> roles = user.getRoles();

      List<String> permissions =newArrayList<String>();

      for(Rolerole:roles){

         //遍历角色得到每个角色下的模块列表

         Set<Module> modules =role.getModules();

         //将模块名放入permissions

         for (Modulemodule : modules) {

            permissions.add(module.getName());

         }

  

         SimpleAuthorizationInfo info =newSimpleAuthorizationInfo();

         info.addStringPermissions(permissions);

         returninfo;

      }

     

      return null;

   }

   /**

    * 认证

    */

   @Override

   protectedAuthenticationInfo doGetAuthenticationInfo(AuthenticationTokentoken[a5] )throwsAuthenticationException {

     

      UsernamePasswordToken upToken = (UsernamePasswordToken)token;[a6] 

     

      //查询用户

      String hql = "fromUser where userName=?";

      List<User> list = userService.find(hql, User.class,new String[]{upToken.getUsername()});

     

      //判断用户是否存在

      if(list!=null &&list.size()>0){

         //获取用户名

         User user = list.get(0);

      //核心API

         SimpleAuthenticationInfoinfo =newSimpleAuthenticationInfo(user,user.getPassword(),

this.getName()[a7] );[a8] 

         returninfo;//进入密码比较器

      }

      return null;

   }

 

密码比较器:

  public classCustomCredentialsMatcher extendsSimpleCredentialsMatcher{

    //密码比较

    public booleandoCredentialsMatch(AuthenticationTokentoken,AuthenticationInfo info[a9] [a10] ){

        UsernamePasswordToken upToken =(UsernamePasswordToken)token;

        //将用户在界面输入的原始密码加密

        Object pwd = Encrypt.md5(new String(upToken.getPassword())[a11] ,upToken.getUsername()[a12] );[a13] 

        //获取数据库中加密的密码

        Object dbPwd = info.getCredentials();

        return this.equals(pwd,dbPwd);//进行密码比较

    }

}

 

 

Action中的方法:

 

try {

            Subject subject =SecurityUtils.getSubject();[a14] 

            //调用登录方法

            UsernamePasswordToken tokan =newUsernamePasswordToken(username,password);

            subject.login(tokan);//当这一代码执行时,就会自动跳入到AuthRealm中认证方法

            //登录成功时,shiro中取出用户的登录信息

            User user = (User)subject.getPrincipal();

        } catch (Exceptione) {

            e.printStackTrace();

            request.put("errorInfo","用户名或密码错误");

            return"login";

        }

 


 

执行过程:

 

 

 


 [a1]自定义认证&权限路径

 [a2]自定义的密码比较器

 [a3]缓存的配置文件

 [a4]获取user对象

 [a5]存放用户名和密码

 [a6]把接口强制转换成它的实现类

 [a7]可为任意字符串,与授权中pc.fromRealm(this.getName()).iterator().next();中的this.getName()一致

 [a8]将用户,用户名,认证名称传入SimpleAuthenticationInfo中

 [a9]来自授权&认证的数据

 [a10]AuthRealm类 info对象穿过来的参数;token 是user对象,info是客户端传来的密码

 [a11]客户端传来的密码

 [a12]Salt 是一个任意的字符串,加密的一个参数

 [a13]调用工具类给密码加密

 [a14]获取subject对象

0 0
原创粉丝点击