web集成shiro(2)

Q:shiro对spring-session的设置是如何操作到redis的?

A:

假如我们对shiro的session做如下操作,最终key -> val会保存到redis中
Subject subject = SecurityUtils.getSubject();
Session userSession = subject.getSession();
userSession.setAttribute("key", "val");

在shiro中是如何实现的呢?

SecurityManager里面会持有一个SessionManager,配置如下:

@Bean
public SecurityManager securityManager() {
        //  默认设置了一个sessionManager
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
         。。。。。。

        SecurityUtils.setSecurityManager(securityManager);
        return securityManager;
 }



配置使用DefaultWebSecurityManager,构造方法为:

public DefaultWebSecurityManager() {
        ((DefaultSubjectDAO)this.subjectDAO).setSessionStorageEvaluator(new DefaultWebSessionStorageEvaluator());
        this.sessionMode = "http";
        this.setSubjectFactory(new DefaultWebSubjectFactory());
        this.setRememberMeManager(new CookieRememberMeManager());
        // sessionManager实现session的管理
        this.setSessionManager(new ServletContainerSessionManager());
}

默认使用的是ServletContainerSessionManager()

ServletContainerSessionManager -> WebSessionManager -> SessionManager

SessionManager接口要求ServletContainerSessionManager 实现类实现启动session和获取session接口

public interface SessionManager {
    Session start(SessionContext var1);

    Session getSession(SessionKey var1) throws SessionException;
}

实现如下:

public Session getSession(SessionKey key) throws SessionException {
        if (!WebUtils.isHttp(key)) {
          。。。。。。
        } else {
            // 获取servlet容器请求
            HttpServletRequest request = WebUtils.getHttpRequest(key);
            Session session = null;
            // 获取容器的session
            HttpSession httpSession = request.getSession(false);
            if (httpSession != null) {
                session = this.createSession(httpSession, request.getRemoteHost());
            }

            return session;
        }
    }

// 将Servlet的Session包装成shiro的Session并且返回
// 推断出对shiroSession的操作,最终会影操作到servletSession上

protected Session createSession(HttpSession httpSession, String host) {
        return new HttpServletSession(httpSession, host);
}

客户端对subject.getSession()获取到的shiroSession做的操作,最终会变成httpSession;
最终在SpringSessionRepositoryFilter类 -> doFilterInternal方法 -> wrappedRequest.commitSession() 中,把session更新到了redis中(参考:https://blog.csdn.net/ShuaiFanPi/article/details/78337159)



 

 

 

 

你可能感兴趣的:(java)