天天看点

Spring mvc + MyBatis 整合Shiro

1.web.xml中配置

<!-- Shiro Filter -->  
    <filter>  
        <filter-name>shiroFilter</filter-name>  
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
        <init-param>  
            <param-name>targetFilterLifecycle</param-name>  
            <param-value>true</param-value>  
        </init-param>  
    </filter>  
    <filter-mapping>  
        <filter-name>shiroFilter</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping> 
           

当然是放在最前面

2.applicationContext.xml配置

<!-- <a href="http://lib.csdn.net/base/14" target="_blank" rel="external nofollow"  class="replace_word" title="MySQL知识库" 
    target="_blank" style="color:#df3434; font-weight:bold;">数据库</a>保存的密码是使用MD5算法加密的,所以这里需要配置一个密码匹配对象 -->
<bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.Md5CredentialsMatcher"></bean>

<!-- 缓存管理 -->
<bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager"></bean>

<!-- 使用Shiro自带的JdbcRealm类
 指定密码匹配所需要用到的加密对象 
 指定存储用户、角色、权限许可的数据源及相关查询语句 -->
<bean id="jdbcRealm" class="org.apache.shiro.realm.jdbc.JdbcRealm">
    <!--<property name="credentialsMatcher" ref="credentialsMatcher"></property>-->
    <property name="permissionsLookupEnabled" value="true"></property>
    <property name="dataSource" ref="dataSource"></property>
    <property name="authenticationQuery"
        value="SELECT password FROM users WHERE username = ?"></property>

</bean>

<!-- Shiro安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="realm" ref="jdbcRealm"></property>
    <property name="cacheManager" ref="cacheManager"></property>
</bean>

<!-- Shiro主过滤器本身功能十分强大,其强大之处就在于它支持任何基于URL路径表达式的、自定义的过滤器的执行 Web应用中,Shiro可控制的Web请求必须经过Shiro主过滤器的拦截,Shiro对基于Spring的Web应用提供了完美的支持 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <!-- Shiro的核心安全接口,这个属性是必须的 -->
    <property name="securityManager" ref="securityManager"></property>
    <!-- 要求登录时的链接(登录页面地址),非必须的属性,默认会自动寻找Web工程根目录下的"/login.jsp"页面 -->
    <property name="loginUrl" value="/jsp/index"></property>
    <!-- 登录成功后要跳转的连接(本例中此属性用不到,因为登录成功后的处理逻辑在LoginController里硬编码) -->
    <!-- <property name="successUrl" value="/" ></property> -->
    <!-- 用户访问未对其授权的资源时,所显示的连接 -->
    <property name="unauthorizedUrl" value="/"></property>

    <property name="filterChainDefinitions">
        <value>
            /security/*=anon
            /tag=authc
        </value>
    </property>
</bean>
           

3.Controller

@RequestMapping(value = "/dologin")
    public String doLogin(HttpServletRequest request, Model model) {
        String msg = "";
        String userName = request.getParameter("userName");
        String password = request.getParameter("password");
        System.out.println("userName"+userName);
        System.out.println("password"+password);
        // Shiro

        /**
         * 第一步:收集用户身份和证明
         */
        System.out.println("第一步:收集用户身份和证明");
        UsernamePasswordToken token = new UsernamePasswordToken(userName,password);// 创建用户名/密码身份验证Token(即用户身份/凭证)
        token.setRememberMe(true);
        System.out.println("第一步:收集用户身份和证明结束");
        /**
         * 第二步:提交身份和证明
         */
        System.out.println("第二步:提交身份和证明");
        Subject subject = SecurityUtils.getSubject(); // 得到Subject
        System.out.println("第二步:提交身份和证明2222");
        try {
            subject.login(token);// 进行身份验证 ---》调用配置中的sql语句进行验证
            System.out.println("第二步:提交身份和证明结束");
            /**
             * 第三步:处理成功或失败
             */

            if (subject.isAuthenticated()) {
                return "service";
            } else {
                return "index";
            }
        } catch (IncorrectCredentialsException e) {
            msg = "登录密码错误. Password for account " + token.getPrincipal()
                    + " was incorrect.";
            model.addAttribute("message", msg);
            System.out.println(msg);
        } catch (ExcessiveAttemptsException e) {
            msg = "登录失败次数过多";
            model.addAttribute("message", msg);
            System.out.println(msg);
        } catch (LockedAccountException e) {
            msg = "帐号已被锁定. The account for username " + token.getPrincipal()
                    + " was locked.";
            model.addAttribute("message", msg);
            System.out.println(msg);
        } catch (DisabledAccountException e) {
            msg = "帐号已被禁用. The account for username " + token.getPrincipal()
                    + " was disabled.";
            model.addAttribute("message", msg);
            System.out.println(msg);
        } catch (ExpiredCredentialsException e) {
            msg = "帐号已过期. the account for username " + token.getPrincipal()
                    + "  was expired.";
            model.addAttribute("message", msg);
            System.out.println(msg);
        } catch (UnknownAccountException e) {
            msg = "帐号不存在. There is no user with username of "
                    + token.getPrincipal();
            model.addAttribute("message", msg);
            System.out.println(msg);
        } catch (UnauthorizedException e) {
            msg = "您没有得到相应的授权!" + e.getMessage();
            model.addAttribute("message", msg);
            System.out.println(msg);
        }
        return "index";
    }
           

4.总结

1.提交的数据用UsernamePasswordToken进行封装

2.使用得到的subject对象进行验证处理

3.验证处理在applicationContext.xml进行配置,也可以新建类进行操作。

参考博客:http://www.cnblogs.com/xql4j/

项目源码:http://pan.baidu.com/s/1qYBtvnm