zoukankan      html  css  js  c++  java
  • shiro使用教程

    一、shiro是什么

    Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码学和会话管理。不仅可以在Web项目中使用,在普通的项目中也是可以使用的

    二、shiro可以做什么

    shiro可以进行细粒度地权限控制,包括对方法,对链接,对页面显示进行权限控制。

    三、在Web项目中使用shiro进行权限管理

    1、  在web.xml中添加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>
            <dispatcher>REQUEST</dispatcher>
        </filter-mapping>

    2、  spring-mvc.xml中添加shiro的权限注解支持

    <aop:config proxy-target-class="true"></aop:config>
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
             <property name="securityManager" ref="securityManager"/>
    </bean>

    3、  使用spring对ehcache进行缓存管理

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:cache="http://www.springframework.org/schema/cache"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="
           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
        <!-- 支持缓存注解 -->
        <cache:annotation-driven cache-manager="ehcacheManager" />
     
        <!--ehcache-->
        <bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
            <property name="configLocation" value="classpath:ehcache.xml"/>
        </bean>
     
        <bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
            <property name="cacheManager" ref="cacheManagerFactory"/>
        </bean>
    </beans>
    

      

    4、  使用ehcache进行缓存管理

    在ehcache中添加如下缓存块

        <diskStore path="java.io.tmpdir"/>
        <cache name="authorizationCache"
               maxEntriesLocalHeap="2000"
               eternal="false"
               timeToIdleSeconds="3600"
               timeToLiveSeconds="0"
               overflowToDisk="false"
               statistics="true">
        </cache>
     
        <cache name="authenticationCache"
               maxEntriesLocalHeap="2000"
               eternal="false"
               timeToIdleSeconds="3600"
               timeToLiveSeconds="0"
               overflowToDisk="false"
               statistics="true">
        </cache>
    
        <cache name="shiro-activeSessionCache"
               maxEntriesLocalHeap="2000"
               eternal="false"
               timeToIdleSeconds="3600"
               timeToLiveSeconds="0"
               overflowToDisk="false"
               statistics="true">
        </cache>

    5、实现CacheManager的接口,对shiro权限使用spring进行缓存管理

    public class SpringCacheManagerWrapper implements CacheManager {
        private org.springframework.cache.CacheManager cacheManager;
    
        /**
         * 设置spring cache manager
         *
         * @param cacheManager
         */
        public void setCacheManager(org.springframework.cache.CacheManager cacheManager) {
            this.cacheManager = cacheManager;
        }
     
        @Override
        public <K, V> Cache<K, V> getCache(String name) throws CacheException {
            org.springframework.cache.Cache springCache = cacheManager.getCache(name);
            return new SpringCacheWrapper(springCache);
        }
    
        static class SpringCacheWrapper implements Cache {
            private org.springframework.cache.Cache springCache;
            SpringCacheWrapper(org.springframework.cache.Cache springCache) {
                this.springCache = springCache;
            }
    
            @Override
            public Object get(Object key) throws CacheException {
                Object value = springCache.get(key);
                if (value instanceof SimpleValueWrapper) {
                    return ((SimpleValueWrapper) value).get();
                }
                return value;
            }
    
            @Override
            public Object put(Object key, Object value) throws CacheException {
                springCache.put(key, value);
                return value;
            }
     
            @Override
            public Object remove(Object key) throws CacheException {
                springCache.evict(key);
                return null;
            }
    
            @Override
            public void clear() throws CacheException {
                springCache.clear();
            }
     
            @Override
            public int size() {
                if(springCache.getNativeCache() instanceof Ehcache) {
                    Ehcache ehcache = (Ehcache) springCache.getNativeCache();
                    return ehcache.getSize();
                }
    
                throw new UnsupportedOperationException("invoke spring cache abstract size method not supported");
            }
     
            @Override
            public Set keys() {
                if(springCache.getNativeCache() instanceof Ehcache) {
                    Ehcache ehcache = (Ehcache) springCache.getNativeCache();
                    return new HashSet(ehcache.getKeys());
                }
                throw new UnsupportedOperationException("invoke spring cache abstract keys method not supported");
            }
     
            @Override
            public Collection values() {
                if(springCache.getNativeCache() instanceof Ehcache) {
                    Ehcache ehcache = (Ehcache) springCache.getNativeCache();
                    List keys = ehcache.getKeys();
                    if (!CollectionUtils.isEmpty(keys)) {
                        List values = new ArrayList(keys.size());
                        for (Object key : keys) {
                            Object value = get(key);
                            if (value != null) {
                                values.add(value);
                            }
                        }
                        return Collections.unmodifiableList(values);
                    } else {
                        return Collections.emptyList();
                    }
                }
                throw new UnsupportedOperationException("invoke spring cache abstract values method not supported");
            }
        }
    }

    6、自定义放在session中的实体

    public class CustomPrincipal implements Serializable {
        private Integer id;
        private String username;
    
        public CustomPrincipal(String username) {
            this.username = username;
        }
     
        public CustomPrincipal(int id, String username) {
            this.id = id;
            this.username = username;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
     
        /**
         * 本函数输出将作为默认的<shiro:principal/>输出.
         */
        @Override
        public String toString() {
            return username;
        }
    } 

    7、重写realm

    public class AdministratorRealm extends AuthorizingRealm {
        private AdministratorService administratorService;
        public AdministratorService getAdministratorService() {
            return administratorService;
        }
     
        public void setAdministratorService(AdministratorService administratorService) {
            this.administratorService = administratorService;
        } 
    
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            CustomPrincipal customPrincipal = (CustomPrincipal)principals.getPrimaryPrincipal();
            String username = customPrincipal.getUsername();
            SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
            Set<String> roles = administratorService.getRoles(username);
            roles.add(UserConstants.ADMINISTRATOR_STR);
            authorizationInfo.setRoles(roles); 
            authorizationInfo.setStringPermissions(administratorService.getPermissions(username));
            return authorizationInfo;
        }
    
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
            String username = (String)usernamePasswordToken.getPrincipal();
            Administrator administrator = administratorService.getAdministrator(username);
            if (administrator == null) {
                throw new UnknownAccountException();//没找到帐号
            }
     
            if (Boolean.FALSE.equals(administrator.getAdmiStatus())) {
                throw new LockedAccountException(); //帐号锁定
            } 
            CustomPrincipal principal = new CustomPrincipal(administrator.getAdmiId(), administrator.getAdmiAccount());
            //交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配,如果觉得人家的不好可以自定义实现
            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                    principal, //用户名
                    administrator.getAdmiPassword(), //密码
                    ByteSource.Util.bytes(administrator.getCredentialsSalt()),//salt=username+salt
                    getName()  //realm name
            );
            return authenticationInfo;
        }
     
        @Override
        public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
            super.clearCachedAuthorizationInfo(principals);
        }
     
        @Override
        public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
            super.clearCachedAuthenticationInfo(principals);
        }
     
        @Override
        public void clearCache(PrincipalCollection principals) {
            super.clearCache(principals);
        }
    
        public void clearAllCachedAuthorizationInfo() {
            getAuthorizationCache().clear();
        }
    
        public void clearAllCachedAuthenticationInfo() {
            getAuthenticationCache().clear();
        }
    
        public void clearAllCache() {
            clearAllCachedAuthenticationInfo();
            clearAllCachedAuthorizationInfo();
        }
    }
    

      

    8、spring-shiro.xml实例化类

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:util="http://www.springframework.org/schema/util"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="
           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
    
           <aop:config proxy-target-class="true"></aop:config>
    
           <!-- 缓存管理器 -->
           <bean id="cacheManager" class="com.misuosi.mshop.shiro.cache.SpringCacheManagerWrapper">
                  <property name="cacheManager" ref="ehcacheManager"/>
           </bean>
    
           <!-- 凭证匹配器 -->
           <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                  <property name="hashAlgorithmName" value="md5"/>
                  <property name="hashIterations" value="2"/>
                  <property name="storedCredentialsHexEncoded" value="true"/>
           </bean>
    
           <!-- Realm实现 -->
           <bean id="administratorRealm" class="com.misuosi.mshop.shiro.realm.AdministratorRealm">
                  <property name="administratorService" ref="administratorService"/>
                  <property name="credentialsMatcher" ref="credentialsMatcher"/>
                  <property name="cachingEnabled" value="false"/>
                  <property name="authenticationCachingEnabled" value="true"/>
                  <property name="authenticationCacheName" value="authenticationCache"/>
                  <property name="authorizationCachingEnabled" value="true"/>
                  <property name="authorizationCacheName" value="authorizationCache"/>
           </bean>
     
           <!-- 会话ID生成器 -->
           <bean id="sessionIdGenerator" class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator"/>
    
           <!-- 会话Cookie模板 -->
           <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
                  <constructor-arg value="sid"/>
                  <property name="httpOnly" value="true"/>
                  <property name="maxAge" value="-1"/>
           </bean>
     
           <!-- 会话DAO -->
           <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
                  <property name="activeSessionsCacheName" value="shiro-activeSessionCache"/>
                  <property name="sessionIdGenerator" ref="sessionIdGenerator"/>
           </bean>
     
           <!-- 会话验证调度器 -->
           <bean id="sessionValidationScheduler" class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler">
                  <property name="sessionValidationInterval" value="1800000"/>
                  <property name="sessionManager" ref="sessionManager"/>
           </bean>
     
           <!-- 会话管理器 -->
           <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
                  <property name="globalSessionTimeout" value="1800000"/>
                  <property name="deleteInvalidSessions" value="true"/>
                  <property name="sessionValidationSchedulerEnabled" value="true"/>
                  <property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>
                  <property name="sessionDAO" ref="sessionDAO"/>
                  <property name="sessionIdCookieEnabled" value="true"/>
                  <property name="sessionIdCookie" ref="sessionIdCookie"/>
           </bean>
    
           <!-- 安全管理器 -->
           <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
                  <property name="realm" ref="administratorRealm"/>
                  <property name="sessionManager" ref="sessionManager"/>
                  <property name="cacheManager" ref="cacheManager"/>
           </bean>
    
           <!-- 相当于调用SecurityUtils.setSecurityManager(securityManager) -->
           <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
                  <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/>
                  <property name="arguments" ref="securityManager"/>
           </bean>
     
           <!-- 基于Form表单的身份验证过滤器 -->
           <bean id="formAuthenticationFilter" class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter">
                  <property name="successUrl" value="/admin/index"/>
                  <property name="loginUrl" value="/admin/login"/>
           </bean>
     
           <bean id="adminLogoutFilter" class="org.apache.shiro.web.filter.authc.LogoutFilter">
                  <property name="redirectUrl" value="/admin/login"/>
           </bean>
     
           <!-- Shiro的Web过滤器 -->
           <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
                  <property name="securityManager" ref="securityManager"/>
                  <property name="filters">
                         <util:map>
                                <entry key="adminAuthc" value-ref="formAuthenticationFilter"/>
                                <entry key="adminLogout" value-ref="adminLogoutFilter"/>
                         </util:map>
                  </property>
                  <property name="filterChainDefinitions">
                         <value>
                                /admin/login = adminAuthc
                                /admin/logout = adminLogout
                                /admin/** = adminAuthc,roles[admin]
                         </value>
                  </property>
           </bean>
     
           <!-- Shiro生命周期处理器-->
           <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
    </beans>  

    9、freemarker使用shiro的标签

    把标签的实现贴到freemarker.tag的包中,在freemarker的配置中添加freemarker标签。

    public class ShiroTagFreeMarkerConfigurer extends FreeMarkerConfigurer {
        @Override
        public void afterPropertiesSet() throws IOException, TemplateException {
            super.afterPropertiesSet();
            this.getConfiguration().setSharedVariable("shiro", new ShiroTags());
        }
    }

    10、完成

  • 相关阅读:
    ThinkPHP框架知识(比较全的知识)
    利用smarty模板(登录、有关信息操作等功能)
    从零开始学习Node.js例子七 发送HTTP客户端请求并显示响应结果
    从零开始学习Node.js例子六 EventEmitter发送和接收事件
    从零开始学习Node.js例子五 服务器监听
    从零开始学习Node.js例子四 多页面实现数学运算 续二(client端和server端)
    从零开始学习Node.js例子四 多页面实现数学运算 续一(使用connect和express框架)
    从零开始学习Node.js例子四 多页面实现数学运算
    从零开始学习Node.js例子三 图片上传和显示
    从零开始学习Node.js例子二 文本提交与显示
  • 原文地址:https://www.cnblogs.com/yingbing/p/4643089.html
Copyright © 2011-2022 走看看