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");

    操作结果如图所示:

    其他情况可自行测试。

  • 相关阅读:
    loj#6433. 「PKUSC2018」最大前缀和(状压dp)
    PKUWC2019游记
    10. Regular Expression Matching
    9. Palindrome Number
    8. String to Integer (atoi)
    7. Reverse Integer
    6. ZigZag Conversion
    5. Longest Palindromic Substring
    4. Median of Two Sorted Arrays
    3. Longest Substring Without Repeating Characters
  • 原文地址:https://www.cnblogs.com/super-chao/p/7891583.html
Copyright © 2011-2022 走看看