zoukankan      html  css  js  c++  java
  • Shiro快速入门

    1.什么是Shiro

    Shiro是Java的一个安全框架, 完成权限控制的任务.

    权限控制的基本功能: 认证(让系统知道你是谁); 授权(让系统知道你能做什么)
    权限控制常用的技术: 过滤器/拦截器, 或者使用代理模式
    权限控制的数据模型: 权限表-(多对多)-角色表-(多对多)-用户表

    shiri的组成

    shiro的调用流程

    Application code:应用程序代码
    Subject:当前用户
    SecurityManager:安全管理器,shiro框架的核心对象,管理各个组件
    Realm:获取权限信息, 决定subject的访问权限, 可以有多个

    2.Shiro的使用

    2.1登录

    Subject subject = SecurityUtils.getSubject();  
    UsernamePasswordToken token = new UsernamePasswordToken(username, password); 
    try{
        // 注意:登录不成功以抛异常的方式通知
        subject.login(token);   
    }catch (UnknownAccountException e) {
        // 没找到用户名
    }catch (IncorrectCredentialsException e) {
        // 用户名密码不匹配
    }catch (AuthenticationException e) {
        // 其他登录错误
    }
    if (subject.isAuthenticated()) {
        // 登录成功后, 取回认证时通过签名存储的对象
        User user = (User) subject.getPrincipal();
    }

    2.2 在realm里管理用户~权限

    public class MyRealm extends AuthorizingRealm {
        
      // 登录及认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { // 获得登录用的token UsernamePasswordToken token = (UsernamePasswordToken) token; // 获得封装的username String username = token.getUsername(); User user = userDao.findByUsername(username); if (null == user) { return null; } else { // 获得真正的password String password = user.getPassword(); // 创建简单认证对象, 返回给安全管理器 // 参数一:可放入任何对象的签名, 执行subject.login()方法后可从subject.getPrincipal()取回 // 参数二:封装真正的密码, 交由安全管理器比对 // 参数三:当前realm的名称 SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, this.getClass().getSimpleName()); return info; } } // 授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { // 获得签名, 可做进一步查询 User user = (User) principals.getPrimaryPrincipal(); // 创建简单授权对象 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //授予perms["keyword"] info.addStringPermission("staff"); //授予role["keyword"] info.addRole("staff"); return info; } }

    2.3 配置及管理访问目标~权限

    2.3.1 过滤器方式:

    web.xml

      <!-- shiro过滤器, 从spring工厂拿, beanname为"shiroFilter" -->
      <filter>
          <filter-name>shiroFilter</filter-name>
          <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
      </filter>
      <filter-mapping>
          <filter-name>shiroFilter</filter-name>
          <url-pattern>/*</url-pattern>
      </filter-mapping>

    applicationContext.xml

      <!-- shiro: 自定义的realm -->
        <bean id = "userDefineRealm" class="com.zx.bos.shiro.UserDefineRealm"></bean>
        
        <!-- 二级缓存-->
        <bean id="ehCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
            <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"></property>
        </bean>
        
        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <!-- realm需注册给安全管理器 -->
            <property name="realm" ref = "userDefineRealm"></property>
            <!-- 使用ehcache二级缓存, 没必要频繁查询权限 -->
            <property name="cacheManager" ref="ehCacheManager"></property>
        </bean>
        
        
        <!-- shiro使用方式1, 对URL进行控制  -->
        <bean id = "shiroFilter" class = "org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <!-- 注入安全管理器 -->
            <property name="securityManager" ref="securityManager"></property>
            <!-- 未登录时跳转到登录页面 -->
            <property name="loginUrl" value="/login.jsp"/>
            <!-- 登录成功页面 -->
            <property name="successUrl" value="/index.jsp"/>   <!-- 登录后跳转到登陆前被拦截的页面, 不跳转至此 -->
            <!-- 权限不足提示页面 -->
            <property name="unauthorizedUrl" value="/unauthorizedUrl.jsp"/>
            <!-- URL拦截规则 -->  <!-- 有先后顺序 从上往下匹配 -->
            <property name="filterChainDefinitions">
                <value>
                    /css/** = anon
                    /images/** = anon
                    /js/** = anon
                    /login.jsp* = anon   <!-- 后面带参数 -->
                    /validatecode.jsp* = anon
              /page_base_staff.action = roles["staff"] /userAction_login.action = anon
    /* = authc </value> </property> </bean>

    anon:可以匿名使用。
    authc:需要认证(登录)才能使用
    roles:可以带参数, 参数可以多个,例如roles["admin,guest"], 表示每个参数都通过才算通过
    perms:可以带参数, 参数可以多个,perms["user:add:*,user:modify:*"]
    port:port[8081]表示当请求的url的端口不是8081时跳转到schema://serverName:8081?queryParams
    user:必须存在用户,登录操作时不做检查

    2.3.2 注解方式:

        <!-- shiro使用方式2, 使用注解对方法进行控制. 不同于url方式权限不足时跳转界面,它直接抛出异常 -->
        <!-- 代理 -->
        <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
            <property name="proxyTargetClass" value="true"></property>   <!-- 使用cglib创建代理对象,  默认false用jdk动态代理 -->
        </bean>
        <!-- 切面类 -->
        <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
            <property name="securityManager" ref="securityManager"/>  
        </bean>

    注意捕获权限不足时抛出的异常. 如果在struts里需要配置

    struts.xml

    <global-results>
        <result name="unauthorizedUrl">/unauthorizedUrl.jsp</result>
    </global-results>
    <!-- 接收异常 -->
    <global-exception-mappings>
        <exception-mapping result="unauthorizedUrl" exception="org.apache.shiro.authz.AuthorizationException"></exception-mapping>
    </global-exception-mappings>
    例如:
    @RequiresRoles("rolename");
    void someMethod();
    @RequiresPermissions({"file:read", "write:aFile.txt"});
    void someMethod();
    最后说一遍, 需要处理可能的AuthorizationException异常
     
    注解方式是在方法级别的控制,无法做类级别的控制访问。
    过滤器方式是根据访问的URL进行控制。允许使用*通配URL,所以可以进行粗粒度,也可以进行细粒度控制。
     

    2.4 在JSP页面使用shiro标签

    使用shiro标签, 根据权限过滤部分内容
     
    <shiro:authenticated>      登录之后
    <shiro:notAuthenticated> 没有登录
    <shiro:hasRole name="abc">     拥有角色abc
    <shiro:lacksRole name="abc">   没有角色abc
    <shiro:hasPermission name="abc">    拥有权限资源abc
    <shiro:lacksPermission name="abc">  没有abc权限资源
    <shiro:principal>   取回签名对象
  • 相关阅读:
    HDU 1261 字串数(排列组合)
    Codeforces 488C Fight the Monster
    HDU 1237 简单计算器
    POJ 2240 Arbitrage
    POJ 3660 Cow Contest
    POJ 1052 MPI Maelstrom
    POJ 3259 Wormholes
    POJ 3268 Silver Cow Party
    Codesforces 485D Maximum Value
    POJ 2253 Frogger(最短路)
  • 原文地址:https://www.cnblogs.com/myJavaEE/p/6677865.html
Copyright © 2011-2022 走看看