shiro的一点记录

由于项目的需要,最近开始研究shiro这个框架。shiro是一个安全框架,主要是验证和授权管理,和它类似的有spring security框架,当然,spring security框架更加强大,但是shiro更加灵活(一般小的东西都比较灵活)。

对于shiro,网上的资料可谓是少之又少。基本上算是被开涛大魔王的一个《跟我学shiro》垄断,当然这个教程是很全面,楼主也是跟着这个教程一点点学的(没办法,没有别的资料啊,很多看不懂的地方没地方找啊,shiro官网的英文看不懂啊卧槽)。虽然过程很痛苦,还好最近对这个框架基本上了解了一些,所以现在敢记录记录。

这里就不从头开始介绍什么ini配置了,一般都是集成在spring项目里面的,使用maven进行项目管理,这一章先简单的写点基础配置吧。代码是学习的时候写的,还有待修改的地方,不过学习足够了。

  1. shiro实际上算是一个拦截器,当然得在web.xml中配置:

     <!-- 配置shiro的核心拦截器 -->
        <filter>
            <filter-name>shiroFilter</filter-name>
            <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>shiroFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping> 
  2. 对于一个验证和授权框架,我们当然得自己写自己的验证和授权方法。这两个方法在一个叫Realm的类中,要我们自己来写:
    @Component
    public class UserRealm extends AuthorizingRealm {
    
        @Autowired
        private IUserService userService;
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            String username= (String) principalCollection.getPrimaryPrincipal();
            User user=userService.findByUsername(username);
            //System.out.println("授权"+user);
            if (user!=null)
            {
                SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
                // System.out.println(userService.findRole(username));
                info.addRole(userService.findRole(username));
                info.addStringPermission(userService.findPermissions(username));
                // System.out.println(info);
                return info;
            }
            else  throw new IncorrectCredentialsException();
        }
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
            String username= (String) authenticationToken.getPrincipal();
            String password=new String((char[])authenticationToken.getCredentials());
            User user=userService.findByUsername(username);
            System.out.println(user);
            if(user!=null)
            {
                if(password.equals(user.getPassword())){
    
                    Session session= SecurityUtils.getSubject().getSession();
                    session.setAttribute("username",user.getUsername());
                    return new SimpleAuthenticationInfo(username,password,getName());
                }
                else throw new UnknownAccountException();
    
            }
            else
            {
                throw new UnknownAccountException();
            }
    
        }
  3. 大家都知道spring的尿性,你用它,就得在他的配置文件里创建相应的bean。shiro也不例外,要在他的配置文件里面创建跟web.xml中你配置的拦截器名字一样的bean。

    分几个小步吧:

    1)最重要的你要有一个shiroFilter的bean

     <!--配置shiroFilter-->
        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager"/>
            <!-- 登录路径-->
            <property name="loginUrl" value="/jsp/login.jsp"/>
            <!--登录成功路径-->
            <property name="successUrl" value="/jsp/loginSuccess.jsp"/>
            <!--授权失败路径-->
            <property name="unauthorizedUrl" value="/jsp/unauthorized.jsp"/>
            <property name="filters">
                <util:map>
                    <entry key="authc" value-ref="formAuthenticationFilter"/>
                    <entry key="stateless" value-ref="statelessFilter"/>
                    <!--<entry key="ssl" value-ref="sslFilter"/>-->
                </util:map>
            </property>
            <!--过滤链定义-->
            <property name="filterChainDefinitions">
                <value>
                    /jsp/login.jsp=anon
                    /jsp/loginSuccess.jsp=authc
                    /jsp/logout.jsp=logout
                    /jsp/success.jsp=user
                    /static/**=anon
                    /hello**=stateless
                </value>
            </property>
        </bean>

2)它还得需要一个叫安全管理器的东东:

    <!--配置securityManager-->
     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="userRealm"/>
    </bean>

3)安全管理器需要一个Realm的东东,就是刚才自己写的那个,配置上就可以了:

     <!--Realm实现-->
    <bean id="userRealm" class="com.pps.sps.realm.UserRealm" >
    </bean>

4)shiro的生命周期管理器,人家都加了,我不加也不好看:

   <!-- Shiro生命周期处理器-->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

倘若需要使用注解,在springMVC的配置文件中引入这个配置文件,加上注解的配置就可以了:

    <!--使用shiro注解-->
    <import resource="spring-shiro.xml"/>
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
        <property name="proxyTargetClass" value="true"></property>
    </bean>
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"></property>
    </bean>

嗯,这样一个最基本的shiro框架就集成到spring的web项目中去了,这里没有使用缓存,没有使用会话管理,没有用到SSL。。。反正就是啥高级都没有,就一个简单的框架,但是基本上就可以拦截你的信息了。OK,今天先写到这吧,回头再写。

时间: 2024-10-11 01:51:15

shiro的一点记录的相关文章

shiro的一点记录(三)

shiro的无状态web集成.所谓无状态就是服务器端无状态,就是不保存会话.一般的会话机制的web应用,都是session机制来保存用户状态.无状态的web应用就是每次请求都带上相应的用户名进行登录. 具体的实践就是:客户端传入秘钥和一个消息作为输入,他们声称相应消息摘要,秘钥是只有客户端和服务端知道的.访问的时候服务端对消息摘要进行验证. 具体的实例如下: 首先我们创建subject的工厂必须是不保存session的: public class StatelessDefaultSubjectF

shiro的一点记录(二)

这次主要写shiro的exception定制,RememberMe和SSL. Exception页面定制 不知道这个属不属于shiro自身的范畴,反正这里用到了,就写上吧,主要是这些Exception都是shiro里面的,所以就在这里写上吧.根据资料显示,要定制错误页面,需要在springMVC配置文件里面配置相应的控制器异常处理.例如: <!--控制器异常处理 --> <bean id="exceptionHandlerExceptionResolver" clas

lodop打印控件一点记录

今天初步接触了下打印控件 LODOP实现了自动分页,高度宽度都可以自己设定来分页. 页码,使用LODOP.SET_PRINT_STYLE("ItemType", 2); LODOP.ADD_PRINT_TEXT(0,0,"95%",30,"总页号:第#页/共&页"); 让每个分页都显示页码/总页数,#当前页,$总页数. 每页页眉页脚.使用LODOP.SET_PRINT_STYLE("ItemType", 1); 来让其

对Integer类中的私有IntegerCache缓存类的一点记录

对Integer类中的私有IntegerCache缓存类的一点记录 // Integer类有内部缓存,存贮着-128 到 127. // 所以,每个使用这些数字的变量都指向同一个缓存数据 // 因此可以直接使用 == 来比较是否相等 Integer a = 88; Integer b = 88; System.out.println(a == b); // true // 下面这个不在Integer缓存类里的数字,在每次赋值的时候都会新建一个对象存放 // 所以,它们不能使用 == 来判断是否相

关于db2的一点记录

近期听搞db2的兄弟说:db2数据库软件的license 不区分平台(os). 先记下来.像db2这么高大上的软件,接触的机会是比較少的. 另外:db2 的license是须要打的,不打的话,超过一段时间.db2是无法启动的.这一点不像oracle db software,oracle db software 是没有不论什么技术上的限制.你愿意用oracle db software ,用上1万年.随便你.仅仅要别让oracle公司盯上你即可. 而一般的商业软件,都是有技术上的限制的.比方:浪潮E

Apache Shiro Realm 学习记录1

最近几天在学习Apache Shiro......看了一些大神们的教程.....感觉收获不少.....但是毕竟教程也只是指引一下方向....即使是精辟教程,仍然有很多东西都没有说明....所以自己也稍微研究了一下...记录了一下我的研究发现....教程点这里 这篇教程的最后提到了自己去写Realm.....然后给出了4个方法.....但是并没有怎么详细说明.....我想说说我的理解.....(我的理解可能会有很多错误) 我想先说说登陆验证的大致流程....大致...... 从用户那里收集完用户名

zabbix的一点记录

zabbix的性能瓶颈主要是磁盘IO(数据库读写操作),对CPU和内存的占用较低. 对于单个监控值 zabbix 在 后台数据库中会存入三个数值(最大值.最小值.平均值). 计算历史数据的大小.zabbix的数据一般是有存放期限的,如几个星期或几个月.这里假如存放30天,那么就有30*24*3600=2592000秒.假如目前监控30台机器,每台机器监控20个item,item的上报频率为30秒,那么每秒就有30*20/30=20个数据上报,一般一个上报数据的大小在40-100bytes之间,这

lua 中关于时间戳和可读时间格式的一点记录

lua 标准库中提供了关于时间的函数os.time()和os.date(),这两个函数使用起来还是有需要注意的地方的:这两个函数的结果都是加入了时区:比如我现在系统是GMT+8; os.time({year=1970, month=1, day=1, hour=0})计算出来的是-28800,也就是86060:计算的是当前table中给定的时间距离1970.1.1 08:00时间的秒数,所以就得到负数了: C标准库中,time()函数得到的时间戳其实也是加入了时区,也就是说不管你系统是那个时区,

Nodejs Promise的一点记录

项目需要,看了点nodejs,其中比较难理解的就是Promise了,记录一下学习bluebird提供的Promise实现. Promise.promisifyAll(obj)方法 作用:把对象的方法属性变成异步方法,会在函数加上后缀Async. 看下面的代码: var Promise = require('bluebird') var obj = { func1: function () { return 'hehe' }, func2: function () { return 'xix' }