shiro2

最近看到网上有其他文章讲述shiro比较齐全,记录一下跟我一起学shiro

Session Management

shiro可以为单机应用到集群应用提供会话管理。
shiro可以在任意应用中使用,不论是不是WEB应用,也不管容器是什么。
使用shiro的会话支持 ,主要是shiro有如下特性:

  1. 基于POJO/J2SE(IOC友好) 所有内容都基于接口,并与POJO一起实现。可以轻松使用SpringXML、JSON或YAML进行配置;
  2. 轻松定义session的存储 这意味着你可以把缓存信息存放在网络分布式缓存、文件系统、关系型数据库或专有的数据存储中;
  3. 不同的客户端访问 可以在不同的客户端之间进行共享缓存;
  4. 事件监听 在session的生命周期中监听周期事件;
  5. 保留主机ip地址 有助于确定用户的位置,并作出相应的反映;
  6. 可以工作touch()延长session;
  7. 透明地使用WEB应用的session;
  8. 可以使用到SSO 因为session可以存放在数据库中,并通过应用共享;并且它用于登录,因为通过session可以保持登录状态。

使用Sessions

	Subject currentUser = SecurityUtils.getSubject();
	Session session = currentUser.getSession();
	session.setAttribute("someKey",someVame);

使用方式和HttpServletRequset API一样;
另外Subject.getSession(boolean create)HttpServletRequest.getSession(boolean create)的结构也是一样的.
如果已经有session,忽略传的参数.
如果没有session,如果create是true,创建session并返回;如果create是false,将不会创建,返回null;

上述方法可以应用于所有程序,甚至不是web程序.

The SessionManager

像其他的shiro框架组件组件,sessionManager需要被定义在SecurityManager内,作为最高等级的组件;
可以通过getter和setter方法注入到SecurityManager中并使用.
SessionManager开箱即用的实现不需要我们做什么,并且它高度可定制.

SessionTimeout

默认的过期时间是30分钟.我们可以设置globalSessionTimeout自定义过期时间.时间的单位是毫秒而不是秒.

Session 监听

Shiro支持SessionListener,对重要的sessin时间做出反应。我们可以实现SessionListener接口或者继承SessionListenerAdapter来实现监听.
需要配置在SessionManager的sessionListeners属性上.该属性是一个集合.
SessionListeners只会被特定的session通知,不会被所有的session通知.

Session Storage(会话的存储)

SessionDao用来反映数据存储的设计模型,需要设置在SessionManager中;
SessionDao不用自己去定义,我们可以使用shiro定义好的.
web应用下默认情况下sessionManager是servlet默认的session manager,不支持存储sessionDao.如果我们需要使用sessionDao,需要先定义SessionManager;

EHCache SessionDao

EHCache默认是不使用的,如果你不计划自己定义SessionDao,建议使用EHCaChe.支持把session存放在磁盘而不是内存中.
引入shiro-ehcache-<version>.jar
默认的使用一个Shiro的一个特定的ehcache.xml;

Custom Session IDs

Shio的SessionDao使用内部的SessionIdGenerator接口的组件,为session生成Sessionid,默认的是JavaUUUidSessionIdGenerator;
如果不能满足需求,可以实现SessionIdGenerator接口,并配置在SessionDao中.

Session Validation & Scheduling

session需要被验证,如果过期则从存储中删除.当使用subject.getSession()时,shiro将会去验证.
这意味着,如果不给一个定期的验证,session就不会删除.
因此SessionManager支持SessionValidationScheduler的概念,它负责周期地去验证,以便清理.

Default SessionValidationScheduler

默认的SessionValidationSchedulerExecutorServiceSessionValidationScheduler,它使用JDK的ScheduledExecutorService去控制验证.每一小时验证一次.你可以重新创建一个ExecutorServiceSessionValidationScheduler实例去改变它,单位是毫秒.

Custom SessionValidationScheduler

你可以自定义一个SessionValidationScheduler,并配置给SessionDao.

Disabling Session Validation

如果不使用Shiro的验证.例如你使用shiro外部的验证.
需要设置SessionDaosessionValidationSchedulerEnabled属性为false;
如果关闭,则必须保证周期验证.

Invalid Session Deletion

默认情况下,删除session是shiro进行删除的.如果要禁用的话,可以设置SessionManager.deleteInvalidSessions = false.但这时你要负责自己删除session;

配置文件

	 <property name="sessionManager">
        <bean class="com.qunar.lfz.shiro.MySessionManager">
            <!--默认自动检查session过期,删除过期session-->
            <property name="globalSessionTimeout" value="1800000"/>
            <property name="sessionValidationInterval" value="1800000"/>
            <!--默认MemorySessionDao-->
            <property name="sessionDAO">
                <!--默认使用javaUuidGenerator-->
                <bean class="com.qunar.lfz.shiro.MyRedisSessionDao"/>
            </property>
			<!-- 因为shiro生成的cookieid是JSESSIONID,此处是修改一下默认值 -->
            <property name="sessionIdCookie">
                <bean class="org.apache.shiro.web.servlet.SimpleCookie">
                    <constructor-arg value="shiroCookie"/>
                </bean>
            </property>
            <!--避免url中出现jsessionid // 去掉shiro登录时url里的JSESSIONID-->
            <property name="sessionIdUrlRewritingEnabled" value="false"/>
            <!--默认使用ExecutorServiceSessionValidationScheduler,AbstractValidatingSessionManager:209-->
        </bean>
    </property>

定义sessionDao

	public class MyRedisSessionDao extends AbstractSessionDAO{
    //redis中session过期时间
    private static final int SESSION_EXPIRE = 60 * 30;
    @Resource
    private RedisClient client;


    @Override
    protected Serializable doCreate(Session session) {
        Serializable sessionId = generateSessionId(session);
        assignSessionId(session,sessionId);
        byte[] keyByte = RedisKey.getKeyByte(RedisKey.SESSION_PRE, sessionId.toString());
        byte[] sessionByte = SerializationUtils.serialize(session);
        client.setEx(keyByte, sessionByte, SESSION_EXPIRE);
        return sessionId;
    }

    @Override
    protected Session doReadSession(Serializable sessionId) {
        if (sessionId == null) {
            return null;
        }
        byte[] keyByte = RedisKey.getKeyByte(RedisKey.SESSION_PRE, sessionId.toString());
        byte[] sessionByte = client.get(keyByte);
        return (Session) SerializationUtils.deserialize(sessionByte);
    }

    @Override
    public void update(Session session) throws UnknownSessionException {
        byte[] keyByte = RedisKey.getKeyByte(RedisKey.SESSION_PRE, session.getId().toString());
        byte[] sessionByte = SerializationUtils.serialize(session);
        client.setEx(keyByte, sessionByte, SESSION_EXPIRE);
    }

    @Override
    public void delete(Session session) {
        byte[] keyByte = RedisKey.getKeyByte(RedisKey.SESSION_PRE, session.getId().toString());
        client.delete(keyByte);
    }

    @Override
    public Collection<Session> getActiveSessions() {
        Set<byte[]> keyByteSet = client.keys((RedisKey.SESSION_PRE + "*").getBytes());
        Set<Session> sessionSet = Sets.newHashSet();
        for (byte[] keyByte : keyByteSet) {
            byte[] sessionByte = client.get(keyByte);
            Session session = (Session) SerializationUtils.deserialize(sessionByte);
            if (session != null) {
                sessionSet.add(session);
            }
        }
        return sessionSet;
    }
}

定义remember me

	<property name="rememberMeManager">
        <bean class="org.apache.shiro.web.mgt.CookieRememberMeManager">
            <property name="cookie">
                <bean class="org.apache.shiro.web.servlet.SimpleCookie">
                    <constructor-arg value="rememberMe"/>
                    <property name="maxAge" value="1800"/>
                </bean>
            </property>
        </bean>
    </property>

使用注解

	<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"/>
    </bean>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值