zoukankan      html  css  js  c++  java
  • shiro框架的使用

    基于ssm框架:

    1.引入shiro相关jar包:

    shiro-core-1.2.3.jar

    shiro-ehcache-1.2.3.jar

    shiro-quartz-1.2.3.jar

    shiro-spring-1.2.3.jar

    shiro-web-1.2.3.jar

    2.配置applicationContext-shiro.xml(/WEB-INF/conf/applicationContext-shiro.xml):

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:p="http://www.springframework.org/schema/p"
           xsi:schemaLocation="
           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
    
        <description>apache shiro配置</description>
    
        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager"/>
           <!--  <property name="loginUrl" value="/index2.jsp"/>
            <property name="successUrl" value="/main/main.htm"/>
            <property name="unauthorizedUrl" value="/page/401.htm"/> -->
            <property name="filterChainDefinitions">
                <value>
                    <!-- 静态资源允许访问 -->
                    <!-- /** = anon -->
                    <!-- /app/** = anon
                    /assets/** = anon -->
                    <!-- 登录页允许访问 -->
                   <!--  /user/login.htm = anon -->
                    
                    /test111/loginAdmin.html=anon
                    <!-- 其他资源需要认证 -->
                    /** = authc
                </value>
            </property>
        </bean>
    
        <!-- 缓存管理器 使用Ehcache实现 -->
        <!-- 
        <bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager" p:cacheManagerConfigFile="/WEB-INF/conf/ehcache-shiro.xml">
        </bean>
         -->
        <!-- 会话DAO -->
        <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.MemorySessionDAO"/>
    
        <!-- 会话管理器 -->
        <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
            <property name="sessionDAO" ref="sessionDAO"/>
        </bean>
    
        <!-- 安全管理器 -->
        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <property name="realms">
                <list>
                    <ref bean="securityRealm"/>
                </list>
            </property>
            <!-- cacheManager,集合spring缓存工厂 -->
            <!-- <property name="cacheManager" ref="shiroEhcacheManager" /> -->
            <!-- <property name="sessionManager" ref="sessionManager" /> -->
        </bean>
    
        <!-- Shiro生命周期处理器 -->
        <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
    
    </beans>

    3.配置缓存文件:ehcache-shiro.xml(/WEB-INF/conf/ehcache-shiro.xml)

    <ehcache updateCheck="false" name="shiroCache">
    
        <defaultCache
                maxElementsInMemory="10000"
                eternal="false"
                timeToIdleSeconds="120"
                timeToLiveSeconds="120"
                overflowToDisk="false"
                diskPersistent="false"
                diskExpiryThreadIntervalSeconds="120"
                />
    </ehcache>

    4.web.xml配置shiro:

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
                /WEB-INF/conf/applicationContext.xml
                /WEB-INF/conf/applicationContext-shiro.xml
                classpath*:applicationContext.xml
            </param-value>
      </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
    
    <!-- shiro 安全过滤器 -->
        <filter>
            <filter-name>shiroFilter</filter-name>
            <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
            <async-supported>true</async-supported>
            <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>

    5.java代码:
    建立applicationContext-shiro.xml中引用到的类securityRealm:

    package com.test.www.web.security;
    
    import java.util.HashSet;
    import java.util.Set;
    
    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.stereotype.Component;
    
    import com.test.www.web.entity.user.User;
    
    /**
     * 用户身份验证,授权 Realm 组件
     * 
     **/
    @Component(value = "securityRealm")
    public class SecurityRealm extends AuthorizingRealm {
        /**
         * 权限检查
         */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            /*SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
            String username = String.valueOf(principals.getPrimaryPrincipal());
    
            System.out.println("ssssssss");*/
            //String username = principals.getPrimaryPrincipal().toString() ;
            SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo() ;
            /*Set<String> roleName = t_userService.findRoles(username) ;
            Set<String> permissions = t_userService.findPermissions(username) ;*/
            //角色集合
            Set<String> roleName = new HashSet<String>(); 
            //权限集合
            Set<String> permissions = new HashSet<String>();
            roleName.add("admin");
            permissions.add("pub:coursecategory");
            authorizationInfo.setRoles(roleName);
            authorizationInfo.setStringPermissions(permissions);
    
            return authorizationInfo;
        }
    
        /**
         * 登录验证
         */
        @SuppressWarnings("unused")
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
           /* String username = String.valueOf(token.getPrincipal());
            String password = new String((char[]) token.getCredentials());
            System.out.println("aaaaaaa");
            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, password, getName());*/
    //        int i = 1/0;
            
            //获取用户账号
            User user = new User() ;
            user.setUsername("aa");
            user.setPassword("bb");
            if (user != null){
                //将查询到的用户账号和密码存放到 authenticationInfo用于后面的权限判断。第三个参数传入realName。
                AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(),"a") ;
                return authenticationInfo ;
            }else{
                return  null ;
            }
        }
    
    }

    PermissionSign常量类:

    package com.test.www.web.security;
    
    /**
     * 权限标识配置类, <br>
     * 与 permission 权限表 中的 permission_sign 字段 相对应 <br>
     * 使用:
     * 
     * <pre>
     * &#064;RequiresPermissions(value = PermissionConfig.USER_CREATE)
     * public String create() {
     *     return &quot;拥有user:create权限,能访问&quot;;
     * }
     * </pre>
     * 
     **/
    public class PermissionSign {
        //课程类别表权限
        public static final String PUB_COURSECATEGORY = "pub:coursecategory";
    
    }

    TestController类:

    package com.test.www.web.controller;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.annotation.Resource;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.authz.annotation.RequiresPermissions;
    import org.apache.shiro.subject.Subject;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.ModelMap;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import com.test.www.test.exception.TestException;
    import com.test.www.util.PrimaryKeyGenerator;
    import com.test.www.web.entity.user.User;
    import com.test.www.web.security.PermissionSign;
    import com.test.www.web.service.user.UserService;
    
    @RequestMapping("/test111")
    @Controller
    public class TestController {
        private final static Logger logger = LoggerFactory.getLogger(TestException.class);
        @Resource
        private UserService userService;
        
        /**
         * 注意:
         * 1.如果不是ajax提交表单,权限认证异常跳转到web.xml中配置的路径;
         * 2.如果是ajax请求,权限认证异常不是按照web.xml跳转
         */
        @RequestMapping("/add")
        @ResponseBody
        @RequiresPermissions(value=PermissionSign.PUB_COURSECATEGORY) //PUB_TRAININGTYPE PUB_COURSECATEGORY 增加权限控制
        public Map<String,Object> saveUser(
                User user,
                ModelMap map, HttpServletResponse response,
                HttpServletRequest request
                ){
            Map<String,Object> resultMap = new HashMap<String,Object>();
            try{
                
                user.setId(PrimaryKeyGenerator.getLongKey());
                int resultCount = userService.insertUser(user);
                
                if(resultCount>0){
                    resultMap.put("msg", "success");
                    resultMap.put("user", user);
                }
    
            }catch(Exception e){
                e.printStackTrace();
                resultMap.put("msg", "failure"); 
            }
            return resultMap;
        }
        
        @RequestMapping("/loginAdmin")
        public String login(){
            User user = new User();
            user.setUsername("aa");
            user.setPassword("bb");
            Subject subject = SecurityUtils.getSubject() ;
            UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),user.getPassword()) ;
            logger.info("登录成功1");
            logger.info("--info--");
            logger.debug("--debug--");
            logger.error("-error-");
            logger.warn("--warn--");
            System.out.println(System.getProperty("test2.root"));
            System.out.println(System.getProperty("Academic.root"));
            try {
                subject.login(token);
                return "index2" ;
            }catch (Exception e){
                //这里将异常打印关闭是因为如果登录失败的话会自动抛异常
    //            e.printStackTrace();
                
                return "index" ;
            }
        }
    
    
    }

    说明:

    1.登录验证:

       login()方法进行登录验证,subject.login(token);是验证核心,执行到这一步会进入SecurityRealm执行doGetAuthenticationInfo进行登录验证。

    2.采用注解控制权限:

       执行saveUser方法操作,由于方法上面添加了权限注解@RequiresPermissions(value=PermissionSign.PUB_COURSECATEGORY),

       执行该操作会先进入到SecurityRealm的doGetAuthorizationInfo方法中获取用户的角色、权限并进行权限检查,只有拥有该权限的用户才能执行该操作,没有该权限则会转向未授权页面。

       去掉该注解,则不进行权限检查,不执行SecurityRealm的doGetAuthorizationInfo方法,所有用户都能执行该操作。

    操作结果如图所示:

    1.用户名密码都正确,用户拥有权限pub:coursecategory:

    2.用户名密码正确,用户没有操作权限:

    将doGetAuthorizationInfo中的permissions.add("pub:coursecategory");改为permissions.add("pub:coursecategory1");

    操作结果如图所示:

    其他情况可自行测试。

  • 相关阅读:
    20
    19下
    19上
    18下
    20145218 《Java程序设计》第五周学习总结
    20145218 《Java程序设计》第四周学习总结
    20145218 《Java程序设计》第三周学习总结
    20145218 《Java程序设计》第二周学习总结
    20145218《Java程序设计》第一周学习总结
    问卷调查
  • 原文地址:https://www.cnblogs.com/super-chao/p/7891583.html
Copyright © 2011-2022 走看看