123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- package com.gxzc.zen.umps.config
- import org.apache.shiro.session.ExpiredSessionException
- import org.apache.shiro.session.InvalidSessionException
- import org.apache.shiro.session.Session
- import org.apache.shiro.session.UnknownSessionException
- import org.apache.shiro.session.mgt.DefaultSessionManager
- import org.apache.shiro.session.mgt.DelegatingSession
- import org.apache.shiro.session.mgt.SessionContext
- import org.apache.shiro.session.mgt.SessionKey
- import org.apache.shiro.web.servlet.Cookie
- import org.apache.shiro.web.servlet.ShiroHttpServletRequest
- import org.apache.shiro.web.servlet.ShiroHttpSession
- import org.apache.shiro.web.servlet.SimpleCookie
- import org.apache.shiro.web.session.mgt.WebSessionKey
- import org.apache.shiro.web.util.WebUtils
- import org.slf4j.LoggerFactory
- import java.io.Serializable
- import javax.servlet.ServletRequest
- import javax.servlet.ServletResponse
- import javax.servlet.http.HttpServletRequest
- import javax.servlet.http.HttpServletResponse
- /**
- * Copied form @link DefaultWebSessionManager
- * 解决一次登陆多次直接读取缓存的问题
- * 在读取前先读取本地缓存(目前存放于spring-session 中 attribute)
- * @author NorthLan
- * @date 2018/4/25
- * @url https://noahlan.com
- */
- @Suppress("unused")
- class ZenWebSessionManager : DefaultSessionManager {
- companion object {
- private val log = LoggerFactory.getLogger(ZenWebSessionManager::class.java)
- }
- var sessionIdCookie: Cookie? = null
- var sessionIdCookieEnabled: Boolean = false
- var sessionIdUrlRewritingEnabled: Boolean = false
- constructor() {
- val cookie = SimpleCookie(ShiroHttpSession.DEFAULT_SESSION_ID_NAME)
- cookie.isHttpOnly = true //more secure, protects against XSS attacks
- this.sessionIdCookie = cookie
- this.sessionIdCookieEnabled = true
- this.sessionIdUrlRewritingEnabled = true
- }
- private fun storeSessionId(currentId: Serializable?, request: HttpServletRequest, response: HttpServletResponse) {
- if (currentId == null) {
- val msg = "sessionId cannot be null when persisting for subsequent requests."
- throw IllegalArgumentException(msg)
- }
- val template = sessionIdCookie
- val cookie = SimpleCookie(template)
- val idString = currentId.toString()
- cookie.value = idString
- cookie.saveTo(request, response)
- log.trace("Set session ID cookie for session with id {}", idString)
- }
- private fun removeSessionIdCookie(request: HttpServletRequest, response: HttpServletResponse) {
- sessionIdCookie?.removeFrom(request, response)
- }
- private fun getSessionIdCookieValue(request: ServletRequest, response: ServletResponse): String? {
- if (!sessionIdCookieEnabled) {
- log.debug("Session ID cookie is disabled - session id will not be acquired from a request cookie.")
- return null
- }
- if (request !is HttpServletRequest) {
- log.debug("Current request is not an HttpServletRequest - cannot get session ID cookie. Returning null.")
- return null
- }
- return sessionIdCookie?.readValue(request, WebUtils.toHttp(response))
- }
- private fun getReferencedSessionId(request: ServletRequest, response: ServletResponse): Serializable? {
- var id = getSessionIdCookieValue(request, response)
- if (id != null) {
- request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,
- ShiroHttpServletRequest.COOKIE_SESSION_ID_SOURCE)
- } else {
- //not in a cookie, or cookie is disabled - try the request URI as a fallback (i.e. due to URL rewriting):
- //try the URI path segment parameters first:
- id = getUriPathSegmentParamValue(request, ShiroHttpSession.DEFAULT_SESSION_ID_NAME)
- if (id == null) {
- //not a URI path segment parameter, try the query parameters:
- val name = getSessionIdName()
- id = request.getParameter(name)
- if (id == null) {
- //try lowercase:
- id = request.getParameter(name.toLowerCase())
- }
- }
- if (id != null) {
- request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,
- ShiroHttpServletRequest.URL_SESSION_ID_SOURCE)
- }
- }
- if (id != null) {
- request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id)
- //automatically mark it valid here. If it is invalid, the
- //onUnknownSession method below will be invoked and we'll remove the attribute at that time.
- request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, java.lang.Boolean.TRUE)
- }
- // always set rewrite flag - SHIRO-361
- request.setAttribute(ShiroHttpServletRequest.SESSION_ID_URL_REWRITING_ENABLED, sessionIdUrlRewritingEnabled)
- return id
- }
- //SHIRO-351
- //also see http://cdivilly.wordpress.com/2011/04/22/java-servlets-uri-parameters/
- //since 1.2.2
- private fun getUriPathSegmentParamValue(servletRequest: ServletRequest, paramName: String): String? {
- if (servletRequest !is HttpServletRequest) {
- return null
- }
- var uri: String? = servletRequest.requestURI ?: return null
- val queryStartIndex = uri!!.indexOf('?')
- if (queryStartIndex >= 0) { //get rid of the query string
- uri = uri.substring(0, queryStartIndex)
- }
- var index = uri.indexOf(';') //now check for path segment parameters:
- if (index < 0) {
- //no path segment params - return:
- return null
- }
- //there are path segment params, let's get the last one that may exist:
- val token = "$paramName="
- uri = uri.substring(index + 1) //uri now contains only the path segment params
- //we only care about the last JSESSIONID param:
- index = uri.lastIndexOf(token)
- if (index < 0) {
- //no segment param:
- return null
- }
- uri = uri.substring(index + token.length)
- index = uri.indexOf(';') //strip off any remaining segment params:
- if (index >= 0) {
- uri = uri.substring(0, index)
- }
- return uri //what remains is the value
- }
- override fun retrieveSession(sessionKey: SessionKey): Session? {
- val sessionId = getSessionId(sessionKey)
- if (sessionId == null) {
- log.debug("Unable to resolve session ID from SessionKey [{}]. Returning null to indicate a " + "session could not be found.", sessionKey)
- return null
- }
- ////////////////////////Add by noahlan//////////////////////////////////
- var request: ServletRequest? = null
- if (sessionKey is WebSessionKey) {
- request = sessionKey.servletRequest
- }
- if (request != null) {
- val s = request.getAttribute(sessionId.toString())
- if (s != null) {
- return s as Session
- }
- }
- ////////////////////////////////////////////////////////////////////////
- val s = retrieveSessionFromDataSource(sessionId)
- if (s == null) {
- //session ID was provided, meaning one is expected to be found, but we couldn't find one:
- val msg = "Could not find session with ID [$sessionId]"
- throw UnknownSessionException(msg)
- }
- ////////////////////////Add by noahlan//////////////////////////////////
- if (request != null) {
- request.setAttribute(sessionId.toString(), s)
- }
- ///////////////////////////////////////////////////////////////////////
- return s
- }
- //since 1.2.1
- private fun getSessionIdName(): String {
- var name: String? = this.sessionIdCookie?.name
- if (name == null) {
- name = ShiroHttpSession.DEFAULT_SESSION_ID_NAME
- }
- return name
- }
- override fun createExposedSession(session: Session, context: SessionContext?): Session {
- if (!WebUtils.isWeb(context)) {
- return super.createExposedSession(session, context)
- }
- val request = WebUtils.getRequest(context)
- val response = WebUtils.getResponse(context)
- val key = WebSessionKey(session.id, request, response)
- return DelegatingSession(this, key)
- }
- override fun createExposedSession(session: Session, key: SessionKey?): Session {
- if (!WebUtils.isWeb(key)) {
- return super.createExposedSession(session, key)
- }
- val request = WebUtils.getRequest(key)
- val response = WebUtils.getResponse(key)
- val sessionKey = WebSessionKey(session.id, request, response)
- return DelegatingSession(this, sessionKey)
- }
- /**
- * Stores the Session's ID, usually as a Cookie, to associate with future requests.
- *
- * @param session the session that was just [created][.createSession].
- */
- override fun onStart(session: Session, context: SessionContext?) {
- super.onStart(session, context)
- if (!WebUtils.isHttp(context)) {
- log.debug("SessionContext argument is not HTTP compatible or does not have an HTTP request/response " + "pair. No session ID cookie will be set.")
- return
- }
- val request = WebUtils.getHttpRequest(context)
- val response = WebUtils.getHttpResponse(context)
- if (sessionIdCookieEnabled) {
- val sessionId = session.id
- storeSessionId(sessionId, request, response)
- } else {
- log.debug("Session ID cookie is disabled. No cookie has been set for new session with id {}", session!!.id)
- }
- request.removeAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE)
- request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_IS_NEW, java.lang.Boolean.TRUE)
- }
- public override fun getSessionId(key: SessionKey): Serializable? {
- var id: Serializable? = super.getSessionId(key)
- if (id == null && WebUtils.isWeb(key)) {
- val request = WebUtils.getRequest(key)
- val response = WebUtils.getResponse(key)
- id = getSessionId(request, response)
- }
- return id
- }
- protected fun getSessionId(request: ServletRequest, response: ServletResponse): Serializable? {
- return getReferencedSessionId(request, response)
- }
- override fun onExpiration(s: Session, ese: ExpiredSessionException?, key: SessionKey?) {
- super.onExpiration(s, ese, key)
- onInvalidation(key)
- }
- override fun onInvalidation(session: Session, ise: InvalidSessionException, key: SessionKey) {
- super.onInvalidation(session, ise, key)
- onInvalidation(key)
- }
- private fun onInvalidation(key: SessionKey?) {
- val request = WebUtils.getRequest(key)
- request?.removeAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID)
- if (WebUtils.isHttp(key)) {
- log.debug("Referenced session was invalid. Removing session ID cookie.")
- removeSessionIdCookie(WebUtils.getHttpRequest(key), WebUtils.getHttpResponse(key))
- } else {
- log.debug("SessionKey argument is not HTTP compatible or does not have an HTTP request/response " + "pair. Session ID cookie will not be removed due to invalidated session.")
- }
- }
- override fun onStop(session: Session, key: SessionKey?) {
- super.onStop(session, key)
- if (WebUtils.isHttp(key)) {
- val request = WebUtils.getHttpRequest(key)
- val response = WebUtils.getHttpResponse(key)
- log.debug("Session has been stopped (subject logout or explicit stop). Removing session ID cookie.")
- removeSessionIdCookie(request, response)
- } else {
- log.debug("SessionKey argument is not HTTP compatible or does not have an HTTP request/response " + "pair. Session ID cookie will not be removed due to stopped session.")
- }
- }
- /**
- * This is a native session manager implementation, so this method returns `false` always.
- *
- * @return `false` always
- * @since 1.2
- */
- fun isServletContainerSessions(): Boolean {
- return false
- }
- }
|