


An example analysis of Session session = getSession() in shiro's source code learning
subject represents some operations for users to access the server: such as logging in, logging out, viewing roles/permissions,
At the same time, the session can be obtained, such as: subject.getSession(), this connection, if it does not exist before session, create a session. The creation process is roughly as follows:
subject entrusts SecurityManager to create, SecurityManager entrusts SessionManager to create, and SessionManager is created through SessionFactory factory. It can be seen that the division of labor in the creation process of Shiro is clear.
The creation process is analyzed as follows.
(1)Session can be obtained in the DelegatingSubject class:
public Session getSession(boolean create) { ....... SessionContext sessionContext = createSessionContext(); //创建Session上下文,context有个backMap,存放创建Session时所需的数据 Session session = this.securityManager.start(sessionContext); this.session = decorate(session);//创建代理session,当session.stop()调用时,清空subject的session ....... return this.session;//返回代理session }
(2)SecurityManager entrusts sessionManager(DefaultSessionManage) to handle the creation of Session:
1 public Session start(SessionContext context) throws AuthorizationException { 2 return this.sessionManager.start(context); 3 }
*Note: DefaultSessionManage The internal structure is:
(3)AbstractNativeSessionManager creates Session and manages Session:
public Session start(SessionContext context) { Session session = createSession(context);//通过模板模式,子类实现通过上下仍创建Session applyGlobalSessionTimeout(session);//更新sessionDAO的sessions(map<String,session>) onStart(session, context);//一个槽点,待子类实现 notifyStart(session);//注册的监听器开始执行 //Don't expose the EIS-tier Session object to the client-tier: return createExposedSession(session, context);//创建暴露的Session }
(4)The creation of Session is completed, and the detailed code is as follows : AbstractNativeSessionManager is handed over to AbstractValidatingSessionManager for processing:
protected Session createSession(SessionContext context) throws AuthorizationException { enableSessionValidationIfNecessary(); //创建Session之前,先起一个Session自动定时任务的线程去执行,校验sessionDAO的sessions是否过期。 return doCreateSession(context); } // private void enableSessionValidationIfNecessary() { SessionValidationScheduler scheduler = getSessionValidationScheduler(); if (isSessionValidationSchedulerEnabled() && (scheduler == null || !scheduler.isEnabled())) { enableSessionValidation(); } } // protected void enableSessionValidation() { SessionValidationScheduler scheduler = getSessionValidationScheduler(); if (scheduler == null) { scheduler = createSessionValidationScheduler(); //scheduler = new ExecutorServiceSessionValidationScheduler(this);scheduler.setInterval(getSessionValidationInterval()); setSessionValidationScheduler(scheduler); } if (log.isInfoEnabled()) { log.info("Enabling session validation scheduler..."); } scheduler.enableSessionValidation();//自动任务启动执行 afterSessionValidationEnabled();//一个槽点,待子类实现 }
(5)ExecutorServiceSessionValidationScheduler verifies the expiration of the Session:
/** * Creates a single thread {@link ScheduledExecutorService} to validate sessions at fixed intervals * and enables this scheduler. The executor is created as a daemon thread to allow JVM to shut down */ //TODO Implement an integration test to test for jvm exit as part of the standalone example // (so we don't have to change the unit test execution model for the core module) public void enableSessionValidation() { if (this.interval > 0l) { this.service = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() { public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setDaemon(true); return thread; } }); this.service.scheduleAtFixedRate(this, interval, interval, TimeUnit.MILLISECONDS); this.enabled = true; } } public void run() { if (log.isDebugEnabled()) { log.debug("Executing session validation..."); } long startTime = System.currentTimeMillis(); this.sessionManager.validateSessions();//ExecutorServiceSessionValidationSchedule的在被SessionManager创建里, long stopTime = System.currentTimeMillis(); if (log.isDebugEnabled()) { log.debug("Session validation completed successfully in " + (stopTime - startTime) + " milliseconds."); } }
(6)AbstractValidatingSessionManager verifies the expiration of the Session:
/** * @see ValidatingSessionManager#validateSessions() */ public void validateSessions() { if (log.isInfoEnabled()) { log.info("Validating all active sessions..."); } int invalidCount = 0; Collection<Session> activeSessions = getActiveSessions();//获取取保存的Session if (activeSessions != null && !activeSessions.isEmpty()) { for (Session s : activeSessions) { try { //simulate a lookup key to satisfy the method signature. //this could probably stand to be cleaned up in future versions: SessionKey key = new DefaultSessionKey(s.getId()); validate(s, key); } catch (InvalidSessionException e) { if (log.isDebugEnabled()) { boolean expired = (e instanceof ExpiredSessionException); String msg = "Invalidated session with id [" + s.getId() + "]" + (expired ? " (expired)" : " (stopped)"); log.debug(msg); } invalidCount++; } } } if (log.isInfoEnabled()) { String msg = "Finished session validation."; if (invalidCount > 0) { msg += " [" + invalidCount + "] sessions were stopped."; } else { msg += " No sessions were stopped."; } log.info(msg); } } //类DefaultSessionManager实现getActiveSessions接口 protected abstract Collection<Session> getActiveSessions(); protected Collection<Session> getActiveSessions() { Collection<Session> active = sessionDAO.getActiveSessions(); return active != null ? active : Collections.<Session>emptySet(); }
(7)Session The verification is completed, and then DefaultSessionManager creates the Session:
protected Session doCreateSession(SessionContext context) { Session s = newSessionInstance(context); if (log.isTraceEnabled()) { log.trace("Creating session for host {}", s.getHost()); } create(s); return s; } protected Session newSessionInstance(SessionContext context) { return getSessionFactory().createSession(context); } protected void create(Session session) { if (log.isDebugEnabled()) { log.debug("Creating new EIS record for new session instance [" + session + "]"); } sessionDAO.create(session); }
(8) DefaultSessionManager entrusts Session (MemorySessionDAO) to maintain the Session:
protected Serializable doCreate(Session session) { Serializable sessionId = generateSessionId(session); assignSessionId(session, sessionId); storeSession(sessionId, session); return sessionId; } protected Session storeSession(Serializable id, Session session) { if (id == null) { throw new NullPointerException("id argument cannot be null."); } return sessions.putIfAbsent(id, session); }
(9) After creating and maintaining the Session, AbstractNativeSessionManager Hand it over to the registered listener, and the listener calls the onStart interface
protected void notifyStart(Session session) { 2 for (SessionListener listener : this.listeners) { 3 listener.onStart(session); 4 } 5 }
(10) Finally, creates the delegate Session,
protected Session createExposedSession(Session session, SessionContext context) { return new DelegatingSession(this, new DefaultSessionKey(session.getId())); }
(11) Finally, the Subject creates its own proxy Session, which is mainly used Interception stop method:
protected Session decorate(Session session) { if (session == null) { throw new IllegalArgumentException("session cannot be null"); } return new StoppingAwareProxiedSession(session, this); } private class StoppingAwareProxiedSession extends ProxiedSession { private final DelegatingSubject owner; private StoppingAwareProxiedSession(Session target, DelegatingSubject owningSubject) { super(target); owner = owningSubject; } 16 public void stop() throws InvalidSessionException { super.stop(); owner.sessionStopped(); } }
Summary: When Session (SimpleSession) is created in DefaultSessionManage, it is encapsulated in DelegatingSession, and is decorated as a proxy session (StoppingAwareProxiedSession) in the subject. The original data is well preserved. The client cannot modify the original Session
...
The above is the detailed content of An example analysis of Session session = getSession() in shiro's source code learning. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

The problem was found in the springboot project production session-out timeout. The problem is described below: In the test environment, the session-out was configured by changing the application.yaml. After setting different times to verify that the session-out configuration took effect, the expiration time was directly set to 8 hours for release. Arrived in production environment. However, I received feedback from customers at noon that the project expiration time was set to be short. If no operation is performed for half an hour, the session will expire and require repeated logins. Solve the problem of handling the development environment: the springboot project has built-in Tomcat, so the session-out configured in application.yaml in the project is effective. Production environment: Production environment release is

Solution to the problem that the php session disappears after refreshing: 1. Open the session through "session_start();"; 2. Write all public configurations in a php file; 3. The variable name cannot be the same as the array subscript; 4. In Just check the storage path of the session data in phpinfo and check whether the sessio in the file directory is saved successfully.

Session failure is usually caused by the session lifetime expiration or server shutdown. The solutions: 1. Extend the lifetime of the session; 2. Use persistent storage; 3. Use cookies; 4. Update the session asynchronously; 5. Use session management middleware.

Solution to the cross-domain problem of PHPSession In the development of front-end and back-end separation, cross-domain requests have become the norm. When dealing with cross-domain issues, we usually involve the use and management of sessions. However, due to browser origin policy restrictions, sessions cannot be shared by default across domains. In order to solve this problem, we need to use some techniques and methods to achieve cross-domain sharing of sessions. 1. The most common use of cookies to share sessions across domains

The default expiration time of session PHP is 1440 seconds, which is 24 minutes, which means that if the client does not refresh for more than 24 minutes, the current session will expire; if the user closes the browser, the session will end and the Session will no longer exist.

Problem: Today, we encountered a setting timeout problem in our project, and changes to SpringBoot2’s application.properties never took effect. Solution: The server.* properties are used to control the embedded container used by SpringBoot. SpringBoot will create an instance of the servlet container using one of the ServletWebServerFactory instances. These classes use server.* properties to configure the controlled servlet container (tomcat, jetty, etc.). When the application is deployed as a war file to a Tomcat instance, the server.* properties do not apply. They do not apply,

1. Implementing SMS login based on session 1.1 SMS login flow chart 1.2 Implementing sending SMS verification code Front-end request description: Description of request method POST request path /user/code request parameter phone (phone number) return value No back-end interface implementation: @Slf4j@ ServicepublicclassUserServiceImplextendsServiceImplimplementsIUserService{@OverridepublicResultsendCode(Stringphone,HttpSessionsession){//1. Verify mobile phone number if

JavaScriptCookies Using JavaScript cookies is the most effective way to remember and track preferences, purchases, commissions and other information. Information needed for a better visitor experience or website statistics. PHPCookieCookies are text files that are stored on client computers and retained for tracking purposes. PHP transparently supports HTTP cookies. How do JavaScript cookies work? Your server sends some data to your visitor's browser in the form of a cookie. Browsers can accept cookies. If present, it will be stored on the visitor's hard drive as a plain text record. Now, when a visitor reaches another page on the site
