shiro的初步使用

shiro的集成之spring(附:推荐springboot 集成shiro网址)

参考网上的代码和公司生产集成案例

三个依赖包

shiro的核心包  shiro和spring整合 shiro的缓存支持  
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.2.4</version>
</dependency>
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.2.4</version>
</dependency>
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-ehcache</artifactId>
    <version>1.2.4</version>
</dependency>

 好了,引入shiro依赖包,我们就可以开始构建一个shiro的安全框架了.

一个web项目,在web.xml中加入shiro过滤器的代理

 <!--Shiro过滤器-->
    <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>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>

两个好处:

一: spring容器来管理filter的生命周期

二:通过spring注入的形式,来代理一个filter执行  

此处主要作用就是代理filter  就是下面我们要讲的shiroFilter

重点来了:

  shiro主要需要我们配置的有三个 

SecurityManager(DefaultWebSecurityManager)  AuthorizingRealm(继承AuthorizingRealm)  CacheManager(EhCacheManager)  还有一个shiroFilter(ShiroFilterFactoryBean)

他们之间的关系是这样的  

                                                      shiroFilter(ShiroFilterFactoryBean)

               DefaultWebSecurityManager(安全管理器 核心)     

     realm(继承AuthorizingRealm)                 CacheManager(EhCacheManager)

 

首先谈一下自定义Realm 继承AuthorizingRealm

    重点在于重写两个方法对身份信息(用户名密码) 授权信息(用户权限)验证进行验证

 

AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException{
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
用户提交用户名和密码,token可以获取. 封装令牌 通过用户名将密码查询返回,shiro自动比较查询出密码和用户输入密码是否一致.
此处我们可以根据用户名从数据库查询出账号信息做判断,最后一步
// 认证缓存信息
return new SimpleAuthenticationInfo(User, User.getPassword().toCharArray(),
getName());
}
AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals)
User user = (User) principals.getPrimaryPrincipal();

此处主要存储用户的权限,并存储
info.addStringPermissions(permissions);


接下来CacheManager 用户授权信息Cache, 采用EhCache 也可以采用redis
<bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml"/>
</bean>
<?xml version="1.0" encoding="UTF-8"?>
<ehcache updateCheck="false" name="shiroCache">

    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="600"
            timeToLiveSeconds="600"
            overflowToDisk="false"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            />
</ehcache>
安全管理器我们采用默认的就可以,当然也可以自定义
 <!--安全管理器-->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <!--设置自定义Realm-->
        <property name="realm" ref="shiroDbRealm"/>
        <!--将缓存管理器,交给安全管理器-->
        <property name="cacheManager" ref="shiroEhcacheManager"/>
    </bean>

 

还有最后一步

shiroFilter   这个filter就是代理的filter

我们需要把安全管理器引用进去,设置我们的所需要配置的地址路径,里面的filter可以配置多个filter   filte需要继承AccessControlFilter
重写isAccessAllowed onAccessDenied
public class MykFilter extends AccessControlFilter {

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response,
                                      Object mappedValue) throws Exception {
        Subject subject = getSubject(request, response);
        String url = getPathWithinApplication(request);
        if (url != null && url.endsWith("/")) {
            // 截去url最后一个/
            url = url.substring(0, url.length() - 1);
        }
        return subject.isAuthenticated() && subject.isPermitted(url);
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request,
                                     ServletResponse response) throws Exception {
        HttpServletResponse resp = (HttpServletResponse) response;
        HttpServletRequest req = (HttpServletRequest) request;
        Subject subject = getSubject(request, response);
        // 如果没有登录,去登录页
        if (!subject.isAuthenticated()) {
          
        } else {
            // 如果已登录,提示没有权限
          
        }
        return false;
    }

}

 



 <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!-- 安全管理器 -->
        <property name="securityManager" ref="securityManager"/>
        <!-- 默认的登陆访问url -->
        <property name="loginUrl" value="/login.html"/>
        <!-- 登陆成功后跳转的url -->
        <property name="successUrl" value="/index.html"/>
        <!-- 没有权限跳转的url -->
        <property name="unauthorizedUrl" value="/admin/unauth.html"/>
        <property name="filters">
            <map>
                <entry key="authc" value-ref="MyFilter"/>
            </map>
        </property>
        <property name="filterChainDefinitions">
            <value>
                /admin/index/pvStatistics = anon
                /** = authc <!-- 需要认证 -->
            </value>
        </property>
    </bean>

 

   <!-- 在方法中 注入  securityManager ,进行代理控制 -->
    <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/>
        <property name="arguments" ref="securityManager"/>
    </bean>

    <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

    <!-- AOP式方法级权限检查  -->
    <!-- <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
          depends-on="lifecycleBeanPostProcessor"/> -->

    <!-- 启用shrio授权注解拦截方式 -->
    <!-- <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"/>
    </bean> -->

 Ehcache缓存配置  当然我们也可以集成redis的缓存

<?xml version="1.0" encoding="UTF-8"?>
<ehcache updateCheck="false" name="shiroCache">

    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="600"
            timeToLiveSeconds="600"
            overflowToDisk="false"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            />
</ehcache>
前台使用shiro的标签的时候,需要引入标签库
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
或者我们直接把源码中的标签直接拷贝到我们的项目中shiro-root-1.2.6\web\src\main\java\org\apache\shiro\web\tags下的标签全部拷贝过来

这样 前端就可以使用
<@shiro.hasPermission name="/aaa/ccc">
新增按钮
</@shiro.hasPermission>
 来控制显示和隐藏了.

分享的可能有所不足,欢迎指正!如果遇到问题欢迎随时联系,互相交流.
附上官网快车: http://shiro.apache.org/
附上一个不错的springboot 集成shiro网址: https://gitee.com/yadong.zhang/shiro
 

 

 

 

                            

            

 

  

 

 

 

 

 

 

 

 

 

 
posted @ 2019-09-02 18:48  蚂蚁style  阅读(211)  评论(0)    收藏  举报