Removing references to request and response from Resteasy

Closes #15374
This commit is contained in:
Pedro Igor 2022-11-25 17:53:12 -03:00
parent 8e6437e596
commit 168734b817
105 changed files with 677 additions and 293 deletions

View file

@ -17,7 +17,7 @@
package org.keycloak.examples.authenticator; package org.keycloak.examples.authenticator;
import org.jboss.resteasy.spi.HttpResponse; import org.keycloak.http.HttpResponse;
import org.keycloak.authentication.AuthenticationFlowContext; import org.keycloak.authentication.AuthenticationFlowContext;
import org.keycloak.authentication.AuthenticationFlowError; import org.keycloak.authentication.AuthenticationFlowError;
import org.keycloak.authentication.Authenticator; import org.keycloak.authentication.Authenticator;
@ -96,11 +96,11 @@ public class SecretQuestionAuthenticator implements Authenticator, CredentialVal
} }
public void addCookie(AuthenticationFlowContext context, String name, String value, String path, String domain, String comment, int maxAge, boolean secure, boolean httpOnly) { public void addCookie(AuthenticationFlowContext context, String name, String value, String path, String domain, String comment, int maxAge, boolean secure, boolean httpOnly) {
HttpResponse response = context.getSession().getContext().getContextObject(HttpResponse.class); HttpResponse response = context.getSession().getContext().getHttpResponse();
StringBuffer cookieBuf = new StringBuffer(); StringBuffer cookieBuf = new StringBuffer();
ServerCookie.appendCookieValue(cookieBuf, 1, name, value, path, domain, comment, maxAge, secure, httpOnly, null); ServerCookie.appendCookieValue(cookieBuf, 1, name, value, path, domain, comment, maxAge, secure, httpOnly, null);
String cookie = cookieBuf.toString(); String cookie = cookieBuf.toString();
response.getOutputHeaders().add(HttpHeaders.SET_COOKIE, cookie); response.addHeader(HttpHeaders.SET_COOKIE, cookie);
} }

View file

@ -16,12 +16,11 @@
*/ */
package org.keycloak.connections.jpa; package org.keycloak.connections.jpa;
import org.keycloak.models.KeycloakSession;
import javax.naming.InitialContext; import javax.naming.InitialContext;
import javax.naming.NamingException; import javax.naming.NamingException;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManagerFactory;
import org.keycloak.models.KeycloakSession;
/** /**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>

View file

@ -66,6 +66,7 @@ import org.keycloak.vault.VaultTranscriber;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
@ -199,6 +200,11 @@ public class ImportKeycloakSession implements KeycloakSession {
session.setAttribute(name, value); session.setAttribute(name, value);
} }
@Override
public Map<String, Object> getAttributes() {
return session.getAttributes();
}
@Override @Override
public void invalidate(InvalidationHandler.InvalidableObjectType type, Object... ids) { public void invalidate(InvalidationHandler.InvalidableObjectType type, Object... ids) {
// For now, forward the invalidations only to those providers created specifically for this import session. // For now, forward the invalidations only to those providers created specifically for this import session.

View file

@ -30,7 +30,6 @@ import java.util.function.BiFunction;
import java.util.function.Function; import java.util.function.Function;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest;
import org.keycloak.Config; import org.keycloak.Config;
import org.keycloak.common.util.Resteasy; import org.keycloak.common.util.Resteasy;
import org.keycloak.config.HostnameOptions; import org.keycloak.config.HostnameOptions;
@ -295,7 +294,7 @@ public final class DefaultHostnameProvider implements HostnameProvider, Hostname
private int getRequestPort() { private int getRequestPort() {
KeycloakSession session = Resteasy.getContextData(KeycloakSession.class); KeycloakSession session = Resteasy.getContextData(KeycloakSession.class);
return session.getContext().getContextObject(HttpRequest.class).getUri().getBaseUri().getPort(); return session.getContext().getHttpRequest().getUri().getBaseUri().getPort();
} }
private <T> T fromBaseUriOrDefault(Function<URI, T> resolver, URI baseUri, T defaultValue) { private <T> T fromBaseUriOrDefault(Function<URI, T> resolver, URI baseUri, T defaultValue) {

View file

@ -0,0 +1,58 @@
/*
* Copyright 2022 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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 org.keycloak.quarkus.runtime.integration;
import java.security.cert.X509Certificate;
import javax.enterprise.inject.Instance;
import javax.enterprise.inject.spi.CDI;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import org.jboss.resteasy.spi.HttpRequest;
import org.keycloak.services.HttpRequestImpl;
import io.vertx.ext.web.RoutingContext;
public class QuarkusHttpRequest extends HttpRequestImpl {
public <R> QuarkusHttpRequest(HttpRequest delegate) {
super(delegate);
}
@Override
public X509Certificate[] getClientCertificateChain() {
Instance<RoutingContext> instances = CDI.current().select(RoutingContext.class);
if (instances.isResolvable()) {
RoutingContext context = instances.get();
try {
SSLSession sslSession = context.request().sslSession();
if (sslSession == null) {
return null;
}
return (X509Certificate[]) sslSession.getPeerCertificates();
} catch (SSLPeerUnverifiedException ignore) {
// client not authenticated
}
}
return null;
}
}

View file

@ -0,0 +1,35 @@
/*
* Copyright 2022 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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 org.keycloak.quarkus.runtime.integration;
import org.keycloak.common.util.Resteasy;
import org.keycloak.http.HttpRequest;
import org.keycloak.models.KeycloakSession;
import org.keycloak.services.DefaultKeycloakContext;
public class QuarkusKeycloakContext extends DefaultKeycloakContext {
public QuarkusKeycloakContext(KeycloakSession session) {
super(session);
}
@Override
protected HttpRequest createHttpRequest() {
return new QuarkusHttpRequest(Resteasy.getContextData(org.jboss.resteasy.spi.HttpRequest.class));
}
}

View file

@ -0,0 +1,35 @@
/*
* Copyright 2022 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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 org.keycloak.quarkus.runtime.integration;
import org.keycloak.models.KeycloakSession;
import org.keycloak.services.DefaultKeycloakContext;
import org.keycloak.services.DefaultKeycloakSession;
import org.keycloak.services.DefaultKeycloakSessionFactory;
public class QuarkusKeycloakSession extends DefaultKeycloakSession {
public QuarkusKeycloakSession(DefaultKeycloakSessionFactory factory) {
super(factory);
}
@Override
protected DefaultKeycloakContext createKeycloakContext(KeycloakSession session) {
return new QuarkusKeycloakContext(session);
}
}

View file

@ -23,6 +23,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.keycloak.Config; import org.keycloak.Config;
import org.keycloak.models.KeycloakSession;
import org.keycloak.provider.Provider; import org.keycloak.provider.Provider;
import org.keycloak.provider.ProviderFactory; import org.keycloak.provider.ProviderFactory;
import org.keycloak.provider.ProviderManagerRegistry; import org.keycloak.provider.ProviderManagerRegistry;
@ -122,4 +123,9 @@ public final class QuarkusKeycloakSessionFactory extends DefaultKeycloakSessionF
return factory; return factory;
} }
@Override
public KeycloakSession create() {
return new QuarkusKeycloakSession(this);
}
} }

View file

@ -19,17 +19,10 @@ package org.keycloak.quarkus.runtime.integration.web;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import javax.enterprise.inject.Instance;
import javax.enterprise.inject.spi.CDI;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.services.x509.X509ClientCertificateLookup; import org.keycloak.services.x509.X509ClientCertificateLookup;
import io.vertx.ext.web.RoutingContext;
/** /**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a> * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/ */
@ -47,19 +40,7 @@ public class VertxClientCertificateLookup implements X509ClientCertificateLookup
@Override @Override
public X509Certificate[] getCertificateChain(HttpRequest httpRequest) { public X509Certificate[] getCertificateChain(HttpRequest httpRequest) {
Instance<RoutingContext> instances = CDI.current().select(RoutingContext.class); X509Certificate[] certificates = httpRequest.getClientCertificateChain();
if (instances.isResolvable()) {
RoutingContext context = instances.get();
try {
SSLSession sslSession = context.request().sslSession();
if (sslSession == null) {
return null;
}
X509Certificate[] certificates = (X509Certificate[]) sslSession.getPeerCertificates();
if (logger.isTraceEnabled() && certificates != null) { if (logger.isTraceEnabled() && certificates != null) {
for (X509Certificate cert : certificates) { for (X509Certificate cert : certificates) {
@ -68,11 +49,5 @@ public class VertxClientCertificateLookup implements X509ClientCertificateLookup
} }
return certificates; return certificates;
} catch (SSLPeerUnverifiedException ignore) {
// client not authenticated
}
}
return null;
} }
} }

View file

@ -17,13 +17,13 @@
package org.keycloak.quarkus.runtime.services.resources; package org.keycloak.quarkus.runtime.services.resources;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest;
import org.keycloak.common.ClientConnection; import org.keycloak.common.ClientConnection;
import org.keycloak.common.Profile; import org.keycloak.common.Profile;
import org.keycloak.common.Version; import org.keycloak.common.Version;
import org.keycloak.common.util.Base64Url; import org.keycloak.common.util.Base64Url;
import org.keycloak.common.util.MimeTypeUtil; import org.keycloak.common.util.MimeTypeUtil;
import org.keycloak.common.util.SecretGenerator; import org.keycloak.common.util.SecretGenerator;
import org.keycloak.http.HttpRequest;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.quarkus.runtime.configuration.Configuration; import org.keycloak.quarkus.runtime.configuration.Configuration;
import org.keycloak.services.ForbiddenException; import org.keycloak.services.ForbiddenException;
@ -71,12 +71,6 @@ public class QuarkusWelcomeResource {
private AtomicBoolean shouldBootstrap; private AtomicBoolean shouldBootstrap;
@Context
HttpHeaders headers;
@Context
HttpRequest request;
@Context @Context
KeycloakSession session; KeycloakSession session;
@ -98,6 +92,7 @@ public class QuarkusWelcomeResource {
@Consumes(MediaType.APPLICATION_FORM_URLENCODED) @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.TEXT_HTML_UTF_8) @Produces(MediaType.TEXT_HTML_UTF_8)
public Response createUser() { public Response createUser() {
HttpRequest request = session.getContext().getHttpRequest();
MultivaluedMap<String, String> formData = request.getDecodedFormParameters(); MultivaluedMap<String, String> formData = request.getDecodedFormParameters();
if (!shouldBootstrap()) { if (!shouldBootstrap()) {
@ -254,6 +249,8 @@ public class QuarkusWelcomeResource {
ClientConnection clientConnection = session.getContext().getConnection(); ClientConnection clientConnection = session.getContext().getConnection();
InetAddress remoteInetAddress = InetAddress.getByName(clientConnection.getRemoteAddr()); InetAddress remoteInetAddress = InetAddress.getByName(clientConnection.getRemoteAddr());
InetAddress localInetAddress = InetAddress.getByName(clientConnection.getLocalAddr()); InetAddress localInetAddress = InetAddress.getByName(clientConnection.getLocalAddr());
HttpRequest request = session.getContext().getHttpRequest();
HttpHeaders headers = request.getHttpHeaders();
String xForwardedFor = headers.getHeaderString("X-Forwarded-For"); String xForwardedFor = headers.getHeaderString("X-Forwarded-For");
logger.debugf("Checking WelcomePage. Remote address: %s, Local address: %s, X-Forwarded-For header: %s", remoteInetAddress.toString(), localInetAddress.toString(), xForwardedFor); logger.debugf("Checking WelcomePage. Remote address: %s, Local address: %s, X-Forwarded-For header: %s", remoteInetAddress.toString(), localInetAddress.toString(), xForwardedFor);
@ -273,18 +270,20 @@ public class QuarkusWelcomeResource {
String stateChecker = Base64Url.encode(SecretGenerator.getInstance().randomBytes()); String stateChecker = Base64Url.encode(SecretGenerator.getInstance().randomBytes());
String cookiePath = session.getContext().getUri().getPath(); String cookiePath = session.getContext().getUri().getPath();
boolean secureOnly = session.getContext().getUri().getRequestUri().getScheme().equalsIgnoreCase("https"); boolean secureOnly = session.getContext().getUri().getRequestUri().getScheme().equalsIgnoreCase("https");
CookieHelper.addCookie(KEYCLOAK_STATE_CHECKER, stateChecker, cookiePath, null, null, 300, secureOnly, true); CookieHelper.addCookie(KEYCLOAK_STATE_CHECKER, stateChecker, cookiePath, null, null, 300, secureOnly, true, session);
return stateChecker; return stateChecker;
} }
private void expireCsrfCookie() { private void expireCsrfCookie() {
String cookiePath = session.getContext().getUri().getPath(); String cookiePath = session.getContext().getUri().getPath();
boolean secureOnly = session.getContext().getUri().getRequestUri().getScheme().equalsIgnoreCase("https"); boolean secureOnly = session.getContext().getUri().getRequestUri().getScheme().equalsIgnoreCase("https");
CookieHelper.addCookie(KEYCLOAK_STATE_CHECKER, "", cookiePath, null, null, 0, secureOnly, true); CookieHelper.addCookie(KEYCLOAK_STATE_CHECKER, "", cookiePath, null, null, 0, secureOnly, true, session);
} }
private void csrfCheck(final MultivaluedMap<String, String> formData) { private void csrfCheck(final MultivaluedMap<String, String> formData) {
String formStateChecker = formData.getFirst("stateChecker"); String formStateChecker = formData.getFirst("stateChecker");
HttpRequest request = session.getContext().getHttpRequest();
HttpHeaders headers = request.getHttpHeaders();
Cookie cookie = headers.getCookies().get(KEYCLOAK_STATE_CHECKER); Cookie cookie = headers.getCookies().get(KEYCLOAK_STATE_CHECKER);
if (cookie == null) { if (cookie == null) {
throw new ForbiddenException(); throw new ForbiddenException();

View file

@ -17,7 +17,7 @@
package org.keycloak.authentication; package org.keycloak.authentication;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.common.ClientConnection; import org.keycloak.common.ClientConnection;
import org.keycloak.events.EventBuilder; import org.keycloak.events.EventBuilder;
import org.keycloak.models.AuthenticationExecutionModel; import org.keycloak.models.AuthenticationExecutionModel;

View file

@ -17,7 +17,7 @@
package org.keycloak.authentication; package org.keycloak.authentication;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.common.ClientConnection; import org.keycloak.common.ClientConnection;
import org.keycloak.events.EventBuilder; import org.keycloak.events.EventBuilder;
import org.keycloak.models.AuthenticationExecutionModel; import org.keycloak.models.AuthenticationExecutionModel;

View file

@ -17,7 +17,7 @@
package org.keycloak.authentication; package org.keycloak.authentication;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.common.ClientConnection; import org.keycloak.common.ClientConnection;
import org.keycloak.events.EventBuilder; import org.keycloak.events.EventBuilder;
import org.keycloak.forms.login.LoginFormsProvider; import org.keycloak.forms.login.LoginFormsProvider;

View file

@ -16,7 +16,7 @@
*/ */
package org.keycloak.broker.provider; package org.keycloak.broker.provider;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.broker.provider.util.IdentityBrokerState; import org.keycloak.broker.provider.util.IdentityBrokerState;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;

View file

@ -0,0 +1,70 @@
/*
* Copyright 2022 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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 org.keycloak.http;
import java.security.cert.X509Certificate;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.UriInfo;
import org.keycloak.models.KeycloakContext;
/**
* <p>Represents an incoming HTTP request.
*
* <p>Instances of this class can be obtained from {@link KeycloakContext#getHttpRequest()}.
*/
public interface HttpRequest {
/**
* Returns the HTTP method.
*
* @return the HTTP method.
*/
String getHttpMethod();
/**
* <p>Returns the form parameters (e.g.: media type {@code application/x-www-form-urlencoded}) as a {@link MultivaluedMap} where the key and its correspondent value maps to the parameter name and
* value, respectively.
*
* <p>The values are already decoded using HTML form decoding.
*
* @return the decoded form parameters
*/
MultivaluedMap<String, String> getDecodedFormParameters();
/**
* Returns the HTTP headers.
*
* @return the HTTP headers
*/
HttpHeaders getHttpHeaders();
/**
* Returns the client X509 certificate chain when processing TLS requests.
*
* @return the client certificate chain
*/
X509Certificate[] getClientCertificateChain();
/**
* Returns a {@link UriInfo} instance for the path being requested.
*
* @return the {@link UriInfo} for the current path
*/
UriInfo getUri();
}

View file

@ -0,0 +1,48 @@
/*
* Copyright 2022 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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 org.keycloak.http;
/**
* <p>Represents an out coming HTTP response.
*
* <p>Instances of this class can be obtained from {@link org.keycloak.models.KeycloakContext#getHttpResponse}.
*/
public interface HttpResponse {
/**
* Sets a status code.
*
* @param statusCode the status code
*/
void setStatus(int statusCode);
/**
* Add a value to the current list of values for the header with the given {@code name}.
*
* @param name the header name
* @param value the header value
*/
void addHeader(String name, String value);
/**
* Set a header. Any existing values will be replaced.
*
* @param name the header name
* @param value the header value
*/
void setHeader(String name, String value);
}

View file

@ -18,6 +18,8 @@
package org.keycloak.models; package org.keycloak.models;
import org.keycloak.common.ClientConnection; import org.keycloak.common.ClientConnection;
import org.keycloak.http.HttpRequest;
import org.keycloak.http.HttpResponse;
import org.keycloak.sessions.AuthenticationSessionModel; import org.keycloak.sessions.AuthenticationSessionModel;
import org.keycloak.urls.UrlType; import org.keycloak.urls.UrlType;
@ -75,4 +77,8 @@ public interface KeycloakContext {
AuthenticationSessionModel getAuthenticationSession(); AuthenticationSessionModel getAuthenticationSession();
void setAuthenticationSession(AuthenticationSessionModel authenticationSession); void setAuthenticationSession(AuthenticationSessionModel authenticationSession);
HttpRequest getHttpRequest();
HttpResponse getHttpResponse();
} }

View file

@ -24,6 +24,7 @@ import org.keycloak.services.clientpolicy.ClientPolicyManager;
import org.keycloak.sessions.AuthenticationSessionProvider; import org.keycloak.sessions.AuthenticationSessionProvider;
import org.keycloak.vault.VaultTranscriber; import org.keycloak.vault.VaultTranscriber;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
@ -123,6 +124,8 @@ public interface KeycloakSession {
Object removeAttribute(String attribute); Object removeAttribute(String attribute);
void setAttribute(String name, Object value); void setAttribute(String name, Object value);
Map<String, Object> getAttributes();
/** /**
* Invalidates intermediate states of the given objects, both immediately and at the end of this session. * Invalidates intermediate states of the given objects, both immediately and at the end of this session.
* @param type Type of the objects to invalidate * @param type Type of the objects to invalidate

View file

@ -18,7 +18,7 @@
package org.keycloak.authentication; package org.keycloak.authentication;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.authentication.authenticators.browser.AbstractUsernameFormAuthenticator; import org.keycloak.authentication.authenticators.browser.AbstractUsernameFormAuthenticator;
import org.keycloak.authentication.authenticators.client.ClientAuthUtil; import org.keycloak.authentication.authenticators.client.ClientAuthUtil;
import org.keycloak.common.ClientConnection; import org.keycloak.common.ClientConnection;
@ -795,7 +795,7 @@ public class AuthenticationProcessor {
.setSession(session) .setSession(session)
.setUriInfo(uriInfo) .setUriInfo(uriInfo)
.setRequest(request); .setRequest(request);
CacheControlUtil.noBackButtonCacheControlHeader(); CacheControlUtil.noBackButtonCacheControlHeader(session);
return processor.authenticate(); return processor.authenticate();
} else if (e.getError() == AuthenticationFlowError.DISPLAY_NOT_SUPPORTED) { } else if (e.getError() == AuthenticationFlowError.DISPLAY_NOT_SUPPORTED) {

View file

@ -18,7 +18,6 @@
package org.keycloak.authentication; package org.keycloak.authentication;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.keycloak.OAuth2Constants;
import org.keycloak.authentication.authenticators.conditional.ConditionalAuthenticator; import org.keycloak.authentication.authenticators.conditional.ConditionalAuthenticator;
import org.keycloak.models.AuthenticationExecutionModel; import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.AuthenticationFlowModel; import org.keycloak.models.AuthenticationFlowModel;

View file

@ -17,7 +17,7 @@
package org.keycloak.authentication; package org.keycloak.authentication;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.common.ClientConnection; import org.keycloak.common.ClientConnection;
import org.keycloak.events.EventBuilder; import org.keycloak.events.EventBuilder;
import org.keycloak.forms.login.LoginFormsProvider; import org.keycloak.forms.login.LoginFormsProvider;

View file

@ -17,7 +17,7 @@
package org.keycloak.authentication; package org.keycloak.authentication;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.common.ClientConnection; import org.keycloak.common.ClientConnection;
import org.keycloak.common.util.Time; import org.keycloak.common.util.Time;
import org.keycloak.events.EventBuilder; import org.keycloak.events.EventBuilder;

View file

@ -30,7 +30,7 @@ import org.keycloak.sessions.AuthenticationSessionModel;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilderException; import javax.ws.rs.core.UriBuilderException;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.sessions.RootAuthenticationSessionModel; import org.keycloak.sessions.RootAuthenticationSessionModel;
/** /**

View file

@ -49,7 +49,7 @@ import java.util.Map;
* <li>{@code user} the current {@link UserModel}</li> * <li>{@code user} the current {@link UserModel}</li>
* <li>{@code session} the active {@link KeycloakSession}</li> * <li>{@code session} the active {@link KeycloakSession}</li>
* <li>{@code authenticationSession} the current {@link org.keycloak.sessions.AuthenticationSessionModel}</li> * <li>{@code authenticationSession} the current {@link org.keycloak.sessions.AuthenticationSessionModel}</li>
* <li>{@code httpRequest} the current {@link org.jboss.resteasy.spi.HttpRequest}</li> * <li>{@code httpRequest} the current {@link org.keycloak.http.HttpRequest}</li>
* <li>{@code LOG} a {@link org.jboss.logging.Logger} scoped to {@link ScriptBasedAuthenticator}/li> * <li>{@code LOG} a {@link org.jboss.logging.Logger} scoped to {@link ScriptBasedAuthenticator}/li>
* </ol> * </ol>
* </p> * </p>

View file

@ -18,7 +18,7 @@
package org.keycloak.authentication.authenticators.browser; package org.keycloak.authentication.authenticators.browser;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.authentication.AuthenticationFlowContext; import org.keycloak.authentication.AuthenticationFlowContext;
import org.keycloak.authentication.AuthenticationFlowError; import org.keycloak.authentication.AuthenticationFlowError;
import org.keycloak.authentication.Authenticator; import org.keycloak.authentication.Authenticator;

View file

@ -16,7 +16,6 @@
package org.keycloak.authentication.authenticators.browser; package org.keycloak.authentication.authenticators.browser;
import com.webauthn4j.data.AuthenticationParameters;
import com.webauthn4j.data.AuthenticationRequest; import com.webauthn4j.data.AuthenticationRequest;
import com.webauthn4j.data.client.Origin; import com.webauthn4j.data.client.Origin;
import com.webauthn4j.data.client.challenge.Challenge; import com.webauthn4j.data.client.challenge.Challenge;

View file

@ -20,7 +20,7 @@ import javax.ws.rs.HttpMethod;
import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.authentication.AuthenticationFlowContext; import org.keycloak.authentication.AuthenticationFlowContext;
import org.keycloak.authentication.Authenticator; import org.keycloak.authentication.Authenticator;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;

View file

@ -17,7 +17,7 @@
package org.keycloak.authentication.authenticators.client; package org.keycloak.authentication.authenticators.client;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.Config; import org.keycloak.Config;
import org.keycloak.authentication.ClientAuthenticator; import org.keycloak.authentication.ClientAuthenticator;
import org.keycloak.authentication.ClientAuthenticatorFactory; import org.keycloak.authentication.ClientAuthenticatorFactory;

View file

@ -19,9 +19,9 @@
package org.keycloak.authentication.authenticators.x509; package org.keycloak.authentication.authenticators.x509;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map;
import javax.ws.rs.core.MultivaluedHashMap; import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.MultivaluedMap;
@ -232,10 +232,9 @@ public class X509ClientCertificateAuthenticator extends AbstractX509ClientCertif
private void dumpContainerAttributes(AuthenticationFlowContext context) { private void dumpContainerAttributes(AuthenticationFlowContext context) {
Enumeration<String> attributeNames = context.getHttpRequest().getAttributeNames(); Map<String, Object> attributeNames = context.getSession().getAttributes();
while(attributeNames.hasMoreElements()) { for (String name : attributeNames.keySet()) {
String a = attributeNames.nextElement(); logger.tracef("[X509ClientCertificateAuthenticator:dumpContainerAttributes] \"%s\"", name);
logger.tracef("[X509ClientCertificateAuthenticator:dumpContainerAttributes] \"%s\"", a);
} }
} }

View file

@ -14,10 +14,8 @@ import org.keycloak.credential.CredentialProvider;
import org.keycloak.events.Details; import org.keycloak.events.Details;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.models.credential.RecoveryAuthnCodesCredentialModel; import org.keycloak.models.credential.RecoveryAuthnCodesCredentialModel;
import org.keycloak.models.utils.RecoveryAuthnCodesUtils;
import org.keycloak.provider.EnvironmentDependentProviderFactory; import org.keycloak.provider.EnvironmentDependentProviderFactory;
import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.MultivaluedMap;

View file

@ -32,7 +32,7 @@ import javax.ws.rs.core.Response;
import com.webauthn4j.WebAuthnRegistrationManager; import com.webauthn4j.WebAuthnRegistrationManager;
import com.webauthn4j.data.AuthenticatorTransport; import com.webauthn4j.data.AuthenticatorTransport;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.WebAuthnConstants; import org.keycloak.WebAuthnConstants;
import org.keycloak.authentication.CredentialRegistrator; import org.keycloak.authentication.CredentialRegistrator;
import org.keycloak.authentication.InitiatedActionSupport; import org.keycloak.authentication.InitiatedActionSupport;

View file

@ -38,7 +38,7 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.Response.Status;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.OAuthErrorException; import org.keycloak.OAuthErrorException;
import org.keycloak.authorization.AuthorizationProvider; import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.common.DefaultEvaluationContext; import org.keycloak.authorization.common.DefaultEvaluationContext;

View file

@ -19,7 +19,7 @@ package org.keycloak.broker.oidc;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.OAuth2Constants; import org.keycloak.OAuth2Constants;
import org.keycloak.OAuthErrorException; import org.keycloak.OAuthErrorException;
import org.keycloak.broker.provider.AbstractIdentityProvider; import org.keycloak.broker.provider.AbstractIdentityProvider;
@ -470,7 +470,7 @@ public abstract class AbstractOAuth2IdentityProvider<C extends OAuth2IdentityPro
this.provider = provider; this.provider = provider;
this.session = provider.session; this.session = provider.session;
this.clientConnection = session.getContext().getConnection(); this.clientConnection = session.getContext().getConnection();
this.httpRequest = session.getContext().getContextObject(HttpRequest.class); this.httpRequest = session.getContext().getHttpRequest();
this.headers = session.getContext().getRequestHeaders(); this.headers = session.getContext().getRequestHeaders();
} }

View file

@ -584,7 +584,7 @@ public class SAMLEndpoint {
*/ */
private AuthenticationSessionModel samlIdpInitiatedSSO(final String clientUrlName) { private AuthenticationSessionModel samlIdpInitiatedSSO(final String clientUrlName) {
event.event(EventType.LOGIN); event.event(EventType.LOGIN);
CacheControlUtil.noBackButtonCacheControlHeader(); CacheControlUtil.noBackButtonCacheControlHeader(session);
Optional<ClientModel> oClient = SAMLEndpoint.this.session.clients() Optional<ClientModel> oClient = SAMLEndpoint.this.session.clients()
.searchClientsByAttributes(realm, Collections.singletonMap(SamlProtocol.SAML_IDP_INITIATED_SSO_URL_NAME, clientUrlName), 0, 1) .searchClientsByAttributes(realm, Collections.singletonMap(SamlProtocol.SAML_IDP_INITIATED_SSO_URL_NAME, clientUrlName), 0, 1)
.findFirst(); .findFirst();

View file

@ -55,7 +55,7 @@ public class DefaultLocaleUpdaterProvider implements LocaleUpdaterProvider {
UriInfo uriInfo = session.getContext().getUri(); UriInfo uriInfo = session.getContext().getUri();
boolean secure = realm.getSslRequired().isRequired(uriInfo.getRequestUri().getHost()); boolean secure = realm.getSslRequired().isRequired(uriInfo.getRequestUri().getHost());
CookieHelper.addCookie(LocaleSelectorProvider.LOCALE_COOKIE, locale, AuthenticationManager.getRealmCookiePath(realm, uriInfo), null, null, -1, secure, true); CookieHelper.addCookie(LocaleSelectorProvider.LOCALE_COOKIE, locale, AuthenticationManager.getRealmCookiePath(realm, uriInfo), null, null, -1, secure, true, session);
logger.debugv("Updating locale cookie to {0}", locale); logger.debugv("Updating locale cookie to {0}", locale);
} }
@ -65,7 +65,7 @@ public class DefaultLocaleUpdaterProvider implements LocaleUpdaterProvider {
UriInfo uriInfo = session.getContext().getUri(); UriInfo uriInfo = session.getContext().getUri();
boolean secure = realm.getSslRequired().isRequired(session.getContext().getConnection()); boolean secure = realm.getSslRequired().isRequired(session.getContext().getConnection());
CookieHelper.addCookie(LocaleSelectorProvider.LOCALE_COOKIE, "", AuthenticationManager.getRealmCookiePath(realm, uriInfo), null, "Expiring cookie", 0, secure, true); CookieHelper.addCookie(LocaleSelectorProvider.LOCALE_COOKIE, "", AuthenticationManager.getRealmCookiePath(realm, uriInfo), null, "Expiring cookie", 0, secure, true, session);
} }
@Override @Override

View file

@ -18,7 +18,7 @@
package org.keycloak.protocol; package org.keycloak.protocol;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.authentication.AuthenticationProcessor; import org.keycloak.authentication.AuthenticationProcessor;
import org.keycloak.common.ClientConnection; import org.keycloak.common.ClientConnection;
import org.keycloak.events.Details; import org.keycloak.events.Details;
@ -73,7 +73,7 @@ public abstract class AuthorizationEndpointBase {
this.clientConnection = session.getContext().getConnection(); this.clientConnection = session.getContext().getConnection();
this.realm = session.getContext().getRealm(); this.realm = session.getContext().getRealm();
this.event = event; this.event = event;
this.httpRequest = session.getContext().getContextObject(HttpRequest.class); this.httpRequest = session.getContext().getHttpRequest();
this.headers = session.getContext().getRequestHeaders(); this.headers = session.getContext().getRequestHeaders();
} }

View file

@ -23,6 +23,7 @@ import org.keycloak.Token;
import org.keycloak.TokenCategory; import org.keycloak.TokenCategory;
import org.keycloak.common.ClientConnection; import org.keycloak.common.ClientConnection;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakContext;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.services.managers.AuthenticationManager; import org.keycloak.services.managers.AuthenticationManager;
@ -124,13 +125,15 @@ public class RestartLoginCookie implements Token {
String encoded = session.tokens().encode(restart); String encoded = session.tokens().encode(restart);
String path = AuthenticationManager.getRealmCookiePath(realm, uriInfo); String path = AuthenticationManager.getRealmCookiePath(realm, uriInfo);
boolean secureOnly = realm.getSslRequired().isRequired(connection); boolean secureOnly = realm.getSslRequired().isRequired(connection);
CookieHelper.addCookie(KC_RESTART, encoded, path, null, null, -1, secureOnly, true); CookieHelper.addCookie(KC_RESTART, encoded, path, null, null, -1, secureOnly, true, session);
} }
public static void expireRestartCookie(RealmModel realm, ClientConnection connection, UriInfo uriInfo) { public static void expireRestartCookie(RealmModel realm, UriInfo uriInfo, KeycloakSession session) {
KeycloakContext context = session.getContext();
ClientConnection connection = context.getConnection();
String path = AuthenticationManager.getRealmCookiePath(realm, uriInfo); String path = AuthenticationManager.getRealmCookiePath(realm, uriInfo);
boolean secureOnly = realm.getSslRequired().isRequired(connection); boolean secureOnly = realm.getSslRequired().isRequired(connection);
CookieHelper.addCookie(KC_RESTART, "", path, null, null, 0, secureOnly, true); CookieHelper.addCookie(KC_RESTART, "", path, null, null, 0, secureOnly, true, session);
} }
public static Cookie getRestartCookie(KeycloakSession session){ public static Cookie getRestartCookie(KeycloakSession session){

View file

@ -72,7 +72,7 @@ public class DockerEndpoint extends AuthorizationEndpointBase {
updateAuthenticationSession(); updateAuthenticationSession();
// So back button doesn't work // So back button doesn't work
CacheControlUtil.noBackButtonCacheControlHeader(); CacheControlUtil.noBackButtonCacheControlHeader(session);
return handleBrowserAuthenticationRequest(authenticationSession, new DockerAuthV2Protocol(session, realm, session.getContext().getUri(), headers, event.event(login)), false, false); return handleBrowserAuthenticationRequest(authenticationSession, new DockerAuthV2Protocol(session, realm, session.getContext().getUri(), headers, event.event(login)), false, false);
} }

View file

@ -22,7 +22,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.OAuthErrorException; import org.keycloak.OAuthErrorException;
import org.keycloak.common.ClientConnection; import org.keycloak.common.ClientConnection;
import org.keycloak.crypto.KeyType; import org.keycloak.crypto.KeyType;
@ -89,7 +89,7 @@ public class OIDCLoginProtocolService {
this.tokenManager = new TokenManager(); this.tokenManager = new TokenManager();
this.event = event; this.event = event;
this.providerConfig = providerConfig; this.providerConfig = providerConfig;
this.request = session.getContext().getContextObject(HttpRequest.class); this.request = session.getContext().getHttpRequest();
this.headers = session.getContext().getRequestHeaders(); this.headers = session.getContext().getRequestHeaders();
} }

View file

@ -19,7 +19,7 @@ package org.keycloak.protocol.oidc;
import java.util.HashMap; import java.util.HashMap;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.OAuth2Constants; import org.keycloak.OAuth2Constants;
import org.keycloak.OAuthErrorException; import org.keycloak.OAuthErrorException;
import org.keycloak.TokenCategory; import org.keycloak.TokenCategory;

View file

@ -201,7 +201,7 @@ public class AuthorizationEndpoint extends AuthorizationEndpointBase {
updateAuthenticationSession(); updateAuthenticationSession();
// So back button doesn't work // So back button doesn't work
CacheControlUtil.noBackButtonCacheControlHeader(); CacheControlUtil.noBackButtonCacheControlHeader(session);
switch (action) { switch (action) {
case REGISTER: case REGISTER:
return buildRegister(); return buildRegister();
@ -356,7 +356,7 @@ public class AuthorizationEndpoint extends AuthorizationEndpointBase {
} }
private Response buildRegister() { private Response buildRegister() {
authManager.expireIdentityCookie(realm, session.getContext().getUri(), clientConnection); authManager.expireIdentityCookie(realm, session.getContext().getUri(), session);
AuthenticationFlowModel flow = realm.getRegistrationFlow(); AuthenticationFlowModel flow = realm.getRegistrationFlow();
String flowId = flow.getId(); String flowId = flow.getId();
@ -368,7 +368,7 @@ public class AuthorizationEndpoint extends AuthorizationEndpointBase {
} }
private Response buildForgotCredential() { private Response buildForgotCredential() {
authManager.expireIdentityCookie(realm, session.getContext().getUri(), clientConnection); authManager.expireIdentityCookie(realm, session.getContext().getUri(), session);
AuthenticationFlowModel flow = realm.getResetCredentialsFlow(); AuthenticationFlowModel flow = realm.getResetCredentialsFlow();
String flowId = flow.getId(); String flowId = flow.getId();

View file

@ -41,7 +41,7 @@ public class IframeUtil {
InputStream resource = IframeUtil.class.getResourceAsStream(fileName); InputStream resource = IframeUtil.class.getResourceAsStream(fileName);
if (resource != null) { if (resource != null) {
P3PHelper.addP3PHeader(); P3PHelper.addP3PHeader(session);
session.getProvider(SecurityHeadersProvider.class).options().allowAnyFrameAncestor(); session.getProvider(SecurityHeadersProvider.class).options().allowAnyFrameAncestor();
return Response.ok(resource).cacheControl(cacheControl).build(); return Response.ok(resource).cacheControl(cacheControl).build();
} else { } else {

View file

@ -24,7 +24,7 @@ import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForM
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.Config; import org.keycloak.Config;
import org.keycloak.OAuth2Constants; import org.keycloak.OAuth2Constants;
import org.keycloak.OAuthErrorException; import org.keycloak.OAuthErrorException;
@ -127,7 +127,7 @@ public class LogoutEndpoint {
this.event = event; this.event = event;
this.providerConfig = providerConfig; this.providerConfig = providerConfig;
this.offlineSessionsLazyLoadingEnabled = !Config.scope("userSessions").scope("infinispan").getBoolean("preloadOfflineSessionsFromDatabase", false); this.offlineSessionsLazyLoadingEnabled = !Config.scope("userSessions").scope("infinispan").getBoolean("preloadOfflineSessionsFromDatabase", false);
this.request = session.getContext().getContextObject(HttpRequest.class); this.request = session.getContext().getHttpRequest();
this.headers = session.getContext().getRequestHeaders(); this.headers = session.getContext().getRequestHeaders();
} }

View file

@ -18,8 +18,8 @@
package org.keycloak.protocol.oidc.endpoints; package org.keycloak.protocol.oidc.endpoints;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.jboss.resteasy.spi.HttpResponse; import org.keycloak.http.HttpResponse;
import org.keycloak.OAuth2Constants; import org.keycloak.OAuth2Constants;
import org.keycloak.OAuthErrorException; import org.keycloak.OAuthErrorException;
import org.keycloak.authentication.AuthenticationProcessor; import org.keycloak.authentication.AuthenticationProcessor;
@ -164,8 +164,8 @@ public class TokenEndpoint {
this.tokenManager = tokenManager; this.tokenManager = tokenManager;
this.realm = session.getContext().getRealm(); this.realm = session.getContext().getRealm();
this.event = event; this.event = event;
this.request = session.getContext().getContextObject(HttpRequest.class); this.request = session.getContext().getHttpRequest();
this.httpResponse = session.getContext().getContextObject(HttpResponse.class); this.httpResponse = session.getContext().getHttpResponse();
this.headers = session.getContext().getRequestHeaders(); this.headers = session.getContext().getRequestHeaders();
} }
@ -201,9 +201,8 @@ public class TokenEndpoint {
// https://tools.ietf.org/html/rfc6749#section-5.1 // https://tools.ietf.org/html/rfc6749#section-5.1
// The authorization server MUST include the HTTP "Cache-Control" response header field // The authorization server MUST include the HTTP "Cache-Control" response header field
// with a value of "no-store" as well as the "Pragma" response header field with a value of "no-cache". // with a value of "no-store" as well as the "Pragma" response header field with a value of "no-cache".
MultivaluedMap<String, Object> outputHeaders = httpResponse.getOutputHeaders(); httpResponse.setHeader("Cache-Control", "no-store");
outputHeaders.putSingle("Cache-Control", "no-store"); httpResponse.setHeader("Pragma", "no-cache");
outputHeaders.putSingle("Pragma", "no-cache");
checkSsl(); checkSsl();
checkRealm(); checkRealm();

View file

@ -17,7 +17,7 @@
package org.keycloak.protocol.oidc.endpoints; package org.keycloak.protocol.oidc.endpoints;
import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.common.ClientConnection; import org.keycloak.common.ClientConnection;
import org.keycloak.events.Errors; import org.keycloak.events.Errors;
import org.keycloak.events.EventBuilder; import org.keycloak.events.EventBuilder;
@ -61,7 +61,7 @@ public class TokenIntrospectionEndpoint {
this.clientConnection = session.getContext().getConnection(); this.clientConnection = session.getContext().getConnection();
this.realm = session.getContext().getRealm(); this.realm = session.getContext().getRealm();
this.event = event; this.event = event;
this.request = session.getContext().getContextObject(HttpRequest.class); this.request = session.getContext().getHttpRequest();
} }
@POST @POST

View file

@ -28,7 +28,7 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.OAuthErrorException; import org.keycloak.OAuthErrorException;
import org.keycloak.common.ClientConnection; import org.keycloak.common.ClientConnection;
import org.keycloak.common.util.Time; import org.keycloak.common.util.Time;
@ -79,7 +79,7 @@ public class TokenRevocationEndpoint {
this.clientConnection = session.getContext().getConnection(); this.clientConnection = session.getContext().getConnection();
this.realm = session.getContext().getRealm(); this.realm = session.getContext().getRealm();
this.event = event; this.event = event;
this.request = session.getContext().getContextObject(HttpRequest.class); this.request = session.getContext().getHttpRequest();
} }
@POST @POST

View file

@ -17,7 +17,7 @@
package org.keycloak.protocol.oidc.endpoints; package org.keycloak.protocol.oidc.endpoints;
import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.OAuth2Constants; import org.keycloak.OAuth2Constants;
import org.keycloak.TokenCategory; import org.keycloak.TokenCategory;
import org.keycloak.TokenVerifier; import org.keycloak.TokenVerifier;
@ -107,7 +107,7 @@ public class UserInfoEndpoint {
this.tokenManager = tokenManager; this.tokenManager = tokenManager;
this.appAuthManager = new AppAuthManager(); this.appAuthManager = new AppAuthManager();
this.error = new OAuth2Error().json(false).realm(realm); this.error = new OAuth2Error().json(false).realm(realm);
this.request = session.getContext().getContextObject(HttpRequest.class); this.request = session.getContext().getHttpRequest();
} }
@Path("/") @Path("/")

View file

@ -18,7 +18,7 @@ package org.keycloak.protocol.oidc.grants.ciba.endpoints;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.OAuthErrorException; import org.keycloak.OAuthErrorException;
import org.keycloak.TokenVerifier; import org.keycloak.TokenVerifier;
import org.keycloak.broker.provider.util.SimpleHttp; import org.keycloak.broker.provider.util.SimpleHttp;
@ -59,7 +59,7 @@ public class BackchannelAuthenticationCallbackEndpoint extends AbstractCibaEndpo
public BackchannelAuthenticationCallbackEndpoint(KeycloakSession session, EventBuilder event) { public BackchannelAuthenticationCallbackEndpoint(KeycloakSession session, EventBuilder event) {
super(session, event); super(session, event);
this.httpRequest = session.getContext().getContextObject(HttpRequest.class); this.httpRequest = session.getContext().getHttpRequest();
} }
@Path("/") @Path("/")

View file

@ -18,7 +18,7 @@ package org.keycloak.protocol.oidc.grants.ciba.endpoints;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.OAuth2Constants; import org.keycloak.OAuth2Constants;
import org.keycloak.OAuthErrorException; import org.keycloak.OAuthErrorException;
import org.keycloak.events.EventBuilder; import org.keycloak.events.EventBuilder;
@ -76,7 +76,7 @@ public class BackchannelAuthenticationEndpoint extends AbstractCibaEndpoint {
@Consumes(MediaType.APPLICATION_FORM_URLENCODED) @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public Response processGrantRequest() { public Response processGrantRequest() {
HttpRequest httpRequest = session.getContext().getContextObject(HttpRequest.class); HttpRequest httpRequest = session.getContext().getHttpRequest();
CIBAAuthenticationRequest request = authorizeClient(httpRequest.getDecodedFormParameters()); CIBAAuthenticationRequest request = authorizeClient(httpRequest.getDecodedFormParameters());
try { try {

View file

@ -18,7 +18,7 @@
package org.keycloak.protocol.oidc.grants.device.endpoints; package org.keycloak.protocol.oidc.grants.device.endpoints;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.OAuthErrorException; import org.keycloak.OAuthErrorException;
import org.keycloak.common.util.Base64Url; import org.keycloak.common.util.Base64Url;
import org.keycloak.common.util.SecretGenerator; import org.keycloak.common.util.SecretGenerator;
@ -86,7 +86,7 @@ public class DeviceEndpoint extends AuthorizationEndpointBase implements RealmRe
public DeviceEndpoint(KeycloakSession session, EventBuilder event) { public DeviceEndpoint(KeycloakSession session, EventBuilder event) {
super(session, event); super(session, event);
this.request = session.getContext().getContextObject(HttpRequest.class); this.request = session.getContext().getHttpRequest();
} }
/** /**
@ -123,7 +123,7 @@ public class DeviceEndpoint extends AuthorizationEndpointBase implements RealmRe
} }
// So back button doesn't work // So back button doesn't work
CacheControlUtil.noBackButtonCacheControlHeader(); CacheControlUtil.noBackButtonCacheControlHeader(session);
if (!realm.getOAuth2DeviceConfig().isOAuth2DeviceAuthorizationGrantEnabled(client)) { if (!realm.getOAuth2DeviceConfig().isOAuth2DeviceAuthorizationGrantEnabled(client)) {
event.error(Errors.NOT_ALLOWED); event.error(Errors.NOT_ALLOWED);
@ -207,7 +207,7 @@ public class DeviceEndpoint extends AuthorizationEndpointBase implements RealmRe
checkRealm(); checkRealm();
// So back button doesn't work // So back button doesn't work
CacheControlUtil.noBackButtonCacheControlHeader(); CacheControlUtil.noBackButtonCacheControlHeader(session);
// code is not known, we can infer the client neither. ask the user to provide the code. // code is not known, we can infer the client neither. ask the user to provide the code.
if (StringUtil.isNullOrEmpty(userCode)) { if (StringUtil.isNullOrEmpty(userCode)) {

View file

@ -17,7 +17,7 @@
package org.keycloak.protocol.oidc.par.endpoints; package org.keycloak.protocol.oidc.par.endpoints;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.OAuthErrorException; import org.keycloak.OAuthErrorException;
import org.keycloak.common.Profile; import org.keycloak.common.Profile;
import org.keycloak.events.EventBuilder; import org.keycloak.events.EventBuilder;
@ -69,7 +69,7 @@ public class ParEndpoint extends AbstractParEndpoint {
public ParEndpoint(KeycloakSession session, EventBuilder event) { public ParEndpoint(KeycloakSession session, EventBuilder event) {
super(session, event); super(session, event);
this.httpRequest = session.getContext().getContextObject(HttpRequest.class); this.httpRequest = session.getContext().getHttpRequest();
} }
@Path("/") @Path("/")

View file

@ -18,8 +18,7 @@
package org.keycloak.protocol.oidc.utils; package org.keycloak.protocol.oidc.utils;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpResponse;
import org.jboss.resteasy.spi.HttpResponse;
import org.keycloak.authentication.AuthenticationProcessor; import org.keycloak.authentication.AuthenticationProcessor;
import org.keycloak.authentication.ClientAuthenticator; import org.keycloak.authentication.ClientAuthenticator;
import org.keycloak.authentication.ClientAuthenticatorFactory; import org.keycloak.authentication.ClientAuthenticatorFactory;
@ -52,7 +51,7 @@ public class AuthorizeClientUtil {
if (response != null) { if (response != null) {
if (cors != null) { if (cors != null) {
cors.allowAllOrigins(); cors.allowAllOrigins();
HttpResponse httpResponse = session.getContext().getContextObject(HttpResponse.class); HttpResponse httpResponse = session.getContext().getHttpResponse();
cors.build(httpResponse); cors.build(httpResponse);
} }
throw new WebApplicationException(response); throw new WebApplicationException(response);
@ -101,7 +100,7 @@ public class AuthorizeClientUtil {
.setRealm(realm) .setRealm(realm)
.setSession(session) .setSession(session)
.setUriInfo(session.getContext().getUri()) .setUriInfo(session.getContext().getUri())
.setRequest(session.getContext().getContextObject(HttpRequest.class)); .setRequest(session.getContext().getHttpRequest());
return processor; return processor;
} }

View file

@ -23,8 +23,6 @@ import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.specimpl.ResteasyHttpHeaders;
import org.jboss.resteasy.spi.HttpRequest;
import org.keycloak.broker.saml.SAMLDataMarshaller; import org.keycloak.broker.saml.SAMLDataMarshaller;
import org.keycloak.common.ClientConnection; import org.keycloak.common.ClientConnection;
import org.keycloak.common.VerificationException; import org.keycloak.common.VerificationException;
@ -52,6 +50,8 @@ import org.keycloak.events.Errors;
import org.keycloak.events.EventBuilder; import org.keycloak.events.EventBuilder;
import org.keycloak.events.EventType; import org.keycloak.events.EventType;
import org.keycloak.executors.ExecutorsProvider; import org.keycloak.executors.ExecutorsProvider;
import org.keycloak.http.HttpRequest;
import org.keycloak.http.HttpResponse;
import org.keycloak.models.AuthenticatedClientSessionModel; import org.keycloak.models.AuthenticatedClientSessionModel;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.KeyManager; import org.keycloak.models.KeyManager;
@ -811,7 +811,7 @@ public class SamlService extends AuthorizationEndpointBase {
@GET @GET
public void redirectBinding(@Suspended AsyncResponse asyncResponse, @QueryParam(GeneralConstants.SAML_REQUEST_KEY) String samlRequest, @QueryParam(GeneralConstants.SAML_RESPONSE_KEY) String samlResponse, @QueryParam(GeneralConstants.RELAY_STATE) String relayState, @QueryParam(GeneralConstants.SAML_ARTIFACT_KEY) String artifact) { public void redirectBinding(@Suspended AsyncResponse asyncResponse, @QueryParam(GeneralConstants.SAML_REQUEST_KEY) String samlRequest, @QueryParam(GeneralConstants.SAML_RESPONSE_KEY) String samlResponse, @QueryParam(GeneralConstants.RELAY_STATE) String relayState, @QueryParam(GeneralConstants.SAML_ARTIFACT_KEY) String artifact) {
logger.debug("SAML GET"); logger.debug("SAML GET");
CacheControlUtil.noBackButtonCacheControlHeader(); CacheControlUtil.noBackButtonCacheControlHeader(session);
new RedirectBindingProtocol().execute(asyncResponse, samlRequest, samlResponse, relayState, artifact); new RedirectBindingProtocol().execute(asyncResponse, samlRequest, samlResponse, relayState, artifact);
} }
@ -919,7 +919,7 @@ public class SamlService extends AuthorizationEndpointBase {
@Produces(MediaType.TEXT_HTML_UTF_8) @Produces(MediaType.TEXT_HTML_UTF_8)
public Response idpInitiatedSSO(@PathParam("client") String clientUrlName, @QueryParam("RelayState") String relayState) { public Response idpInitiatedSSO(@PathParam("client") String clientUrlName, @QueryParam("RelayState") String relayState) {
event.event(EventType.LOGIN); event.event(EventType.LOGIN);
CacheControlUtil.noBackButtonCacheControlHeader(); CacheControlUtil.noBackButtonCacheControlHeader(session);
ClientModel client = session.clients() ClientModel client = session.clients()
.searchClientsByAttributes(realm, Collections.singletonMap(SamlProtocol.SAML_IDP_INITIATED_SSO_URL_NAME, clientUrlName), 0, 1) .searchClientsByAttributes(realm, Collections.singletonMap(SamlProtocol.SAML_IDP_INITIATED_SSO_URL_NAME, clientUrlName), 0, 1)
.findFirst().orElse(null); .findFirst().orElse(null);
@ -1311,16 +1311,15 @@ public class SamlService extends AuthorizationEndpointBase {
private class ArtifactResolutionRunnable implements ScheduledTask{ private class ArtifactResolutionRunnable implements ScheduledTask{
private final HttpRequest request;
private final HttpResponse response;
private AsyncResponse asyncResponse; private AsyncResponse asyncResponse;
private URI clientArtifactBindingURI; private URI clientArtifactBindingURI;
private String relayState; private String relayState;
private Document doc; private Document doc;
private UriInfo uri; private UriInfo uri;
private String realmId; private String realmId;
private HttpHeaders httpHeaders;
private ClientConnection connection; private ClientConnection connection;
private org.jboss.resteasy.spi.HttpResponse response;
private HttpRequest request;
private String bindingType; private String bindingType;
public ArtifactResolutionRunnable(String bindingType, AsyncResponse asyncResponse, Document doc, URI clientArtifactBindingURI, String relayState, ClientConnection connection){ public ArtifactResolutionRunnable(String bindingType, AsyncResponse asyncResponse, Document doc, URI clientArtifactBindingURI, String relayState, ClientConnection connection){
@ -1330,11 +1329,10 @@ public class SamlService extends AuthorizationEndpointBase {
this.relayState = relayState; this.relayState = relayState;
this.uri = session.getContext().getUri(); this.uri = session.getContext().getUri();
this.realmId = realm.getId(); this.realmId = realm.getId();
this.httpHeaders = new ResteasyHttpHeaders(headers.getRequestHeaders());
this.connection = connection; this.connection = connection;
this.response = session.getContext().getContextObject(org.jboss.resteasy.spi.HttpResponse.class);
this.request = session.getContext().getContextObject(HttpRequest.class);
this.bindingType = bindingType; this.bindingType = bindingType;
this.request = session.getContext().getHttpRequest();
this.response = session.getContext().getHttpResponse();
} }
@ -1346,10 +1344,8 @@ public class SamlService extends AuthorizationEndpointBase {
Resteasy.pushContext(KeycloakTransaction.class, tx); Resteasy.pushContext(KeycloakTransaction.class, tx);
Resteasy.pushContext(KeycloakSession.class, session); Resteasy.pushContext(KeycloakSession.class, session);
Resteasy.pushContext(HttpHeaders.class, httpHeaders);
Resteasy.pushContext(org.jboss.resteasy.spi.HttpResponse.class, response);
Resteasy.pushContext(HttpRequest.class, request); Resteasy.pushContext(HttpRequest.class, request);
Resteasy.pushContext(HttpResponse.class, response);
Resteasy.pushContext(ClientConnection.class, connection); Resteasy.pushContext(ClientConnection.class, connection);
RealmManager realmManager = new RealmManager(session); RealmManager realmManager = new RealmManager(session);

View file

@ -1,6 +1,6 @@
package org.keycloak.protocol.saml.profile.ecp.authenticator; package org.keycloak.protocol.saml.profile.ecp.authenticator;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.authentication.AuthenticationFlowContext; import org.keycloak.authentication.AuthenticationFlowContext;
import org.keycloak.authentication.AuthenticationFlowError; import org.keycloak.authentication.AuthenticationFlowError;
import org.keycloak.authentication.Authenticator; import org.keycloak.authentication.Authenticator;

View file

@ -19,6 +19,8 @@ package org.keycloak.services;
import org.keycloak.common.ClientConnection; import org.keycloak.common.ClientConnection;
import org.keycloak.common.util.Resteasy; import org.keycloak.common.util.Resteasy;
import org.keycloak.http.HttpRequest;
import org.keycloak.http.HttpResponse;
import org.keycloak.locale.LocaleSelectorProvider; import org.keycloak.locale.LocaleSelectorProvider;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakContext; import org.keycloak.models.KeycloakContext;
@ -45,13 +47,13 @@ public class DefaultKeycloakContext implements KeycloakContext {
private ClientModel client; private ClientModel client;
private ClientConnection connection;
private KeycloakSession session; private KeycloakSession session;
private Map<UrlType, KeycloakUriInfo> uriInfo; private Map<UrlType, KeycloakUriInfo> uriInfo;
private AuthenticationSessionModel authenticationSession; private AuthenticationSessionModel authenticationSession;
private HttpRequest request;
private HttpResponse response;
public DefaultKeycloakContext(KeycloakSession session) { public DefaultKeycloakContext(KeycloakSession session) {
this.session = session; this.session = session;
@ -85,9 +87,15 @@ public class DefaultKeycloakContext implements KeycloakContext {
return getUri(UrlType.FRONTEND); return getUri(UrlType.FRONTEND);
} }
/**
* @deprecated
* Use {@link #getHttpRequest()} to obtain the request headers.
* @return
*/
@Deprecated
@Override @Override
public HttpHeaders getRequestHeaders() { public HttpHeaders getRequestHeaders() {
return getContextObject(HttpHeaders.class); return getHttpRequest().getHttpHeaders();
} }
@Override @Override
@ -136,4 +144,39 @@ public class DefaultKeycloakContext implements KeycloakContext {
this.authenticationSession = authenticationSession; this.authenticationSession = authenticationSession;
} }
@Override
public HttpRequest getHttpRequest() {
if (request == null) {
synchronized (this) {
request = getContextObject(HttpRequest.class);
if (request == null) {
request = createHttpRequest();
}
}
}
return request;
}
@Override
public HttpResponse getHttpResponse() {
if (response == null) {
synchronized (this) {
response = getContextObject(HttpResponse.class);
if (response == null) {
response = createHttpResponse();
}
}
}
return response;
}
protected HttpRequest createHttpRequest() {
return new HttpRequestImpl(getContextObject(org.jboss.resteasy.spi.HttpRequest.class));
}
protected HttpResponse createHttpResponse() {
return new HttpResponseImpl(getContextObject(org.jboss.resteasy.spi.HttpResponse.class));
}
} }

View file

@ -53,6 +53,7 @@ import org.keycloak.vault.VaultProvider;
import org.keycloak.vault.VaultTranscriber; import org.keycloak.vault.VaultTranscriber;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
@ -93,7 +94,7 @@ public class DefaultKeycloakSession implements KeycloakSession {
public DefaultKeycloakSession(DefaultKeycloakSessionFactory factory) { public DefaultKeycloakSession(DefaultKeycloakSessionFactory factory) {
this.factory = factory; this.factory = factory;
this.transactionManager = new DefaultKeycloakTransactionManager(this); this.transactionManager = new DefaultKeycloakTransactionManager(this);
context = new DefaultKeycloakContext(this); context = createKeycloakContext(this);
} }
@Override @Override
@ -158,6 +159,11 @@ public class DefaultKeycloakSession implements KeycloakSession {
attributes.put(name, value); attributes.put(name, value);
} }
@Override
public Map<String, Object> getAttributes() {
return Collections.unmodifiableMap(attributes);
}
@Override @Override
public KeycloakTransactionManager getTransactionManager() { public KeycloakTransactionManager getTransactionManager() {
return transactionManager; return transactionManager;
@ -469,4 +475,8 @@ public class DefaultKeycloakSession implements KeycloakSession {
public boolean isClosed() { public boolean isClosed() {
return closed; return closed;
} }
protected DefaultKeycloakContext createKeycloakContext(KeycloakSession session) {
return new DefaultKeycloakContext(session);
}
} }

View file

@ -0,0 +1,58 @@
/*
* Copyright 2022 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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 org.keycloak.services;
import java.security.cert.X509Certificate;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.UriInfo;
import org.keycloak.http.HttpRequest;
public class HttpRequestImpl implements HttpRequest {
private org.jboss.resteasy.spi.HttpRequest delegate;
public <R> HttpRequestImpl(org.jboss.resteasy.spi.HttpRequest delegate) {
this.delegate = delegate;
}
@Override
public String getHttpMethod() {
return delegate.getHttpMethod();
}
@Override
public MultivaluedMap<String, String> getDecodedFormParameters() {
return delegate.getDecodedFormParameters();
}
@Override
public HttpHeaders getHttpHeaders() {
return delegate.getHttpHeaders();
}
@Override
public X509Certificate[] getClientCertificateChain() {
return (X509Certificate[]) delegate.getAttribute("javax.servlet.request.X509Certificate");
}
@Override
public UriInfo getUri() {
return delegate.getUri();
}
}

View file

@ -0,0 +1,44 @@
/*
* Copyright 2022 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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 org.keycloak.services;
import org.keycloak.http.HttpResponse;
public class HttpResponseImpl implements HttpResponse {
private org.jboss.resteasy.spi.HttpResponse delegate;
public HttpResponseImpl(org.jboss.resteasy.spi.HttpResponse delegate) {
this.delegate = delegate;
}
@Override
public void setStatus(int statusCode) {
delegate.setStatus(statusCode);
}
@Override
public void addHeader(String name, String value) {
delegate.getOutputHeaders().add(name, value);
}
@Override
public void setHeader(String name, String value) {
delegate.getOutputHeaders().putSingle(name, value);
}
}

View file

@ -17,7 +17,7 @@
package org.keycloak.services.clientpolicy.executor; package org.keycloak.services.clientpolicy.executor;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.OAuth2Constants; import org.keycloak.OAuth2Constants;
import org.keycloak.OAuthErrorException; import org.keycloak.OAuthErrorException;
@ -81,7 +81,7 @@ public class HolderOfKeyEnforcerExecutor implements ClientPolicyExecutorProvider
@Override @Override
public void executeOnEvent(ClientPolicyContext context) throws ClientPolicyException { public void executeOnEvent(ClientPolicyContext context) throws ClientPolicyException {
HttpRequest request = session.getContext().getContextObject(HttpRequest.class); HttpRequest request = session.getContext().getHttpRequest();
switch (context.getEvent()) { switch (context.getEvent()) {
case REGISTER: case REGISTER:
case UPDATE: case UPDATE:

View file

@ -19,7 +19,7 @@ package org.keycloak.services.clientpolicy.executor;
import java.util.Optional; import java.util.Optional;
import javax.ws.rs.HttpMethod; import javax.ws.rs.HttpMethod;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.events.Errors; import org.keycloak.events.Errors;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper; import org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper;
@ -84,7 +84,7 @@ public class SecureLogoutExecutor implements ClientPolicyExecutorProvider<Secure
return; return;
case LOGOUT_REQUEST: case LOGOUT_REQUEST:
HttpRequest request = session.getContext().getContextObject(HttpRequest.class); HttpRequest request = session.getContext().getHttpRequest();
if (HttpMethod.GET.equalsIgnoreCase(request.getHttpMethod()) && !configuration.isAllowFrontChannelLogout()) { if (HttpMethod.GET.equalsIgnoreCase(request.getHttpMethod()) && !configuration.isAllowFrontChannelLogout()) {
throwFrontChannelLogoutNotAllowed(); throwFrontChannelLogoutNotAllowed();

View file

@ -20,11 +20,10 @@ package org.keycloak.services.clientpolicy.executor;
import java.util.Optional; import java.util.Optional;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.OAuth2Constants; import org.keycloak.OAuth2Constants;
import org.keycloak.OAuthErrorException; import org.keycloak.OAuthErrorException;
import org.keycloak.common.util.ObjectUtil; import org.keycloak.common.util.ObjectUtil;
import org.keycloak.crypto.Algorithm;
import org.keycloak.jose.jws.JWSInput; import org.keycloak.jose.jws.JWSInput;
import org.keycloak.jose.jws.JWSInputException; import org.keycloak.jose.jws.JWSInputException;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
@ -83,7 +82,7 @@ public class SecureSigningAlgorithmForSignedJwtExecutor implements ClientPolicyE
case TOKEN_INTROSPECT: case TOKEN_INTROSPECT:
case LOGOUT_REQUEST: case LOGOUT_REQUEST:
boolean isRequireClientAssertion = Optional.ofNullable(configuration.isRequireClientAssertion()).orElse(Boolean.FALSE).booleanValue(); boolean isRequireClientAssertion = Optional.ofNullable(configuration.isRequireClientAssertion()).orElse(Boolean.FALSE).booleanValue();
HttpRequest req = session.getContext().getContextObject(HttpRequest.class); HttpRequest req = session.getContext().getHttpRequest();
String clientAssertion = req.getDecodedFormParameters().getFirst(OAuth2Constants.CLIENT_ASSERTION); String clientAssertion = req.getDecodedFormParameters().getFirst(OAuth2Constants.CLIENT_ASSERTION);
if (!isRequireClientAssertion && ObjectUtil.isBlank(clientAssertion)) { if (!isRequireClientAssertion && ObjectUtil.isBlank(clientAssertion)) {
break; break;

View file

@ -44,7 +44,7 @@ public class AppAuthManager extends AuthenticationManager {
if (authResult == null) return null; if (authResult == null) return null;
// refresh the cookies! // refresh the cookies!
createLoginCookie(session, realm, authResult.getUser(), authResult.getSession(), session.getContext().getUri(), session.getContext().getConnection()); createLoginCookie(session, realm, authResult.getUser(), authResult.getSession(), session.getContext().getUri(), session.getContext().getConnection());
if (authResult.getSession().isRememberMe()) createRememberMeCookie(realm, authResult.getUser().getUsername(), session.getContext().getUri(), session.getContext().getConnection()); if (authResult.getSession().isRememberMe()) createRememberMeCookie(authResult.getUser().getUsername(), session.getContext().getUri(), session);
return authResult; return authResult;
} }

View file

@ -17,7 +17,7 @@
package org.keycloak.services.managers; package org.keycloak.services.managers;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.OAuth2Constants; import org.keycloak.OAuth2Constants;
import org.keycloak.TokenVerifier; import org.keycloak.TokenVerifier;
import org.keycloak.TokenVerifier.Predicate; import org.keycloak.TokenVerifier.Predicate;
@ -46,6 +46,7 @@ import org.keycloak.events.Errors;
import org.keycloak.events.EventBuilder; import org.keycloak.events.EventBuilder;
import org.keycloak.events.EventType; import org.keycloak.events.EventType;
import org.keycloak.forms.login.LoginFormsProvider; import org.keycloak.forms.login.LoginFormsProvider;
import org.keycloak.models.KeycloakContext;
import org.keycloak.models.SingleUseObjectKeyModel; import org.keycloak.models.SingleUseObjectKeyModel;
import org.keycloak.models.AuthenticatedClientSessionModel; import org.keycloak.models.AuthenticatedClientSessionModel;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
@ -229,7 +230,7 @@ public class AuthenticationManager {
AccessToken token = verifier.verify().getToken(); AccessToken token = verifier.verify().getToken();
UserSessionModel cookieSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSession(realm, token.getSessionState())); UserSessionModel cookieSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSession(realm, token.getSessionState()));
if (cookieSession == null || !cookieSession.getId().equals(userSession.getId())) return true; if (cookieSession == null || !cookieSession.getId().equals(userSession.getId())) return true;
expireIdentityCookie(realm, uriInfo, connection); expireIdentityCookie(realm, uriInfo, session);
return true; return true;
} catch (Exception e) { } catch (Exception e) {
return false; return false;
@ -686,8 +687,8 @@ public class AuthenticationManager {
checkUserSessionOnlyHasLoggedOutClients(realm, userSession, logoutAuthSession); checkUserSessionOnlyHasLoggedOutClients(realm, userSession, logoutAuthSession);
// For resolving artifact we don't need any cookie, all details are stored in session storage so we can remove // For resolving artifact we don't need any cookie, all details are stored in session storage so we can remove
expireIdentityCookie(realm, uriInfo, connection); expireIdentityCookie(realm, uriInfo, session);
expireRememberMeCookie(realm, uriInfo, connection); expireRememberMeCookie(realm, uriInfo, session);
String method = userSession.getNote(KEYCLOAK_LOGOUT_PROTOCOL); String method = userSession.getNote(KEYCLOAK_LOGOUT_PROTOCOL);
EventBuilder event = new EventBuilder(realm, session, connection); EventBuilder event = new EventBuilder(realm, session, connection);
@ -782,7 +783,7 @@ public class AuthenticationManager {
maxAge = realm.getSsoSessionMaxLifespanRememberMe() > 0 ? realm.getSsoSessionMaxLifespanRememberMe() : realm.getSsoSessionMaxLifespan(); maxAge = realm.getSsoSessionMaxLifespanRememberMe() > 0 ? realm.getSsoSessionMaxLifespanRememberMe() : realm.getSsoSessionMaxLifespan();
} }
logger.debugv("Create login cookie - name: {0}, path: {1}, max-age: {2}", KEYCLOAK_IDENTITY_COOKIE, cookiePath, maxAge); logger.debugv("Create login cookie - name: {0}, path: {1}, max-age: {2}", KEYCLOAK_IDENTITY_COOKIE, cookiePath, maxAge);
CookieHelper.addCookie(KEYCLOAK_IDENTITY_COOKIE, encoded, cookiePath, null, null, maxAge, secureOnly, true, SameSiteAttributeValue.NONE); CookieHelper.addCookie(KEYCLOAK_IDENTITY_COOKIE, encoded, cookiePath, null, null, maxAge, secureOnly, true, SameSiteAttributeValue.NONE, keycloakSession);
//builder.cookie(new NewCookie(cookieName, encoded, cookiePath, null, null, maxAge, secureOnly));// todo httponly , true); //builder.cookie(new NewCookie(cookieName, encoded, cookiePath, null, null, maxAge, secureOnly));// todo httponly , true);
// With user-storage providers, user ID can contain special characters, which need to be encoded // With user-storage providers, user ID can contain special characters, which need to be encoded
@ -793,17 +794,20 @@ public class AuthenticationManager {
// THIS SHOULD NOT BE A HTTPONLY COOKIE! It is used for OpenID Connect Iframe Session support! // THIS SHOULD NOT BE A HTTPONLY COOKIE! It is used for OpenID Connect Iframe Session support!
// Max age should be set to the max lifespan of the session as it's used to invalidate old-sessions on re-login // Max age should be set to the max lifespan of the session as it's used to invalidate old-sessions on re-login
int sessionCookieMaxAge = session.isRememberMe() && realm.getSsoSessionMaxLifespanRememberMe() > 0 ? realm.getSsoSessionMaxLifespanRememberMe() : realm.getSsoSessionMaxLifespan(); int sessionCookieMaxAge = session.isRememberMe() && realm.getSsoSessionMaxLifespanRememberMe() > 0 ? realm.getSsoSessionMaxLifespanRememberMe() : realm.getSsoSessionMaxLifespan();
CookieHelper.addCookie(KEYCLOAK_SESSION_COOKIE, sessionCookieValue, cookiePath, null, null, sessionCookieMaxAge, secureOnly, false, SameSiteAttributeValue.NONE); CookieHelper.addCookie(KEYCLOAK_SESSION_COOKIE, sessionCookieValue, cookiePath, null, null, sessionCookieMaxAge, secureOnly, false, SameSiteAttributeValue.NONE, keycloakSession);
P3PHelper.addP3PHeader(); P3PHelper.addP3PHeader(keycloakSession);
} }
public static void createRememberMeCookie(RealmModel realm, String username, UriInfo uriInfo, ClientConnection connection) { public static void createRememberMeCookie(String username, UriInfo uriInfo, KeycloakSession session) {
KeycloakContext context = session.getContext();
RealmModel realm = context.getRealm();
ClientConnection connection = context.getConnection();
String path = getIdentityCookiePath(realm, uriInfo); String path = getIdentityCookiePath(realm, uriInfo);
boolean secureOnly = realm.getSslRequired().isRequired(connection); boolean secureOnly = realm.getSslRequired().isRequired(connection);
// remember me cookie should be persistent (hardcoded to 365 days for now) // remember me cookie should be persistent (hardcoded to 365 days for now)
//NewCookie cookie = new NewCookie(KEYCLOAK_REMEMBER_ME, "true", path, null, null, realm.getCentralLoginLifespan(), secureOnly);// todo httponly , true); //NewCookie cookie = new NewCookie(KEYCLOAK_REMEMBER_ME, "true", path, null, null, realm.getCentralLoginLifespan(), secureOnly);// todo httponly , true);
try { try {
CookieHelper.addCookie(KEYCLOAK_REMEMBER_ME, "username:" + URLEncoder.encode(username, "UTF-8"), path, null, null, 31536000, secureOnly, true); CookieHelper.addCookie(KEYCLOAK_REMEMBER_ME, "username:" + URLEncoder.encode(username, "UTF-8"), path, null, null, 31536000, secureOnly, true, session);
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
throw new RuntimeException("Failed to urlencode", e); throw new RuntimeException("Failed to urlencode", e);
} }
@ -827,37 +831,40 @@ public class AuthenticationManager {
return null; return null;
} }
public static void expireIdentityCookie(RealmModel realm, UriInfo uriInfo, ClientConnection connection) { public static void expireIdentityCookie(RealmModel realm, UriInfo uriInfo, KeycloakSession session) {
ClientConnection connection = session.getContext().getConnection();
logger.debug("Expiring identity cookie"); logger.debug("Expiring identity cookie");
String path = getIdentityCookiePath(realm, uriInfo); String path = getIdentityCookiePath(realm, uriInfo);
expireCookie(realm, KEYCLOAK_IDENTITY_COOKIE, path, true, connection, SameSiteAttributeValue.NONE); expireCookie(realm, KEYCLOAK_IDENTITY_COOKIE, path, true, connection, SameSiteAttributeValue.NONE, session);
expireCookie(realm, KEYCLOAK_SESSION_COOKIE, path, false, connection, SameSiteAttributeValue.NONE); expireCookie(realm, KEYCLOAK_SESSION_COOKIE, path, false, connection, SameSiteAttributeValue.NONE, session);
String oldPath = getOldCookiePath(realm, uriInfo); String oldPath = getOldCookiePath(realm, uriInfo);
expireCookie(realm, KEYCLOAK_IDENTITY_COOKIE, oldPath, true, connection, SameSiteAttributeValue.NONE); expireCookie(realm, KEYCLOAK_IDENTITY_COOKIE, oldPath, true, connection, SameSiteAttributeValue.NONE, session);
expireCookie(realm, KEYCLOAK_SESSION_COOKIE, oldPath, false, connection, SameSiteAttributeValue.NONE); expireCookie(realm, KEYCLOAK_SESSION_COOKIE, oldPath, false, connection, SameSiteAttributeValue.NONE, session);
} }
public static void expireOldIdentityCookie(RealmModel realm, UriInfo uriInfo, ClientConnection connection) { public static void expireOldIdentityCookie(RealmModel realm, UriInfo uriInfo, KeycloakSession session) {
ClientConnection connection = session.getContext().getConnection();
logger.debug("Expiring old identity cookie with wrong path"); logger.debug("Expiring old identity cookie with wrong path");
String oldPath = getOldCookiePath(realm, uriInfo); String oldPath = getOldCookiePath(realm, uriInfo);
expireCookie(realm, KEYCLOAK_IDENTITY_COOKIE, oldPath, true, connection, SameSiteAttributeValue.NONE); expireCookie(realm, KEYCLOAK_IDENTITY_COOKIE, oldPath, true, connection, SameSiteAttributeValue.NONE, session);
expireCookie(realm, KEYCLOAK_SESSION_COOKIE, oldPath, false, connection, SameSiteAttributeValue.NONE); expireCookie(realm, KEYCLOAK_SESSION_COOKIE, oldPath, false, connection, SameSiteAttributeValue.NONE, session);
} }
public static void expireRememberMeCookie(RealmModel realm, UriInfo uriInfo, ClientConnection connection) { public static void expireRememberMeCookie(RealmModel realm, UriInfo uriInfo, KeycloakSession session) {
ClientConnection connection = session.getContext().getConnection();
logger.debug("Expiring remember me cookie"); logger.debug("Expiring remember me cookie");
String path = getIdentityCookiePath(realm, uriInfo); String path = getIdentityCookiePath(realm, uriInfo);
String cookieName = KEYCLOAK_REMEMBER_ME; String cookieName = KEYCLOAK_REMEMBER_ME;
expireCookie(realm, cookieName, path, true, connection, null); expireCookie(realm, cookieName, path, true, connection, null, session);
} }
public static void expireOldAuthSessionCookie(RealmModel realm, UriInfo uriInfo, ClientConnection connection) { public static void expireOldAuthSessionCookie(RealmModel realm, UriInfo uriInfo, KeycloakSession session) {
logger.debugv("Expire {1} cookie .", AuthenticationSessionManager.AUTH_SESSION_ID); logger.debugv("Expire {1} cookie .", AuthenticationSessionManager.AUTH_SESSION_ID);
ClientConnection connection = session.getContext().getConnection();
String oldPath = getOldCookiePath(realm, uriInfo); String oldPath = getOldCookiePath(realm, uriInfo);
expireCookie(realm, AuthenticationSessionManager.AUTH_SESSION_ID, oldPath, true, connection, SameSiteAttributeValue.NONE); expireCookie(realm, AuthenticationSessionManager.AUTH_SESSION_ID, oldPath, true, connection, SameSiteAttributeValue.NONE, session);
} }
protected static String getIdentityCookiePath(RealmModel realm, UriInfo uriInfo) { protected static String getIdentityCookiePath(RealmModel realm, UriInfo uriInfo) {
@ -880,10 +887,10 @@ public class AuthenticationManager {
return uri.getRawPath(); return uri.getRawPath();
} }
public static void expireCookie(RealmModel realm, String cookieName, String path, boolean httpOnly, ClientConnection connection, SameSiteAttributeValue sameSite) { public static void expireCookie(RealmModel realm, String cookieName, String path, boolean httpOnly, ClientConnection connection, SameSiteAttributeValue sameSite, KeycloakSession session) {
logger.debugf("Expiring cookie: %s path: %s", cookieName, path); logger.debugf("Expiring cookie: %s path: %s", cookieName, path);
boolean secureOnly = realm.getSslRequired().isRequired(connection);; boolean secureOnly = realm.getSslRequired().isRequired(connection);;
CookieHelper.addCookie(cookieName, "", path, null, "Expiring cookie", 0, secureOnly, httpOnly, sameSite); CookieHelper.addCookie(cookieName, "", path, null, "Expiring cookie", 0, secureOnly, httpOnly, sameSite, session);
} }
public AuthResult authenticateIdentityCookie(KeycloakSession session, RealmModel realm) { public AuthResult authenticateIdentityCookie(KeycloakSession session, RealmModel realm) {
@ -900,8 +907,8 @@ public class AuthenticationManager {
String tokenString = cookie.getValue(); String tokenString = cookie.getValue();
AuthResult authResult = verifyIdentityToken(session, realm, session.getContext().getUri(), session.getContext().getConnection(), checkActive, false, null, true, tokenString, session.getContext().getRequestHeaders(), VALIDATE_IDENTITY_COOKIE); AuthResult authResult = verifyIdentityToken(session, realm, session.getContext().getUri(), session.getContext().getConnection(), checkActive, false, null, true, tokenString, session.getContext().getRequestHeaders(), VALIDATE_IDENTITY_COOKIE);
if (authResult == null) { if (authResult == null) {
expireIdentityCookie(realm, session.getContext().getUri(), session.getContext().getConnection()); expireIdentityCookie(realm, session.getContext().getUri(), session);
expireOldIdentityCookie(realm, session.getContext().getUri(), session.getContext().getConnection()); expireOldIdentityCookie(realm, session.getContext().getUri(), session);
return null; return null;
} }
authResult.getSession().setLastSessionRefresh(Time.currentTime()); authResult.getSession().setLastSessionRefresh(Time.currentTime());
@ -949,9 +956,9 @@ public class AuthenticationManager {
createLoginCookie(session, realm, userSession.getUser(), userSession, uriInfo, clientConnection); createLoginCookie(session, realm, userSession.getUser(), userSession, uriInfo, clientConnection);
if (userSession.getState() != UserSessionModel.State.LOGGED_IN) userSession.setState(UserSessionModel.State.LOGGED_IN); if (userSession.getState() != UserSessionModel.State.LOGGED_IN) userSession.setState(UserSessionModel.State.LOGGED_IN);
if (userSession.isRememberMe()) { if (userSession.isRememberMe()) {
createRememberMeCookie(realm, userSession.getLoginUsername(), uriInfo, clientConnection); createRememberMeCookie(userSession.getLoginUsername(), uriInfo, session);
} else { } else {
expireRememberMeCookie(realm, uriInfo, clientConnection); expireRememberMeCookie(realm, uriInfo, session);
} }
AuthenticatedClientSessionModel clientSession = clientSessionCtx.getClientSession(); AuthenticatedClientSessionModel clientSession = clientSessionCtx.getClientSession();

View file

@ -149,7 +149,7 @@ public class AuthenticationSessionManager {
StickySessionEncoderProvider encoder = session.getProvider(StickySessionEncoderProvider.class); StickySessionEncoderProvider encoder = session.getProvider(StickySessionEncoderProvider.class);
String encodedAuthSessionId = encoder.encodeSessionId(authSessionId); String encodedAuthSessionId = encoder.encodeSessionId(authSessionId);
CookieHelper.addCookie(AUTH_SESSION_ID, encodedAuthSessionId, cookiePath, null, null, -1, sslRequired, true, SameSiteAttributeValue.NONE); CookieHelper.addCookie(AUTH_SESSION_ID, encodedAuthSessionId, cookiePath, null, null, -1, sslRequired, true, SameSiteAttributeValue.NONE, session);
log.debugf("Set AUTH_SESSION_ID cookie with value %s", encodedAuthSessionId); log.debugf("Set AUTH_SESSION_ID cookie with value %s", encodedAuthSessionId);
} }
@ -184,10 +184,10 @@ public class AuthenticationSessionManager {
* @return list of the values of AUTH_SESSION_ID cookies. It is assumed that values could be encoded with route added (EG. "5e161e00-d426-4ea6-98e9-52eb9844e2d7.node1" ) * @return list of the values of AUTH_SESSION_ID cookies. It is assumed that values could be encoded with route added (EG. "5e161e00-d426-4ea6-98e9-52eb9844e2d7.node1" )
*/ */
List<String> getAuthSessionCookies(RealmModel realm) { List<String> getAuthSessionCookies(RealmModel realm) {
Set<String> cookiesVal = CookieHelper.getCookieValue(AUTH_SESSION_ID); Set<String> cookiesVal = CookieHelper.getCookieValue(session, AUTH_SESSION_ID);
if (cookiesVal.size() > 1) { if (cookiesVal.size() > 1) {
AuthenticationManager.expireOldAuthSessionCookie(realm, session.getContext().getUri(), session.getContext().getConnection()); AuthenticationManager.expireOldAuthSessionCookie(realm, session.getContext().getUri(), session);
} }
List<String> authSessionIds = cookiesVal.stream().limit(AUTH_SESSION_COOKIE_LIMIT).collect(Collectors.toList()); List<String> authSessionIds = cookiesVal.stream().limit(AUTH_SESSION_COOKIE_LIMIT).collect(Collectors.toList());
@ -208,9 +208,8 @@ public class AuthenticationSessionManager {
// expire restart cookie // expire restart cookie
if (expireRestartCookie) { if (expireRestartCookie) {
ClientConnection clientConnection = session.getContext().getConnection();
UriInfo uriInfo = session.getContext().getUri(); UriInfo uriInfo = session.getContext().getUri();
RestartLoginCookie.expireRestartCookie(realm, clientConnection, uriInfo); RestartLoginCookie.expireRestartCookie(realm, uriInfo, session);
} }
} }

View file

@ -18,7 +18,7 @@ package org.keycloak.services.resources;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.BadRequestException; import org.jboss.resteasy.spi.BadRequestException;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.AbstractOAuthClient; import org.keycloak.AbstractOAuthClient;
import org.keycloak.OAuth2Constants; import org.keycloak.OAuth2Constants;
import org.keycloak.OAuthErrorException; import org.keycloak.OAuthErrorException;
@ -72,7 +72,7 @@ public abstract class AbstractSecuredLocalService {
this.realm = session.getContext().getRealm(); this.realm = session.getContext().getRealm();
this.clientConnection = session.getContext().getConnection(); this.clientConnection = session.getContext().getConnection();
this.client = client; this.client = client;
this.request = session.getContext().getContextObject(HttpRequest.class); this.request = session.getContext().getHttpRequest();
this.headers = session.getContext().getRequestHeaders(); this.headers = session.getContext().getRequestHeaders();
} }

View file

@ -18,7 +18,7 @@ package org.keycloak.services.resources;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.BadRequestException; import org.jboss.resteasy.spi.BadRequestException;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import javax.ws.rs.NotAuthorizedException; import javax.ws.rs.NotAuthorizedException;
import org.keycloak.OAuthErrorException; import org.keycloak.OAuthErrorException;
import org.keycloak.common.ClientConnection; import org.keycloak.common.ClientConnection;
@ -69,7 +69,7 @@ public class ClientsManagementService {
this.clientConnection = session.getContext().getConnection(); this.clientConnection = session.getContext().getConnection();
this.realm = session.getContext().getRealm(); this.realm = session.getContext().getRealm();
this.event = event; this.event = event;
this.request = session.getContext().getContextObject(HttpRequest.class); this.request = session.getContext().getHttpRequest();
this.headers = session.getContext().getRequestHeaders(); this.headers = session.getContext().getRequestHeaders();
} }

View file

@ -25,9 +25,9 @@ import java.util.function.BiConsumer;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.Response.ResponseBuilder;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.jboss.resteasy.spi.HttpResponse;
import org.keycloak.common.util.CollectionUtil; import org.keycloak.common.util.CollectionUtil;
import org.keycloak.http.HttpResponse;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.protocol.oidc.utils.WebOriginsUtils; import org.keycloak.protocol.oidc.utils.WebOriginsUtils;
@ -141,11 +141,11 @@ public class Cors {
} }
public void build(HttpResponse response) { public void build(HttpResponse response) {
build(response.getOutputHeaders()::add); build(response::addHeader);
logger.debug("Added CORS headers to response"); logger.debug("Added CORS headers to response");
} }
public void build(BiConsumer<String, Object> addHeader) { public void build(BiConsumer<String, String> addHeader) {
String origin = request.getHttpHeaders().getRequestHeaders().getFirst(ORIGIN_HEADER); String origin = request.getHttpHeaders().getRequestHeaders().getFirst(ORIGIN_HEADER);
if (origin == null) { if (origin == null) {
logger.trace("No origin header ignoring"); logger.trace("No origin header ignoring");
@ -184,7 +184,7 @@ public class Cors {
} }
if (preflight) { if (preflight) {
addHeader.accept(ACCESS_CONTROL_MAX_AGE, DEFAULT_MAX_AGE); addHeader.accept(ACCESS_CONTROL_MAX_AGE, String.valueOf(DEFAULT_MAX_AGE));
} }
} }

View file

@ -18,8 +18,7 @@ package org.keycloak.services.resources;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.OAuthErrorException; import org.keycloak.OAuthErrorException;
import org.keycloak.authentication.AuthenticationProcessor; import org.keycloak.authentication.AuthenticationProcessor;
import org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator; import org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator;
@ -151,7 +150,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
if (realmModel == null) { if (realmModel == null) {
throw new IllegalArgumentException("Realm can not be null."); throw new IllegalArgumentException("Realm can not be null.");
} }
this.request = session.getContext().getContextObject(HttpRequest.class); this.request = session.getContext().getHttpRequest();
this.headers = session.getContext().getRequestHeaders(); this.headers = session.getContext().getRequestHeaders();
} }
@ -1207,7 +1206,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
if (errorMessage != null) processor.setForwardedErrorMessage(new FormMessage(null, errorMessage)); if (errorMessage != null) processor.setForwardedErrorMessage(new FormMessage(null, errorMessage));
try { try {
CacheControlUtil.noBackButtonCacheControlHeader(); CacheControlUtil.noBackButtonCacheControlHeader(session);
return processor.authenticate(); return processor.authenticate();
} catch (Exception e) { } catch (Exception e) {
return processor.handleBrowserException(e); return processor.handleBrowserException(e);

View file

@ -17,7 +17,6 @@
package org.keycloak.services.resources; package org.keycloak.services.resources;
import org.jboss.resteasy.spi.HttpRequest;
import org.keycloak.common.Version; import org.keycloak.common.Version;
import org.keycloak.encoding.ResourceEncodingHelper; import org.keycloak.encoding.ResourceEncodingHelper;
import org.keycloak.encoding.ResourceEncodingProvider; import org.keycloak.encoding.ResourceEncodingProvider;
@ -124,7 +123,7 @@ public class JsResource {
} }
String contentType = "text/javascript"; String contentType = "text/javascript";
Cors cors = Cors.add(session.getContext().getContextObject(HttpRequest.class)).allowAllOrigins(); Cors cors = Cors.add(session.getContext().getHttpRequest()).allowAllOrigins();
ResourceEncodingProvider encodingProvider = ResourceEncodingHelper.getResourceEncodingProvider(session, contentType); ResourceEncodingProvider encodingProvider = ResourceEncodingHelper.getResourceEncodingProvider(session, contentType);

View file

@ -17,7 +17,7 @@
package org.keycloak.services.resources; package org.keycloak.services.resources;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.OAuth2Constants; import org.keycloak.OAuth2Constants;
import org.keycloak.TokenVerifier; import org.keycloak.TokenVerifier;
import org.keycloak.authentication.AuthenticationFlowException; import org.keycloak.authentication.AuthenticationFlowException;
@ -29,7 +29,6 @@ import org.keycloak.authentication.RequiredActionFactory;
import org.keycloak.authentication.RequiredActionProvider; import org.keycloak.authentication.RequiredActionProvider;
import org.keycloak.authentication.actiontoken.ActionTokenContext; import org.keycloak.authentication.actiontoken.ActionTokenContext;
import org.keycloak.authentication.actiontoken.ActionTokenHandler; import org.keycloak.authentication.actiontoken.ActionTokenHandler;
import org.keycloak.common.util.Resteasy;
import org.keycloak.models.DefaultActionTokenKey; import org.keycloak.models.DefaultActionTokenKey;
import org.keycloak.authentication.actiontoken.ExplainedTokenVerificationException; import org.keycloak.authentication.actiontoken.ExplainedTokenVerificationException;
import org.keycloak.authentication.actiontoken.resetcred.ResetCredentialsActionTokenHandler; import org.keycloak.authentication.actiontoken.resetcred.ResetCredentialsActionTokenHandler;
@ -177,8 +176,8 @@ public class LoginActionsService {
this.clientConnection = session.getContext().getConnection(); this.clientConnection = session.getContext().getConnection();
this.realm = session.getContext().getRealm(); this.realm = session.getContext().getRealm();
this.event = event; this.event = event;
CacheControlUtil.noBackButtonCacheControlHeader(); CacheControlUtil.noBackButtonCacheControlHeader(session);
this.request = session.getContext().getContextObject(HttpRequest.class); this.request = session.getContext().getHttpRequest();
this.headers = session.getContext().getRequestHeaders(); this.headers = session.getContext().getRequestHeaders();
} }
@ -702,7 +701,7 @@ public class LoginActionsService {
processLocaleParam(authSession); processLocaleParam(authSession);
AuthenticationManager.expireIdentityCookie(realm, session.getContext().getUri(), clientConnection); AuthenticationManager.expireIdentityCookie(realm, session.getContext().getUri(), session);
return processRegistration(checks.isActionRequest(), execution, authSession, null); return processRegistration(checks.isActionRequest(), execution, authSession, null);
} }

View file

@ -23,8 +23,7 @@ import java.net.URI;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.authentication.AuthenticationProcessor;
import org.keycloak.common.ClientConnection; import org.keycloak.common.ClientConnection;
import org.keycloak.events.Errors; import org.keycloak.events.Errors;
import org.keycloak.events.EventBuilder; import org.keycloak.events.EventBuilder;

View file

@ -18,8 +18,8 @@ package org.keycloak.services.resources;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.jboss.resteasy.spi.HttpResponse; import org.keycloak.http.HttpResponse;
import org.keycloak.common.util.PemUtils; import org.keycloak.common.util.PemUtils;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
@ -55,8 +55,8 @@ public class PublicRealmResource {
public PublicRealmResource(KeycloakSession session) { public PublicRealmResource(KeycloakSession session) {
this.session = session; this.session = session;
this.realm = session.getContext().getRealm(); this.realm = session.getContext().getRealm();
this.request = session.getContext().getContextObject(HttpRequest.class); this.request = session.getContext().getHttpRequest();
this.response = session.getContext().getContextObject(HttpResponse.class); this.response = session.getContext().getHttpResponse();
} }
/** /**

View file

@ -17,7 +17,7 @@
package org.keycloak.services.resources; package org.keycloak.services.resources;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.OAuthErrorException; import org.keycloak.OAuthErrorException;
import org.keycloak.authorization.AuthorizationProvider; import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.AuthorizationService; import org.keycloak.authorization.AuthorizationService;
@ -213,7 +213,7 @@ public class RealmsResource {
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public Response getVersionPreflight(final @PathParam("realm") String name, public Response getVersionPreflight(final @PathParam("realm") String name,
final @PathParam("provider") String providerName) { final @PathParam("provider") String providerName) {
return Cors.add(session.getContext().getContextObject(HttpRequest.class), Response.ok()).allowedMethods("GET").preflight().auth().build(); return Cors.add(session.getContext().getHttpRequest(), Response.ok()).allowedMethods("GET").preflight().auth().build();
} }
@GET @GET
@ -236,7 +236,7 @@ public class RealmsResource {
if (wellKnown != null) { if (wellKnown != null) {
ResponseBuilder responseBuilder = Response.ok(wellKnown.getConfig()).cacheControl(CacheControlUtil.noCache()); ResponseBuilder responseBuilder = Response.ok(wellKnown.getConfig()).cacheControl(CacheControlUtil.noCache());
return Cors.add(session.getContext().getContextObject(HttpRequest.class), responseBuilder).allowedOrigins("*").auth().build(); return Cors.add(session.getContext().getHttpRequest(), responseBuilder).allowedOrigins("*").auth().build();
} }
throw new NotFoundException(); throw new NotFoundException();
@ -274,7 +274,7 @@ public class RealmsResource {
private void checkSsl(RealmModel realm) { private void checkSsl(RealmModel realm) {
if (!session.getContext().getUri().getBaseUri().getScheme().equals("https") if (!session.getContext().getUri().getBaseUri().getScheme().equals("https")
&& realm.getSslRequired().isRequired(session.getContext().getConnection())) { && realm.getSslRequired().isRequired(session.getContext().getConnection())) {
HttpRequest request = session.getContext().getContextObject(HttpRequest.class); HttpRequest request = session.getContext().getHttpRequest();
Cors cors = Cors.add(request).auth().allowedMethods(request.getHttpMethod()).auth().exposedHeaders(Cors.ACCESS_CONTROL_ALLOW_METHODS); Cors cors = Cors.add(request).auth().allowedMethods(request.getHttpMethod()).auth().exposedHeaders(Cors.ACCESS_CONTROL_ALLOW_METHODS);
throw new CorsErrorResponseException(cors.allowAllOrigins(), OAuthErrorException.INVALID_REQUEST, "HTTPS required", throw new CorsErrorResponseException(cors.allowAllOrigins(), OAuthErrorException.INVALID_REQUEST, "HTTPS required",
Response.Status.FORBIDDEN); Response.Status.FORBIDDEN);

View file

@ -25,7 +25,7 @@ import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.authentication.AuthenticationProcessor; import org.keycloak.authentication.AuthenticationProcessor;
import org.keycloak.common.ClientConnection; import org.keycloak.common.ClientConnection;
import org.keycloak.common.util.ObjectUtil; import org.keycloak.common.util.ObjectUtil;
@ -257,7 +257,7 @@ public class SessionCodeChecks {
// Allow refresh, but rewrite browser history // Allow refresh, but rewrite browser history
if (execution == null && lastExecFromSession != null) { if (execution == null && lastExecFromSession != null) {
logger.debugf("Parameter 'execution' is not in the request, but flow wasn't changed. Will update browser history"); logger.debugf("Parameter 'execution' is not in the request, but flow wasn't changed. Will update browser history");
request.setAttribute(BrowserHistoryHelper.SHOULD_UPDATE_BROWSER_HISTORY, true); session.setAttribute(BrowserHistoryHelper.SHOULD_UPDATE_BROWSER_HISTORY, true);
} }
return true; return true;

View file

@ -262,14 +262,14 @@ public class WelcomeResource {
String stateChecker = Base64Url.encode(SecretGenerator.getInstance().randomBytes()); String stateChecker = Base64Url.encode(SecretGenerator.getInstance().randomBytes());
String cookiePath = session.getContext().getUri().getPath(); String cookiePath = session.getContext().getUri().getPath();
boolean secureOnly = session.getContext().getUri().getRequestUri().getScheme().equalsIgnoreCase("https"); boolean secureOnly = session.getContext().getUri().getRequestUri().getScheme().equalsIgnoreCase("https");
CookieHelper.addCookie(KEYCLOAK_STATE_CHECKER, stateChecker, cookiePath, null, null, 300, secureOnly, true); CookieHelper.addCookie(KEYCLOAK_STATE_CHECKER, stateChecker, cookiePath, null, null, 300, secureOnly, true, session);
return stateChecker; return stateChecker;
} }
private void expireCsrfCookie() { private void expireCsrfCookie() {
String cookiePath = session.getContext().getUri().getPath(); String cookiePath = session.getContext().getUri().getPath();
boolean secureOnly = session.getContext().getUri().getRequestUri().getScheme().equalsIgnoreCase("https"); boolean secureOnly = session.getContext().getUri().getRequestUri().getScheme().equalsIgnoreCase("https");
CookieHelper.addCookie(KEYCLOAK_STATE_CHECKER, "", cookiePath, null, null, 0, secureOnly, true); CookieHelper.addCookie(KEYCLOAK_STATE_CHECKER, "", cookiePath, null, null, 0, secureOnly, true, session);
} }
private void csrfCheck(final MultivaluedMap<String, String> formData) { private void csrfCheck(final MultivaluedMap<String, String> formData) {

View file

@ -17,8 +17,8 @@
package org.keycloak.services.resources.account; package org.keycloak.services.resources.account;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.jboss.resteasy.spi.HttpResponse; import org.keycloak.http.HttpResponse;
import org.keycloak.common.enums.AccountRestApiVersion; import org.keycloak.common.enums.AccountRestApiVersion;
import org.keycloak.events.EventBuilder; import org.keycloak.events.EventBuilder;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
@ -60,8 +60,8 @@ public class AccountLoader {
public AccountLoader(KeycloakSession session, EventBuilder event) { public AccountLoader(KeycloakSession session, EventBuilder event) {
this.session = session; this.session = session;
this.event = event; this.event = event;
this.request = session.getContext().getContextObject(HttpRequest.class); this.request = session.getContext().getHttpRequest();
this.response = session.getContext().getContextObject(HttpResponse.class); this.response = session.getContext().getHttpResponse();
} }
@Path("/") @Path("/")
@ -69,7 +69,7 @@ public class AccountLoader {
RealmModel realm = session.getContext().getRealm(); RealmModel realm = session.getContext().getRealm();
ClientModel client = getAccountManagementClient(realm); ClientModel client = getAccountManagementClient(realm);
HttpRequest request = session.getContext().getContextObject(HttpRequest.class); HttpRequest request = session.getContext().getHttpRequest();
HttpHeaders headers = session.getContext().getRequestHeaders(); HttpHeaders headers = session.getContext().getRequestHeaders();
MediaType content = headers.getMediaType(); MediaType content = headers.getMediaType();
List<MediaType> accepts = headers.getAcceptableMediaTypes(); List<MediaType> accepts = headers.getAcceptableMediaTypes();

View file

@ -49,7 +49,7 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.common.ClientConnection; import org.keycloak.common.ClientConnection;
import org.keycloak.common.Profile; import org.keycloak.common.Profile;
import org.keycloak.common.enums.AccountRestApiVersion; import org.keycloak.common.enums.AccountRestApiVersion;
@ -124,7 +124,7 @@ public class AccountRestService {
this.locale = session.getContext().resolveLocale(user); this.locale = session.getContext().resolveLocale(user);
this.version = version; this.version = version;
event.client(auth.getClient()).user(auth.getUser()); event.client(auth.getClient()).user(auth.getUser());
this.request = session.getContext().getContextObject(HttpRequest.class); this.request = session.getContext().getHttpRequest();
this.headers = session.getContext().getRequestHeaders(); this.headers = session.getContext().getRequestHeaders();
} }

View file

@ -1,6 +1,6 @@
package org.keycloak.services.resources.account; package org.keycloak.services.resources.account;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.services.resources.Cors; import org.keycloak.services.resources.Cors;
import javax.ws.rs.OPTIONS; import javax.ws.rs.OPTIONS;

View file

@ -37,7 +37,7 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriBuilder;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.broker.social.SocialIdentityProvider; import org.keycloak.broker.social.SocialIdentityProvider;
import org.keycloak.common.util.Base64Url; import org.keycloak.common.util.Base64Url;
import org.keycloak.events.Details; import org.keycloak.events.Details;

View file

@ -25,7 +25,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.authorization.AuthorizationProvider; import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.model.PermissionTicket; import org.keycloak.authorization.model.PermissionTicket;
import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.model.ResourceServer;

View file

@ -34,7 +34,7 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.authorization.model.PermissionTicket; import org.keycloak.authorization.model.PermissionTicket;
import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.models.AccountRoles; import org.keycloak.models.AccountRoles;

View file

@ -34,7 +34,7 @@ import java.util.function.BiFunction;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.authorization.model.PermissionTicket; import org.keycloak.authorization.model.PermissionTicket;
import org.keycloak.authorization.store.PermissionTicketStore; import org.keycloak.authorization.store.PermissionTicketStore;
import org.keycloak.common.util.KeycloakUriBuilder; import org.keycloak.common.util.KeycloakUriBuilder;

View file

@ -19,8 +19,8 @@ package org.keycloak.services.resources.admin;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.jboss.resteasy.spi.HttpResponse; import org.keycloak.http.HttpResponse;
import javax.ws.rs.NotFoundException; import javax.ws.rs.NotFoundException;
import org.keycloak.Config; import org.keycloak.Config;
import org.keycloak.common.ClientConnection; import org.keycloak.common.ClientConnection;
@ -85,8 +85,8 @@ public class AdminConsole {
this.session = session; this.session = session;
this.realm = session.getContext().getRealm(); this.realm = session.getContext().getRealm();
this.clientConnection = session.getContext().getConnection(); this.clientConnection = session.getContext().getConnection();
this.request = session.getContext().getContextObject(HttpRequest.class); this.request = session.getContext().getHttpRequest();
this.response = session.getContext().getContextObject(HttpResponse.class); this.response = session.getContext().getHttpResponse();
} }
public static class WhoAmI { public static class WhoAmI {

View file

@ -1,6 +1,6 @@
package org.keycloak.services.resources.admin; package org.keycloak.services.resources.admin;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.services.resources.Cors; import org.keycloak.services.resources.Cors;
import javax.ws.rs.OPTIONS; import javax.ws.rs.OPTIONS;

View file

@ -17,8 +17,8 @@
package org.keycloak.services.resources.admin; package org.keycloak.services.resources.admin;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.jboss.resteasy.spi.HttpResponse; import org.keycloak.http.HttpResponse;
import javax.ws.rs.NotFoundException; import javax.ws.rs.NotFoundException;
import javax.ws.rs.NotAuthorizedException; import javax.ws.rs.NotAuthorizedException;
import org.keycloak.common.Profile; import org.keycloak.common.Profile;
@ -258,11 +258,11 @@ public class AdminRoot {
} }
private HttpResponse getHttpResponse() { private HttpResponse getHttpResponse() {
return session.getContext().getContextObject(HttpResponse.class); return session.getContext().getHttpResponse();
} }
private HttpRequest getHttpRequest() { private HttpRequest getHttpRequest() {
return session.getContext().getContextObject(HttpRequest.class); return session.getContext().getHttpRequest();
} }
public static Theme getTheme(KeycloakSession session, RealmModel realm) throws IOException { public static Theme getTheme(KeycloakSession session, RealmModel realm) throws IOException {

View file

@ -17,7 +17,7 @@
package org.keycloak.services.resources.admin; package org.keycloak.services.resources.admin;
import org.jboss.resteasy.spi.HttpResponse; import org.keycloak.http.HttpResponse;
import org.keycloak.events.admin.OperationType; import org.keycloak.events.admin.OperationType;
import org.keycloak.events.admin.ResourceType; import org.keycloak.events.admin.ResourceType;
import org.keycloak.models.ClientInitialAccessModel; import org.keycloak.models.ClientInitialAccessModel;
@ -84,10 +84,10 @@ public class ClientInitialAccessResource {
String token = ClientRegistrationTokenUtils.createInitialAccessToken(session, realm, clientInitialAccessModel); String token = ClientRegistrationTokenUtils.createInitialAccessToken(session, realm, clientInitialAccessModel);
rep.setToken(token); rep.setToken(token);
HttpResponse response = session.getContext().getContextObject(HttpResponse.class); HttpResponse response = session.getContext().getHttpResponse();
response.setStatus(Response.Status.CREATED.getStatusCode()); response.setStatus(Response.Status.CREATED.getStatusCode());
response.getOutputHeaders().add(HttpHeaders.LOCATION, session.getContext().getUri().getAbsolutePathBuilder().path(clientInitialAccessModel.getId()).build().toString()); response.addHeader(HttpHeaders.LOCATION, session.getContext().getUri().getAbsolutePathBuilder().path(clientInitialAccessModel.getId()).build().toString());
return rep; return rep;
} }

View file

@ -27,8 +27,8 @@ import javax.ws.rs.core.Response;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.jboss.resteasy.spi.HttpResponse; import org.keycloak.http.HttpResponse;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.representations.idm.ClientPoliciesRepresentation; import org.keycloak.representations.idm.ClientPoliciesRepresentation;
@ -52,8 +52,8 @@ public class ClientPoliciesResource {
this.session = session; this.session = session;
this.realm = session.getContext().getRealm(); this.realm = session.getContext().getRealm();
this.auth = auth; this.auth = auth;
this.request = session.getContext().getContextObject(HttpRequest.class); this.request = session.getContext().getHttpRequest();
this.response = session.getContext().getContextObject(HttpResponse.class); this.response = session.getContext().getHttpResponse();
} }
@GET @GET

View file

@ -28,8 +28,8 @@ import javax.ws.rs.core.Response;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.jboss.resteasy.spi.HttpResponse; import org.keycloak.http.HttpResponse;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.representations.idm.ClientProfilesRepresentation; import org.keycloak.representations.idm.ClientProfilesRepresentation;
@ -53,8 +53,8 @@ public class ClientProfilesResource {
this.session = session; this.session = session;
this.realm = session.getContext().getRealm(); this.realm = session.getContext().getRealm();
this.auth = auth; this.auth = auth;
this.request = session.getContext().getContextObject(HttpRequest.class); this.request = session.getContext().getHttpRequest();
this.response = session.getContext().getContextObject(HttpResponse.class); this.response = session.getContext().getHttpResponse();
} }
@GET @GET

View file

@ -324,8 +324,8 @@ public class UserResource {
if (authenticatedRealm.getId().equals(realm.getId()) && sessionState != null) { if (authenticatedRealm.getId().equals(realm.getId()) && sessionState != null) {
sameRealm = true; sameRealm = true;
UserSessionModel userSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSession(authenticatedRealm, sessionState)); UserSessionModel userSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSession(authenticatedRealm, sessionState));
AuthenticationManager.expireIdentityCookie(realm, session.getContext().getUri(), clientConnection); AuthenticationManager.expireIdentityCookie(realm, session.getContext().getUri(), session);
AuthenticationManager.expireRememberMeCookie(realm, session.getContext().getUri(), clientConnection); AuthenticationManager.expireRememberMeCookie(realm, session.getContext().getUri(), session);
AuthenticationManager.backchannelLogout(session, authenticatedRealm, userSession, session.getContext().getUri(), clientConnection, headers, true); AuthenticationManager.backchannelLogout(session, authenticatedRealm, userSession, session.getContext().getUri(), clientConnection, headers, true);
} }
EventBuilder event = new EventBuilder(realm, session, clientConnection); EventBuilder event = new EventBuilder(realm, session, clientConnection);

View file

@ -24,7 +24,7 @@ import java.util.regex.Pattern;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.sessions.AuthenticationSessionModel; import org.keycloak.sessions.AuthenticationSessionModel;
import org.keycloak.utils.MediaType; import org.keycloak.utils.MediaType;
@ -54,12 +54,12 @@ public abstract class BrowserHistoryHelper {
public abstract Response loadSavedResponse(KeycloakSession session, AuthenticationSessionModel authSession); public abstract Response loadSavedResponse(KeycloakSession session, AuthenticationSessionModel authSession);
protected boolean shouldReplaceBrowserHistory(boolean actionRequest, HttpRequest httpRequest) { protected boolean shouldReplaceBrowserHistory(boolean actionRequest, KeycloakSession session) {
if (actionRequest) { if (actionRequest) {
return true; return true;
} }
Boolean flowChanged = (Boolean) httpRequest.getAttribute(SHOULD_UPDATE_BROWSER_HISTORY); Boolean flowChanged = (Boolean) session.getAttribute(SHOULD_UPDATE_BROWSER_HISTORY);
return (flowChanged != null && flowChanged); return (flowChanged != null && flowChanged);
} }
@ -81,7 +81,7 @@ public abstract class BrowserHistoryHelper {
@Override @Override
public Response saveResponseAndRedirect(KeycloakSession session, AuthenticationSessionModel authSession, Response response, boolean actionRequest, HttpRequest httpRequest) { public Response saveResponseAndRedirect(KeycloakSession session, AuthenticationSessionModel authSession, Response response, boolean actionRequest, HttpRequest httpRequest) {
if (!shouldReplaceBrowserHistory(actionRequest, httpRequest)) { if (!shouldReplaceBrowserHistory(actionRequest, session)) {
return response; return response;
} }
@ -144,7 +144,7 @@ public abstract class BrowserHistoryHelper {
@Override @Override
public Response saveResponseAndRedirect(KeycloakSession session, AuthenticationSessionModel authSession, Response response, boolean actionRequest, HttpRequest httpRequest) { public Response saveResponseAndRedirect(KeycloakSession session, AuthenticationSessionModel authSession, Response response, boolean actionRequest, HttpRequest httpRequest) {
if (!shouldReplaceBrowserHistory(actionRequest, httpRequest)) { if (!shouldReplaceBrowserHistory(actionRequest, session)) {
return response; return response;
} }

View file

@ -17,9 +17,10 @@
package org.keycloak.services.util; package org.keycloak.services.util;
import org.jboss.resteasy.spi.HttpResponse; import org.keycloak.http.HttpResponse;
import org.keycloak.Config; import org.keycloak.Config;
import org.keycloak.common.util.Resteasy; import org.keycloak.models.KeycloakContext;
import org.keycloak.models.KeycloakSession;
import javax.ws.rs.core.CacheControl; import javax.ws.rs.core.CacheControl;
@ -28,9 +29,10 @@ import javax.ws.rs.core.CacheControl;
*/ */
public class CacheControlUtil { public class CacheControlUtil {
public static void noBackButtonCacheControlHeader() { public static void noBackButtonCacheControlHeader(KeycloakSession session) {
HttpResponse response = Resteasy.getContextData(HttpResponse.class); KeycloakContext context = session.getContext();
response.getOutputHeaders().putSingle("Cache-Control", "no-store, must-revalidate, max-age=0"); HttpResponse response = context.getHttpResponse();
response.setHeader("Cache-Control", "no-store, must-revalidate, max-age=0");
} }
public static CacheControl getDefaultCacheControl() { public static CacheControl getDefaultCacheControl() {

View file

@ -18,10 +18,11 @@
package org.keycloak.services.util; package org.keycloak.services.util;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpResponse; import org.keycloak.http.HttpResponse;
import org.jboss.resteasy.util.CookieParser; import org.jboss.resteasy.util.CookieParser;
import org.keycloak.common.util.Resteasy; import org.keycloak.common.util.Resteasy;
import org.keycloak.common.util.ServerCookie; import org.keycloak.common.util.ServerCookie;
import org.keycloak.models.KeycloakSession;
import javax.ws.rs.core.Cookie; import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.HttpHeaders;
@ -55,7 +56,7 @@ public class CookieHelper {
* @param httpOnly * @param httpOnly
* @param sameSite * @param sameSite
*/ */
public static void addCookie(String name, String value, String path, String domain, String comment, int maxAge, boolean secure, boolean httpOnly, SameSiteAttributeValue sameSite) { public static void addCookie(String name, String value, String path, String domain, String comment, int maxAge, boolean secure, boolean httpOnly, SameSiteAttributeValue sameSite, KeycloakSession session) {
SameSiteAttributeValue sameSiteParam = sameSite; SameSiteAttributeValue sameSiteParam = sameSite;
// when expiring a cookie we shouldn't set the sameSite attribute; if we set e.g. SameSite=None when expiring a cookie, the new cookie (with maxAge == 0) // when expiring a cookie we shouldn't set the sameSite attribute; if we set e.g. SameSite=None when expiring a cookie, the new cookie (with maxAge == 0)
// might be rejected by the browser in some cases resulting in leaving the original cookie untouched; that can even prevent user from accessing their application // might be rejected by the browser in some cases resulting in leaving the original cookie untouched; that can even prevent user from accessing their application
@ -65,15 +66,15 @@ public class CookieHelper {
boolean secure_sameSite = sameSite == SameSiteAttributeValue.NONE || secure; // when SameSite=None, Secure attribute must be set boolean secure_sameSite = sameSite == SameSiteAttributeValue.NONE || secure; // when SameSite=None, Secure attribute must be set
HttpResponse response = Resteasy.getContextData(HttpResponse.class); HttpResponse response = session.getContext().getHttpResponse();
StringBuffer cookieBuf = new StringBuffer(); StringBuffer cookieBuf = new StringBuffer();
ServerCookie.appendCookieValue(cookieBuf, 1, name, value, path, domain, comment, maxAge, secure_sameSite, httpOnly, sameSite); ServerCookie.appendCookieValue(cookieBuf, 1, name, value, path, domain, comment, maxAge, secure_sameSite, httpOnly, sameSite);
String cookie = cookieBuf.toString(); String cookie = cookieBuf.toString();
response.getOutputHeaders().add(HttpHeaders.SET_COOKIE, cookie); response.addHeader(HttpHeaders.SET_COOKIE, cookie);
// a workaround for browser in older Apple OSs browsers ignore cookies with SameSite=None // a workaround for browser in older Apple OSs browsers ignore cookies with SameSite=None
if (sameSiteParam == SameSiteAttributeValue.NONE) { if (sameSiteParam == SameSiteAttributeValue.NONE) {
addCookie(name + LEGACY_COOKIE, value, path, domain, comment, maxAge, secure, httpOnly, null); addCookie(name + LEGACY_COOKIE, value, path, domain, comment, maxAge, secure, httpOnly, null, session);
} }
} }
@ -88,23 +89,23 @@ public class CookieHelper {
* @param secure * @param secure
* @param httpOnly * @param httpOnly
*/ */
public static void addCookie(String name, String value, String path, String domain, String comment, int maxAge, boolean secure, boolean httpOnly) { public static void addCookie(String name, String value, String path, String domain, String comment, int maxAge, boolean secure, boolean httpOnly, KeycloakSession session) {
addCookie(name, value, path, domain, comment, maxAge, secure, httpOnly, null); addCookie(name, value, path, domain, comment, maxAge, secure, httpOnly, null, session);
} }
public static Set<String> getCookieValue(String name) { public static Set<String> getCookieValue(KeycloakSession session, String name) {
Set<String> ret = getInternalCookieValue(name); Set<String> ret = getInternalCookieValue(session, name);
if (ret.size() == 0) { if (ret.size() == 0) {
String legacy = name + LEGACY_COOKIE; String legacy = name + LEGACY_COOKIE;
logger.debugv("Could not find any cookies with name '{0}', trying '{1}'", name, legacy); logger.debugv("Could not find any cookies with name '{0}', trying '{1}'", name, legacy);
ret = getInternalCookieValue(legacy); ret = getInternalCookieValue(session, legacy);
} }
return ret; return ret;
} }
private static Set<String> getInternalCookieValue(String name) { private static Set<String> getInternalCookieValue(KeycloakSession session, String name) {
HttpHeaders headers = Resteasy.getContextData(HttpHeaders.class); HttpHeaders headers = session.getContext().getHttpRequest().getHttpHeaders();
Set<String> cookiesVal = new HashSet<>(); Set<String> cookiesVal = new HashSet<>();
// check for cookies in the request headers // check for cookies in the request headers

View file

@ -7,7 +7,7 @@ import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.common.util.Base64Url; import org.keycloak.common.util.Base64Url;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.representations.AccessToken; import org.keycloak.representations.AccessToken;

View file

@ -17,8 +17,8 @@
package org.keycloak.services.util; package org.keycloak.services.util;
import org.jboss.resteasy.spi.HttpResponse; import org.keycloak.http.HttpResponse;
import org.keycloak.common.util.Resteasy; import org.keycloak.models.KeycloakSession;
/** /**
* IE requires P3P header to allow loading cookies from iframes when domain differs from main page (see KEYCLOAK-2828 for more details) * IE requires P3P header to allow loading cookies from iframes when domain differs from main page (see KEYCLOAK-2828 for more details)
@ -27,9 +27,9 @@ import org.keycloak.common.util.Resteasy;
*/ */
public class P3PHelper { public class P3PHelper {
public static void addP3PHeader() { public static void addP3PHeader(KeycloakSession session) {
HttpResponse response = Resteasy.getContextData(HttpResponse.class); HttpResponse response = session.getContext().getHttpResponse();
response.getOutputHeaders().putSingle("P3P", "CP=\"This is not a P3P policy!\""); response.setHeader("P3P", "CP=\"This is not a P3P policy!\"");
} }
} }

View file

@ -19,7 +19,7 @@
package org.keycloak.services.x509; package org.keycloak.services.x509;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.common.util.PemException; import org.keycloak.common.util.PemException;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;

View file

@ -19,7 +19,7 @@
package org.keycloak.services.x509; package org.keycloak.services.x509;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
/** /**
@ -34,8 +34,6 @@ public class DefaultClientCertificateLookup implements X509ClientCertificateLook
private static final Logger logger = Logger.getLogger(DefaultClientCertificateLookup.class); private static final Logger logger = Logger.getLogger(DefaultClientCertificateLookup.class);
public static final String JAVAX_SERVLET_REQUEST_X509_CERTIFICATE = "javax.servlet.request.X509Certificate";
public DefaultClientCertificateLookup() { public DefaultClientCertificateLookup() {
} }
@ -47,7 +45,7 @@ public class DefaultClientCertificateLookup implements X509ClientCertificateLook
@Override @Override
public X509Certificate[] getCertificateChain(HttpRequest httpRequest) { public X509Certificate[] getCertificateChain(HttpRequest httpRequest) {
X509Certificate[] certs = (X509Certificate[]) httpRequest.getAttribute(JAVAX_SERVLET_REQUEST_X509_CERTIFICATE); X509Certificate[] certs = httpRequest.getClientCertificateChain();
if (logger.isTraceEnabled() && certs != null) { if (logger.isTraceEnabled() && certs != null) {
for (X509Certificate cert : certs) { for (X509Certificate cert : certs) {
logger.tracef("Certificate's SubjectDN => \"%s\"", cert.getSubjectDN().getName()); logger.tracef("Certificate's SubjectDN => \"%s\"", cert.getSubjectDN().getName());

View file

@ -23,7 +23,7 @@ import java.util.Set;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.logging.Logger.Level; import org.jboss.logging.Logger.Level;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.common.crypto.CryptoIntegration; import org.keycloak.common.crypto.CryptoIntegration;
import org.keycloak.common.util.PemException; import org.keycloak.common.util.PemException;
import org.keycloak.common.util.PemUtils; import org.keycloak.common.util.PemUtils;

View file

@ -1,7 +1,7 @@
package org.keycloak.services.x509; package org.keycloak.services.x509;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.common.util.PemException; import org.keycloak.common.util.PemException;
import org.keycloak.common.util.PemUtils; import org.keycloak.common.util.PemUtils;

View file

@ -18,7 +18,7 @@
package org.keycloak.services.x509; package org.keycloak.services.x509;
import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.http.HttpRequest;
import org.keycloak.provider.Provider; import org.keycloak.provider.Provider;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;

View file

@ -13,7 +13,7 @@ AuthenticationFlowError = Java.type("org.keycloak.authentication.AuthenticationF
* user - current user {@see org.keycloak.models.UserModel} * user - current user {@see org.keycloak.models.UserModel}
* realm - current realm {@see org.keycloak.models.RealmModel} * realm - current realm {@see org.keycloak.models.RealmModel}
* session - current KeycloakSession {@see org.keycloak.models.KeycloakSession} * session - current KeycloakSession {@see org.keycloak.models.KeycloakSession}
* httpRequest - current HttpRequest {@see org.jboss.resteasy.spi.HttpRequest} * httpRequest - current HttpRequest {@see org.keycloak.http.HttpRequest}
* script - current script {@see org.keycloak.models.ScriptModel} * script - current script {@see org.keycloak.models.ScriptModel}
* authenticationSession - current authentication session {@see org.keycloak.sessions.AuthenticationSessionModel} * authenticationSession - current authentication session {@see org.keycloak.sessions.AuthenticationSessionModel}
* LOG - current logger {@see org.jboss.logging.Logger} * LOG - current logger {@see org.jboss.logging.Logger}

Some files were not shown because too many files have changed in this diff Show more