Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/* Copyright 2019 predic8 GmbH, www.predic8.com
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
package com.predic8.membrane.core.interceptor.session;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.predic8.membrane.annot.MCAttribute;
import com.predic8.membrane.core.Router;
import com.predic8.membrane.core.exchange.Exchange;
import com.predic8.membrane.core.http.Header;
import com.predic8.membrane.core.http.HeaderField;
import com.predic8.membrane.core.http.HeaderName;
import com.predic8.membrane.core.http.Response;
import com.predic8.membrane.core.rules.RuleKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.Duration;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public abstract class SessionManager {
public static final String SESSION_VALUE_SEPARATOR = ",";
public static final String VALUE_TO_EXPIRE_SESSION_IN_BROWSER = "Expires=Thu, 01 Jan 1970 00:00:00 GMT";
Logger log = LoggerFactory.getLogger(SessionManager.class);
public static final String SESSION = "SESSION";
public static final String SESSION_COOKIE_ORIGINAL = "SESSION_COOKIE_ORIGINAL";
protected String usernameKeyName = "username";
long expiresAfterSeconds = 15 * 60;
String domain;
boolean httpOnly = false;
String sameSite = null;
String issuer;
protected boolean ttlExpiryRefreshOnAccess = true;
protected boolean secure = false;
protected boolean sessionCookie = false;
Cache cookieExpireCache = CacheBuilder.newBuilder()
.maximumSize(10000)
.expireAfterWrite(Duration.ofSeconds(10))
.build();
private void initIssuer(Exchange exc) {
String xForwardedProto = exc.getRequest().getHeader().getFirstValue(Header.X_FORWARDED_PROTO);
boolean isHTTPS = xForwardedProto != null ? "https".equals(xForwardedProto) : exc.getRule().getSslInboundContext() != null;
issuer = (isHTTPS ? "https://" : "http://") + exc.getOriginalHostHeader();
RuleKey key = exc.getRule().getKey();
if (!key.isPathRegExp() && key.getPath() != null)
issuer += key.getPath();
normalizePublicURL();
}
private void normalizePublicURL() {
if(!issuer.endsWith("/"))
issuer += "/";
}
public abstract void init(Router router) throws Exception;
/**
* Transforms a cookie value into its attributes. The cookie should be assumed valid as @isValidCookieForThisSessionManager was called beforehand
*
* @param cookie
* @return
*/
protected abstract Map cookieValueToAttributes(String cookie);
/**
* Get the String identifier of the sessions to be used as cookie value.
*
* @param session
* @return
*/
protected abstract Map getCookieValues(Session... session);
/**
* Get all cookies String representations from the request that are not valid anymore, e.g. because the cookie is a self contained value and has changed or expired (e.g. jwt).
* Should return cookie values in the form of key=value.
*
* @param exc
* @param validCookie is the cookie value representation of the currently active session. Is key=value
* @return
*/
public abstract List getInvalidCookies(Exchange exc, String validCookie);
/**
* Gets called for every cookie value. Returns if the cookie value is valid and managed by this manager instance, e.g. jwt session manager checks if the cookie is a jwt, if it has the correct issuer, if it is not expired and if the signature is valid.
* Cookie is in format key=value
* @param cookie
* @return
*/
protected abstract boolean isValidCookieForThisSessionManager(String cookie);
/**
* Gets called when session was not modified. Should check, if session needs to be renewed (e.g. jwt expiration).
* @param originalCookie the original cookie from which the session was created (can be different from current session)
* @return
*/
protected abstract boolean cookieRenewalNeeded(String originalCookie);
public void postProcess(Exchange exc) {
synchronized (this) {
if (issuer == null)
initIssuer(exc);
}
getSessionFromExchange(exc).ifPresent(session -> {
try {
createDefaultResponseIfNeeded(exc);
handleSetCookieHeaderForResponse(exc, session);
} catch (Exception e) {
throw new RuntimeException("The newly created session could not be persisted in the Set-Cookie header", e);
}
});
}
private void createDefaultResponseIfNeeded(Exchange exc) {
if (exc.getResponse() == null)
exc.setResponse(Response.ok().build());
}
private void handleSetCookieHeaderForResponse(Exchange exc, Session session) throws Exception {
Optional