Remove remaining servlet filter adapter bits
Closes #29225 Signed-off-by: Douglas Palmer <dpalmer@redhat.com>
This commit is contained in:
parent
e0176a7e31
commit
8a0322cc13
10 changed files with 0 additions and 1756 deletions
|
@ -1,141 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
<!--
|
|
||||||
~ Copyright 2016 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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
|
||||||
<parent>
|
|
||||||
<artifactId>keycloak-parent</artifactId>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<version>999.0.0-SNAPSHOT</version>
|
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
|
||||||
</parent>
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<artifactId>keycloak-saml-jakarta-servlet-filter-adapter</artifactId>
|
|
||||||
<name>Keycloak SAML Jakarta Servlet Filter</name>
|
|
||||||
<description/>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
NOTE: This maven module is generated using original: servlet-filter
|
|
||||||
@see: ${jakarta-transformer-sources}
|
|
||||||
Reason is the transition to Jakarta APIs.
|
|
||||||
-->
|
|
||||||
<properties>
|
|
||||||
<jakarta-transformer-sources>${project.basedir}/../servlet-filter/src</jakarta-transformer-sources>
|
|
||||||
<jakarta-transformer-target>${project.basedir}/src</jakarta-transformer-target>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jboss.logging</groupId>
|
|
||||||
<artifactId>jboss-logging</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-common</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-adapter-spi</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-jakarta-servlet-adapter-spi</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.bouncycastle</groupId>
|
|
||||||
<artifactId>bcprov-jdk18on</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-saml-core</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-saml-adapter-api-public</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-saml-adapter-core-jakarta</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-crypto-default</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>jakarta.servlet</groupId>
|
|
||||||
<artifactId>jakarta.servlet-api</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-antrun-plugin</artifactId>
|
|
||||||
<version>3.0.0</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>transform</id>
|
|
||||||
<phase>initialize</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>run</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<target>
|
|
||||||
<property name="plugin_classpath" refid="maven.plugin.classpath" />
|
|
||||||
<java classname="org.eclipse.transformer.jakarta.JakartaTransformer">
|
|
||||||
<arg value="-o" />
|
|
||||||
<arg value="${jakarta-transformer-sources}" />
|
|
||||||
<arg value="${jakarta-transformer-target}" />
|
|
||||||
<classpath>
|
|
||||||
<pathelement path="${plugin_classpath}" />
|
|
||||||
</classpath>
|
|
||||||
</java>
|
|
||||||
</target>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.transformer</groupId>
|
|
||||||
<artifactId>org.eclipse.transformer.cli</artifactId>
|
|
||||||
<version>0.2.0</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>ant-contrib</groupId>
|
|
||||||
<artifactId>ant-contrib</artifactId>
|
|
||||||
<version>1.0b3</version>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>ant</groupId>
|
|
||||||
<artifactId>ant</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
</project>
|
|
|
@ -36,7 +36,6 @@
|
||||||
<module>core-jakarta</module>
|
<module>core-jakarta</module>
|
||||||
<module>undertow</module>
|
<module>undertow</module>
|
||||||
<module>wildfly</module>
|
<module>wildfly</module>
|
||||||
<module>jakarta-servlet-filter</module>
|
|
||||||
<module>wildfly-elytron</module>
|
<module>wildfly-elytron</module>
|
||||||
<module>wildfly-elytron-jakarta</module>
|
<module>wildfly-elytron-jakarta</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
|
@ -1,105 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
<!--
|
|
||||||
~ Copyright 2016 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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
|
||||||
<parent>
|
|
||||||
<artifactId>keycloak-parent</artifactId>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<version>999.0.0-SNAPSHOT</version>
|
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
|
||||||
</parent>
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<artifactId>keycloak-jakarta-servlet-adapter-spi</artifactId>
|
|
||||||
<name>Keycloak Jakarta Servlet Integration</name>
|
|
||||||
<description/>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<keycloak.osgi.export>
|
|
||||||
org.keycloak.adapters.servlet.*
|
|
||||||
</keycloak.osgi.export>
|
|
||||||
<keycloak.osgi.import>
|
|
||||||
*;resolution:=optional
|
|
||||||
</keycloak.osgi.import>
|
|
||||||
<keycloak.osgi.fragment>${project.groupId}.keycloak-jakarta-servlet-filter-adapter</keycloak.osgi.fragment>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jboss.logging</groupId>
|
|
||||||
<artifactId>jboss-logging</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-adapter-spi</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-common</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>jakarta.servlet</groupId>
|
|
||||||
<artifactId>jakarta.servlet-api</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
|
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<archive>
|
|
||||||
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
|
|
||||||
</archive>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.felix</groupId>
|
|
||||||
<artifactId>maven-bundle-plugin</artifactId>
|
|
||||||
<extensions>true</extensions>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>bundle-manifest</id>
|
|
||||||
<phase>process-classes</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>manifest</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<instructions>
|
|
||||||
<Bundle-ClassPath>.</Bundle-ClassPath>
|
|
||||||
<Bundle-Name>${project.name}</Bundle-Name>
|
|
||||||
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
|
|
||||||
<Import-Package>${keycloak.osgi.import}</Import-Package>
|
|
||||||
<Export-Package>${keycloak.osgi.export}</Export-Package>
|
|
||||||
<Fragment-Host>${keycloak.osgi.fragment}</Fragment-Host>
|
|
||||||
</instructions>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
</project>
|
|
|
@ -1,433 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2016 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.adapters.servlet;
|
|
||||||
|
|
||||||
import org.keycloak.adapters.spi.AdapterSessionStore;
|
|
||||||
import org.keycloak.adapters.spi.HttpFacade;
|
|
||||||
import org.keycloak.adapters.spi.KeycloakAccount;
|
|
||||||
import org.keycloak.common.util.Encode;
|
|
||||||
import org.keycloak.common.util.MultivaluedHashMap;
|
|
||||||
|
|
||||||
import jakarta.servlet.ServletException;
|
|
||||||
import jakarta.servlet.ServletInputStream;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import jakarta.servlet.http.HttpServletRequestWrapper;
|
|
||||||
import jakarta.servlet.http.HttpSession;
|
|
||||||
import jakarta.servlet.ReadListener;
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.security.Principal;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
|
||||||
* @version $Revision: 1 $
|
|
||||||
*/
|
|
||||||
public class FilterSessionStore implements AdapterSessionStore {
|
|
||||||
public static final String REDIRECT_URI = "__REDIRECT_URI";
|
|
||||||
public static final String SAVED_METHOD = "__SAVED_METHOD";
|
|
||||||
public static final String SAVED_HEADERS = "__SAVED_HEADERS";
|
|
||||||
public static final String SAVED_BODY = "__SAVED_BODY";
|
|
||||||
protected final HttpServletRequest request;
|
|
||||||
protected final HttpFacade facade;
|
|
||||||
protected final int maxBuffer;
|
|
||||||
protected byte[] restoredBuffer = null;
|
|
||||||
protected boolean needRequestRestore;
|
|
||||||
|
|
||||||
public FilterSessionStore(HttpServletRequest request, HttpFacade facade, int maxBuffer) {
|
|
||||||
this.request = request;
|
|
||||||
this.facade = facade;
|
|
||||||
this.maxBuffer = maxBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearSavedRequest(HttpSession session) {
|
|
||||||
session.removeAttribute(REDIRECT_URI);
|
|
||||||
session.removeAttribute(SAVED_METHOD);
|
|
||||||
session.removeAttribute(SAVED_HEADERS);
|
|
||||||
session.removeAttribute(SAVED_BODY);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void servletRequestLogout() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getCharsetFromContentType(String contentType) {
|
|
||||||
|
|
||||||
if (contentType == null)
|
|
||||||
return (null);
|
|
||||||
int start = contentType.indexOf("charset=");
|
|
||||||
if (start < 0)
|
|
||||||
return (null);
|
|
||||||
String encoding = contentType.substring(start + 8);
|
|
||||||
int end = encoding.indexOf(';');
|
|
||||||
if (end >= 0)
|
|
||||||
encoding = encoding.substring(0, end);
|
|
||||||
encoding = encoding.trim();
|
|
||||||
if ((encoding.length() > 2) && (encoding.startsWith("\""))
|
|
||||||
&& (encoding.endsWith("\"")))
|
|
||||||
encoding = encoding.substring(1, encoding.length() - 1);
|
|
||||||
return (encoding.trim());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public HttpServletRequestWrapper buildWrapper(HttpSession session, final KeycloakAccount account) {
|
|
||||||
if (needRequestRestore) {
|
|
||||||
final String method = (String)session.getAttribute(SAVED_METHOD);
|
|
||||||
final byte[] body = (byte[])session.getAttribute(SAVED_BODY);
|
|
||||||
final MultivaluedHashMap<String, String> headers = (MultivaluedHashMap<String, String>)session.getAttribute(SAVED_HEADERS);
|
|
||||||
clearSavedRequest(session);
|
|
||||||
HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(request) {
|
|
||||||
protected MultivaluedHashMap<String, String> parameters;
|
|
||||||
|
|
||||||
MultivaluedHashMap<String, String> getParams() {
|
|
||||||
if (parameters != null) return parameters;
|
|
||||||
|
|
||||||
if (body == null) return new MultivaluedHashMap<String, String>();
|
|
||||||
|
|
||||||
String contentType = getContentType();
|
|
||||||
if (contentType != null && contentType.toLowerCase().startsWith("application/x-www-form-urlencoded")) {
|
|
||||||
ByteArrayInputStream is = new ByteArrayInputStream(body);
|
|
||||||
try {
|
|
||||||
parameters = parseForm(is);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return parameters;
|
|
||||||
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public boolean isUserInRole(String role) {
|
|
||||||
return account.getRoles().contains(role);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Principal getUserPrincipal() {
|
|
||||||
return account.getPrincipal();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMethod() {
|
|
||||||
if (needRequestRestore) {
|
|
||||||
return method;
|
|
||||||
} else {
|
|
||||||
return super.getMethod();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHeader(String name) {
|
|
||||||
if (needRequestRestore && headers != null) {
|
|
||||||
return headers.getFirst(name.toLowerCase());
|
|
||||||
}
|
|
||||||
return super.getHeader(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Enumeration<String> getHeaders(String name) {
|
|
||||||
if (needRequestRestore && headers != null) {
|
|
||||||
List<String> values = headers.getList(name.toLowerCase());
|
|
||||||
if (values == null) return Collections.emptyEnumeration();
|
|
||||||
else return Collections.enumeration(values);
|
|
||||||
}
|
|
||||||
return super.getHeaders(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Enumeration<String> getHeaderNames() {
|
|
||||||
if (needRequestRestore && headers != null) {
|
|
||||||
return Collections.enumeration(headers.keySet());
|
|
||||||
}
|
|
||||||
return super.getHeaderNames();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ServletInputStream getInputStream() throws IOException {
|
|
||||||
if (needRequestRestore && body != null) {
|
|
||||||
final ByteArrayInputStream is = new ByteArrayInputStream(body);
|
|
||||||
return new ServletInputStream() {
|
|
||||||
@Override
|
|
||||||
public int read() throws IOException {
|
|
||||||
return is.read();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFinished() {
|
|
||||||
return is.available() == 0; // Check if the underlying stream has data available.
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isReady() {
|
|
||||||
return true; // Return true to indicate that the data is always ready to be read.
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setReadListener(ReadListener readListener) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return super.getInputStream();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void logout() throws ServletException {
|
|
||||||
servletRequestLogout();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getDateHeader(String name) {
|
|
||||||
if (!needRequestRestore) return super.getDateHeader(name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getIntHeader(String name) {
|
|
||||||
if (!needRequestRestore) return super.getIntHeader(name);
|
|
||||||
String value = getHeader(name);
|
|
||||||
if (value == null) return -1;
|
|
||||||
return Integer.valueOf(value);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getParameterValues(String name) {
|
|
||||||
if (!needRequestRestore) return super.getParameterValues(name);
|
|
||||||
MultivaluedHashMap<String, String> formParams = getParams();
|
|
||||||
if (formParams == null) {
|
|
||||||
return super.getParameterValues(name);
|
|
||||||
}
|
|
||||||
String[] values = request.getParameterValues(name);
|
|
||||||
List<String> list = new LinkedList<>();
|
|
||||||
if (values != null) {
|
|
||||||
for (String val : values) list.add(val);
|
|
||||||
}
|
|
||||||
List<String> vals = formParams.get(name);
|
|
||||||
if (vals != null) list.addAll(vals);
|
|
||||||
return list.toArray(new String[list.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Enumeration<String> getParameterNames() {
|
|
||||||
if (!needRequestRestore) return super.getParameterNames();
|
|
||||||
MultivaluedHashMap<String, String> formParams = getParams();
|
|
||||||
if (formParams == null) {
|
|
||||||
return super.getParameterNames();
|
|
||||||
}
|
|
||||||
Set<String> names = new HashSet<>();
|
|
||||||
Enumeration<String> qnames = super.getParameterNames();
|
|
||||||
while (qnames.hasMoreElements()) names.add(qnames.nextElement());
|
|
||||||
names.addAll(formParams.keySet());
|
|
||||||
return Collections.enumeration(names);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, String[]> getParameterMap() {
|
|
||||||
if (!needRequestRestore) return super.getParameterMap();
|
|
||||||
MultivaluedHashMap<String, String> formParams = getParams();
|
|
||||||
if (formParams == null) {
|
|
||||||
return super.getParameterMap();
|
|
||||||
}
|
|
||||||
Map<String, String[]> map = new HashMap<>();
|
|
||||||
Enumeration<String> names = getParameterNames();
|
|
||||||
while (names.hasMoreElements()) {
|
|
||||||
String name = names.nextElement();
|
|
||||||
String[] values = getParameterValues(name);
|
|
||||||
if (values != null) {
|
|
||||||
map.put(name, values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getParameter(String name) {
|
|
||||||
if (!needRequestRestore) return super.getParameter(name);
|
|
||||||
String param = super.getParameter(name);
|
|
||||||
if (param != null) return param;
|
|
||||||
MultivaluedHashMap<String, String> formParams = getParams();
|
|
||||||
if (formParams == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return formParams.getFirst(name);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BufferedReader getReader() throws IOException {
|
|
||||||
if (!needRequestRestore) return super.getReader();
|
|
||||||
return new BufferedReader(new InputStreamReader(getInputStream()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getContentLength() {
|
|
||||||
if (!needRequestRestore) return super.getContentLength();
|
|
||||||
String header = getHeader("content-length");
|
|
||||||
if (header == null) return -1;
|
|
||||||
return Integer.valueOf(header);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getContentType() {
|
|
||||||
if (!needRequestRestore) return super.getContentType();
|
|
||||||
return getHeader("content-type");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getCharacterEncoding() {
|
|
||||||
if (!needRequestRestore) return super.getCharacterEncoding();
|
|
||||||
return getCharsetFromContentType(getContentType());
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
return wrapper;
|
|
||||||
} else {
|
|
||||||
return new HttpServletRequestWrapper(request) {
|
|
||||||
@Override
|
|
||||||
public boolean isUserInRole(String role) {
|
|
||||||
return account.getRoles().contains(role);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Principal getUserPrincipal() {
|
|
||||||
if (account == null) return null;
|
|
||||||
return account.getPrincipal();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void logout() throws ServletException {
|
|
||||||
servletRequestLogout();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRedirectUri() {
|
|
||||||
HttpSession session = request.getSession(true);
|
|
||||||
return (String)session.getAttribute(REDIRECT_URI);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean restoreRequest() {
|
|
||||||
HttpSession session = request.getSession(false);
|
|
||||||
if (session == null) return false;
|
|
||||||
return session.getAttribute(REDIRECT_URI) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MultivaluedHashMap<String, String> parseForm(InputStream entityStream)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
char[] buffer = new char[100];
|
|
||||||
StringBuffer buf = new StringBuffer();
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(entityStream));
|
|
||||||
|
|
||||||
int wasRead = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
wasRead = reader.read(buffer, 0, 100);
|
|
||||||
if (wasRead > 0) buf.append(buffer, 0, wasRead);
|
|
||||||
} while (wasRead > -1);
|
|
||||||
|
|
||||||
String form = buf.toString();
|
|
||||||
|
|
||||||
MultivaluedHashMap<String, String> formData = new MultivaluedHashMap<String, String>();
|
|
||||||
if ("".equals(form)) return formData;
|
|
||||||
|
|
||||||
String[] params = form.split("&");
|
|
||||||
|
|
||||||
for (String param : params)
|
|
||||||
{
|
|
||||||
if (param.indexOf('=') >= 0)
|
|
||||||
{
|
|
||||||
String[] nv = param.split("=");
|
|
||||||
String val = nv.length > 1 ? nv[1] : "";
|
|
||||||
formData.add(Encode.decode(nv[0]), Encode.decode(val));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
formData.add(Encode.decode(param), "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return formData;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveRequest() {
|
|
||||||
HttpSession session = request.getSession(true);
|
|
||||||
session.setAttribute(REDIRECT_URI, facade.getRequest().getURI());
|
|
||||||
session.setAttribute(SAVED_METHOD, request.getMethod());
|
|
||||||
MultivaluedHashMap<String, String> headers = new MultivaluedHashMap<>();
|
|
||||||
Enumeration<String> names = request.getHeaderNames();
|
|
||||||
while (names.hasMoreElements()) {
|
|
||||||
String name = names.nextElement();
|
|
||||||
Enumeration<String> values = request.getHeaders(name);
|
|
||||||
while (values.hasMoreElements()) {
|
|
||||||
headers.add(name.toLowerCase(), values.nextElement());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
session.setAttribute(SAVED_HEADERS, headers);
|
|
||||||
if (request.getMethod().equalsIgnoreCase("GET")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
|
||||||
|
|
||||||
byte[] buffer = new byte[4096];
|
|
||||||
int bytesRead;
|
|
||||||
int totalRead = 0;
|
|
||||||
try {
|
|
||||||
InputStream is = request.getInputStream();
|
|
||||||
|
|
||||||
while ( (bytesRead = is.read(buffer) ) >= 0) {
|
|
||||||
os.write(buffer, 0, bytesRead);
|
|
||||||
totalRead += bytesRead;
|
|
||||||
if (totalRead > maxBuffer) {
|
|
||||||
throw new RuntimeException("max buffer reached on a saved request");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
byte[] body = os.toByteArray();
|
|
||||||
// Only save the request body if there is something to save
|
|
||||||
if (body.length > 0) {
|
|
||||||
session.setAttribute(SAVED_BODY, body);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,268 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2016 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.adapters.servlet;
|
|
||||||
|
|
||||||
import org.keycloak.adapters.spi.AuthenticationError;
|
|
||||||
import org.keycloak.adapters.spi.HttpFacade;
|
|
||||||
import org.keycloak.adapters.spi.LogoutError;
|
|
||||||
import org.keycloak.common.util.MultivaluedHashMap;
|
|
||||||
import org.keycloak.common.util.ServerCookie;
|
|
||||||
import org.keycloak.common.util.UriUtils;
|
|
||||||
|
|
||||||
import javax.security.cert.X509Certificate;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
|
||||||
* @version $Revision: 1 $
|
|
||||||
*/
|
|
||||||
public class ServletHttpFacade implements HttpFacade {
|
|
||||||
protected final RequestFacade requestFacade = new RequestFacade();
|
|
||||||
protected final ResponseFacade responseFacade = new ResponseFacade();
|
|
||||||
protected HttpServletRequest request;
|
|
||||||
protected HttpServletResponse response;
|
|
||||||
protected MultivaluedHashMap<String, String> queryParameters;
|
|
||||||
|
|
||||||
public ServletHttpFacade(HttpServletRequest request, HttpServletResponse response) {
|
|
||||||
this.request = request;
|
|
||||||
this.response = response;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected class RequestFacade implements Request {
|
|
||||||
|
|
||||||
private InputStream inputStream;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMethod() {
|
|
||||||
return request.getMethod();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getURI() {
|
|
||||||
StringBuffer buf = request.getRequestURL();
|
|
||||||
if (request.getQueryString() != null) {
|
|
||||||
buf.append('?').append(request.getQueryString());
|
|
||||||
}
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getRelativePath() {
|
|
||||||
String uri = request.getRequestURI();
|
|
||||||
String contextPath = request.getContextPath();
|
|
||||||
String servletPath = uri.substring(uri.indexOf(contextPath) + contextPath.length());
|
|
||||||
|
|
||||||
if ("".equals(servletPath)) {
|
|
||||||
servletPath = "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
return servletPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSecure() {
|
|
||||||
return request.isSecure();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getFirstParam(String param) {
|
|
||||||
return request.getParameter(param);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getQueryParamValue(String param) {
|
|
||||||
if (queryParameters == null) {
|
|
||||||
queryParameters = UriUtils.decodeQueryString(request.getQueryString());
|
|
||||||
}
|
|
||||||
return queryParameters.getFirst(param);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MultivaluedHashMap<String, String> getQueryParameters() {
|
|
||||||
if (queryParameters == null) {
|
|
||||||
queryParameters = UriUtils.decodeQueryString(request.getQueryString());
|
|
||||||
}
|
|
||||||
return queryParameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Cookie getCookie(String cookieName) {
|
|
||||||
if (request.getCookies() == null) return null;
|
|
||||||
jakarta.servlet.http.Cookie cookie = null;
|
|
||||||
for (jakarta.servlet.http.Cookie c : request.getCookies()) {
|
|
||||||
if (c.getName().equals(cookieName)) {
|
|
||||||
cookie = c;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cookie == null) return null;
|
|
||||||
return new Cookie(cookie.getName(), cookie.getValue(), cookie.getVersion(), cookie.getDomain(), cookie.getPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHeader(String name) {
|
|
||||||
return request.getHeader(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getHeaders(String name) {
|
|
||||||
Enumeration<String> values = request.getHeaders(name);
|
|
||||||
List<String> list = new LinkedList<>();
|
|
||||||
while (values.hasMoreElements()) list.add(values.nextElement());
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream getInputStream() {
|
|
||||||
return getInputStream(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream getInputStream(boolean buffered) {
|
|
||||||
if (inputStream != null) {
|
|
||||||
return inputStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buffered) {
|
|
||||||
try {
|
|
||||||
return inputStream = new BufferedInputStream(request.getInputStream());
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
return request.getInputStream();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getRemoteAddr() {
|
|
||||||
return request.getRemoteAddr();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setError(AuthenticationError error) {
|
|
||||||
request.setAttribute(AuthenticationError.class.getName(), error);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setError(LogoutError error) {
|
|
||||||
request.setAttribute(LogoutError.class.getName(), error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public boolean isEnded() {
|
|
||||||
return responseFacade.isEnded();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected class ResponseFacade implements Response {
|
|
||||||
protected boolean ended;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setStatus(int status) {
|
|
||||||
response.setStatus(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addHeader(String name, String value) {
|
|
||||||
response.addHeader(name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setHeader(String name, String value) {
|
|
||||||
response.setHeader(name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void resetCookie(String name, String path) {
|
|
||||||
setCookie(name, "", path, null, 0, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setCookie(String name, String value, String path, String domain, int maxAge, boolean secure, boolean httpOnly) {
|
|
||||||
StringBuilder cookieBuf = new StringBuilder();
|
|
||||||
ServerCookie.appendCookieValue(cookieBuf, 1, name, value, path, domain, null, maxAge, secure, httpOnly, null);
|
|
||||||
String cookie = cookieBuf.toString();
|
|
||||||
response.addHeader("Set-Cookie", cookie);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public OutputStream getOutputStream() {
|
|
||||||
try {
|
|
||||||
return response.getOutputStream();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendError(int code) {
|
|
||||||
try {
|
|
||||||
response.sendError(code);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendError(int code, String message) {
|
|
||||||
try {
|
|
||||||
response.sendError(code, message);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void end() {
|
|
||||||
ended = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEnded() {
|
|
||||||
return ended;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Request getRequest() {
|
|
||||||
return requestFacade;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Response getResponse() {
|
|
||||||
return responseFacade;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public X509Certificate[] getCertificateChain() {
|
|
||||||
throw new IllegalStateException("Not supported yet");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -33,8 +33,6 @@
|
||||||
<modules>
|
<modules>
|
||||||
<module>adapter-spi</module>
|
<module>adapter-spi</module>
|
||||||
<module>undertow-adapter-spi</module>
|
<module>undertow-adapter-spi</module>
|
||||||
<module>servlet-adapter-spi</module>
|
|
||||||
<module>jakarta-servlet-adapter-spi</module>
|
|
||||||
<module>jboss-adapter-core</module>
|
<module>jboss-adapter-core</module>
|
||||||
</modules>
|
</modules>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -1,105 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
<!--
|
|
||||||
~ Copyright 2016 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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
|
||||||
<parent>
|
|
||||||
<artifactId>keycloak-parent</artifactId>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<version>999.0.0-SNAPSHOT</version>
|
|
||||||
<relativePath>../../../pom.xml</relativePath>
|
|
||||||
</parent>
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<artifactId>keycloak-servlet-adapter-spi</artifactId>
|
|
||||||
<name>Keycloak Servlet Integration</name>
|
|
||||||
<description/>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<keycloak.osgi.export>
|
|
||||||
org.keycloak.adapters.servlet.*
|
|
||||||
</keycloak.osgi.export>
|
|
||||||
<keycloak.osgi.import>
|
|
||||||
*;resolution:=optional
|
|
||||||
</keycloak.osgi.import>
|
|
||||||
<keycloak.osgi.fragment>${project.groupId}.keycloak-servlet-filter-adapter</keycloak.osgi.fragment>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jboss.logging</groupId>
|
|
||||||
<artifactId>jboss-logging</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-adapter-spi</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-common</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jboss.spec.javax.servlet</groupId>
|
|
||||||
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
|
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<archive>
|
|
||||||
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
|
|
||||||
</archive>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.felix</groupId>
|
|
||||||
<artifactId>maven-bundle-plugin</artifactId>
|
|
||||||
<extensions>true</extensions>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>bundle-manifest</id>
|
|
||||||
<phase>process-classes</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>manifest</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<instructions>
|
|
||||||
<Bundle-ClassPath>.</Bundle-ClassPath>
|
|
||||||
<Bundle-Name>${project.name}</Bundle-Name>
|
|
||||||
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
|
|
||||||
<Import-Package>${keycloak.osgi.import}</Import-Package>
|
|
||||||
<Export-Package>${keycloak.osgi.export}</Export-Package>
|
|
||||||
<Fragment-Host>${keycloak.osgi.fragment}</Fragment-Host>
|
|
||||||
</instructions>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
</project>
|
|
|
@ -1,418 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2016 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.adapters.servlet;
|
|
||||||
|
|
||||||
import org.keycloak.adapters.spi.AdapterSessionStore;
|
|
||||||
import org.keycloak.adapters.spi.HttpFacade;
|
|
||||||
import org.keycloak.adapters.spi.KeycloakAccount;
|
|
||||||
import org.keycloak.common.util.Encode;
|
|
||||||
import org.keycloak.common.util.MultivaluedHashMap;
|
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.ServletInputStream;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletRequestWrapper;
|
|
||||||
import javax.servlet.http.HttpSession;
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.security.Principal;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
|
||||||
* @version $Revision: 1 $
|
|
||||||
*/
|
|
||||||
public class FilterSessionStore implements AdapterSessionStore {
|
|
||||||
public static final String REDIRECT_URI = "__REDIRECT_URI";
|
|
||||||
public static final String SAVED_METHOD = "__SAVED_METHOD";
|
|
||||||
public static final String SAVED_HEADERS = "__SAVED_HEADERS";
|
|
||||||
public static final String SAVED_BODY = "__SAVED_BODY";
|
|
||||||
protected final HttpServletRequest request;
|
|
||||||
protected final HttpFacade facade;
|
|
||||||
protected final int maxBuffer;
|
|
||||||
protected byte[] restoredBuffer = null;
|
|
||||||
protected boolean needRequestRestore;
|
|
||||||
|
|
||||||
public FilterSessionStore(HttpServletRequest request, HttpFacade facade, int maxBuffer) {
|
|
||||||
this.request = request;
|
|
||||||
this.facade = facade;
|
|
||||||
this.maxBuffer = maxBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearSavedRequest(HttpSession session) {
|
|
||||||
session.removeAttribute(REDIRECT_URI);
|
|
||||||
session.removeAttribute(SAVED_METHOD);
|
|
||||||
session.removeAttribute(SAVED_HEADERS);
|
|
||||||
session.removeAttribute(SAVED_BODY);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void servletRequestLogout() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getCharsetFromContentType(String contentType) {
|
|
||||||
|
|
||||||
if (contentType == null)
|
|
||||||
return (null);
|
|
||||||
int start = contentType.indexOf("charset=");
|
|
||||||
if (start < 0)
|
|
||||||
return (null);
|
|
||||||
String encoding = contentType.substring(start + 8);
|
|
||||||
int end = encoding.indexOf(';');
|
|
||||||
if (end >= 0)
|
|
||||||
encoding = encoding.substring(0, end);
|
|
||||||
encoding = encoding.trim();
|
|
||||||
if ((encoding.length() > 2) && (encoding.startsWith("\""))
|
|
||||||
&& (encoding.endsWith("\"")))
|
|
||||||
encoding = encoding.substring(1, encoding.length() - 1);
|
|
||||||
return (encoding.trim());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public HttpServletRequestWrapper buildWrapper(HttpSession session, final KeycloakAccount account) {
|
|
||||||
if (needRequestRestore) {
|
|
||||||
final String method = (String)session.getAttribute(SAVED_METHOD);
|
|
||||||
final byte[] body = (byte[])session.getAttribute(SAVED_BODY);
|
|
||||||
final MultivaluedHashMap<String, String> headers = (MultivaluedHashMap<String, String>)session.getAttribute(SAVED_HEADERS);
|
|
||||||
clearSavedRequest(session);
|
|
||||||
HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(request) {
|
|
||||||
protected MultivaluedHashMap<String, String> parameters;
|
|
||||||
|
|
||||||
MultivaluedHashMap<String, String> getParams() {
|
|
||||||
if (parameters != null) return parameters;
|
|
||||||
|
|
||||||
if (body == null) return new MultivaluedHashMap<String, String>();
|
|
||||||
|
|
||||||
String contentType = getContentType();
|
|
||||||
if (contentType != null && contentType.toLowerCase().startsWith("application/x-www-form-urlencoded")) {
|
|
||||||
ByteArrayInputStream is = new ByteArrayInputStream(body);
|
|
||||||
try {
|
|
||||||
parameters = parseForm(is);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return parameters;
|
|
||||||
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public boolean isUserInRole(String role) {
|
|
||||||
return account.getRoles().contains(role);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Principal getUserPrincipal() {
|
|
||||||
return account.getPrincipal();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMethod() {
|
|
||||||
if (needRequestRestore) {
|
|
||||||
return method;
|
|
||||||
} else {
|
|
||||||
return super.getMethod();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHeader(String name) {
|
|
||||||
if (needRequestRestore && headers != null) {
|
|
||||||
return headers.getFirst(name.toLowerCase());
|
|
||||||
}
|
|
||||||
return super.getHeader(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Enumeration<String> getHeaders(String name) {
|
|
||||||
if (needRequestRestore && headers != null) {
|
|
||||||
List<String> values = headers.getList(name.toLowerCase());
|
|
||||||
if (values == null) return Collections.emptyEnumeration();
|
|
||||||
else return Collections.enumeration(values);
|
|
||||||
}
|
|
||||||
return super.getHeaders(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Enumeration<String> getHeaderNames() {
|
|
||||||
if (needRequestRestore && headers != null) {
|
|
||||||
return Collections.enumeration(headers.keySet());
|
|
||||||
}
|
|
||||||
return super.getHeaderNames();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ServletInputStream getInputStream() throws IOException {
|
|
||||||
|
|
||||||
if (needRequestRestore && body != null) {
|
|
||||||
final ByteArrayInputStream is = new ByteArrayInputStream(body);
|
|
||||||
return new ServletInputStream() {
|
|
||||||
@Override
|
|
||||||
public int read() throws IOException {
|
|
||||||
return is.read();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return super.getInputStream();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void logout() throws ServletException {
|
|
||||||
servletRequestLogout();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getDateHeader(String name) {
|
|
||||||
if (!needRequestRestore) return super.getDateHeader(name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getIntHeader(String name) {
|
|
||||||
if (!needRequestRestore) return super.getIntHeader(name);
|
|
||||||
String value = getHeader(name);
|
|
||||||
if (value == null) return -1;
|
|
||||||
return Integer.valueOf(value);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getParameterValues(String name) {
|
|
||||||
if (!needRequestRestore) return super.getParameterValues(name);
|
|
||||||
MultivaluedHashMap<String, String> formParams = getParams();
|
|
||||||
if (formParams == null) {
|
|
||||||
return super.getParameterValues(name);
|
|
||||||
}
|
|
||||||
String[] values = request.getParameterValues(name);
|
|
||||||
List<String> list = new LinkedList<>();
|
|
||||||
if (values != null) {
|
|
||||||
for (String val : values) list.add(val);
|
|
||||||
}
|
|
||||||
List<String> vals = formParams.get(name);
|
|
||||||
if (vals != null) list.addAll(vals);
|
|
||||||
return list.toArray(new String[list.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Enumeration<String> getParameterNames() {
|
|
||||||
if (!needRequestRestore) return super.getParameterNames();
|
|
||||||
MultivaluedHashMap<String, String> formParams = getParams();
|
|
||||||
if (formParams == null) {
|
|
||||||
return super.getParameterNames();
|
|
||||||
}
|
|
||||||
Set<String> names = new HashSet<>();
|
|
||||||
Enumeration<String> qnames = super.getParameterNames();
|
|
||||||
while (qnames.hasMoreElements()) names.add(qnames.nextElement());
|
|
||||||
names.addAll(formParams.keySet());
|
|
||||||
return Collections.enumeration(names);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, String[]> getParameterMap() {
|
|
||||||
if (!needRequestRestore) return super.getParameterMap();
|
|
||||||
MultivaluedHashMap<String, String> formParams = getParams();
|
|
||||||
if (formParams == null) {
|
|
||||||
return super.getParameterMap();
|
|
||||||
}
|
|
||||||
Map<String, String[]> map = new HashMap<>();
|
|
||||||
Enumeration<String> names = getParameterNames();
|
|
||||||
while (names.hasMoreElements()) {
|
|
||||||
String name = names.nextElement();
|
|
||||||
String[] values = getParameterValues(name);
|
|
||||||
if (values != null) {
|
|
||||||
map.put(name, values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getParameter(String name) {
|
|
||||||
if (!needRequestRestore) return super.getParameter(name);
|
|
||||||
String param = super.getParameter(name);
|
|
||||||
if (param != null) return param;
|
|
||||||
MultivaluedHashMap<String, String> formParams = getParams();
|
|
||||||
if (formParams == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return formParams.getFirst(name);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BufferedReader getReader() throws IOException {
|
|
||||||
if (!needRequestRestore) return super.getReader();
|
|
||||||
return new BufferedReader(new InputStreamReader(getInputStream()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getContentLength() {
|
|
||||||
if (!needRequestRestore) return super.getContentLength();
|
|
||||||
String header = getHeader("content-length");
|
|
||||||
if (header == null) return -1;
|
|
||||||
return Integer.valueOf(header);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getContentType() {
|
|
||||||
if (!needRequestRestore) return super.getContentType();
|
|
||||||
return getHeader("content-type");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getCharacterEncoding() {
|
|
||||||
if (!needRequestRestore) return super.getCharacterEncoding();
|
|
||||||
return getCharsetFromContentType(getContentType());
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
return wrapper;
|
|
||||||
} else {
|
|
||||||
return new HttpServletRequestWrapper(request) {
|
|
||||||
@Override
|
|
||||||
public boolean isUserInRole(String role) {
|
|
||||||
return account.getRoles().contains(role);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Principal getUserPrincipal() {
|
|
||||||
if (account == null) return null;
|
|
||||||
return account.getPrincipal();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void logout() throws ServletException {
|
|
||||||
servletRequestLogout();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRedirectUri() {
|
|
||||||
HttpSession session = request.getSession(true);
|
|
||||||
return (String)session.getAttribute(REDIRECT_URI);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean restoreRequest() {
|
|
||||||
HttpSession session = request.getSession(false);
|
|
||||||
if (session == null) return false;
|
|
||||||
return session.getAttribute(REDIRECT_URI) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MultivaluedHashMap<String, String> parseForm(InputStream entityStream)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
char[] buffer = new char[100];
|
|
||||||
StringBuffer buf = new StringBuffer();
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(entityStream));
|
|
||||||
|
|
||||||
int wasRead = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
wasRead = reader.read(buffer, 0, 100);
|
|
||||||
if (wasRead > 0) buf.append(buffer, 0, wasRead);
|
|
||||||
} while (wasRead > -1);
|
|
||||||
|
|
||||||
String form = buf.toString();
|
|
||||||
|
|
||||||
MultivaluedHashMap<String, String> formData = new MultivaluedHashMap<String, String>();
|
|
||||||
if ("".equals(form)) return formData;
|
|
||||||
|
|
||||||
String[] params = form.split("&");
|
|
||||||
|
|
||||||
for (String param : params)
|
|
||||||
{
|
|
||||||
if (param.indexOf('=') >= 0)
|
|
||||||
{
|
|
||||||
String[] nv = param.split("=");
|
|
||||||
String val = nv.length > 1 ? nv[1] : "";
|
|
||||||
formData.add(Encode.decode(nv[0]), Encode.decode(val));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
formData.add(Encode.decode(param), "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return formData;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveRequest() {
|
|
||||||
HttpSession session = request.getSession(true);
|
|
||||||
session.setAttribute(REDIRECT_URI, facade.getRequest().getURI());
|
|
||||||
session.setAttribute(SAVED_METHOD, request.getMethod());
|
|
||||||
MultivaluedHashMap<String, String> headers = new MultivaluedHashMap<>();
|
|
||||||
Enumeration<String> names = request.getHeaderNames();
|
|
||||||
while (names.hasMoreElements()) {
|
|
||||||
String name = names.nextElement();
|
|
||||||
Enumeration<String> values = request.getHeaders(name);
|
|
||||||
while (values.hasMoreElements()) {
|
|
||||||
headers.add(name.toLowerCase(), values.nextElement());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
session.setAttribute(SAVED_HEADERS, headers);
|
|
||||||
if (request.getMethod().equalsIgnoreCase("GET")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
|
||||||
|
|
||||||
byte[] buffer = new byte[4096];
|
|
||||||
int bytesRead;
|
|
||||||
int totalRead = 0;
|
|
||||||
try {
|
|
||||||
InputStream is = request.getInputStream();
|
|
||||||
|
|
||||||
while ( (bytesRead = is.read(buffer) ) >= 0) {
|
|
||||||
os.write(buffer, 0, bytesRead);
|
|
||||||
totalRead += bytesRead;
|
|
||||||
if (totalRead > maxBuffer) {
|
|
||||||
throw new RuntimeException("max buffer reached on a saved request");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
byte[] body = os.toByteArray();
|
|
||||||
// Only save the request body if there is something to save
|
|
||||||
if (body.length > 0) {
|
|
||||||
session.setAttribute(SAVED_BODY, body);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,268 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2016 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.adapters.servlet;
|
|
||||||
|
|
||||||
import org.keycloak.adapters.spi.AuthenticationError;
|
|
||||||
import org.keycloak.adapters.spi.HttpFacade;
|
|
||||||
import org.keycloak.adapters.spi.LogoutError;
|
|
||||||
import org.keycloak.common.util.MultivaluedHashMap;
|
|
||||||
import org.keycloak.common.util.ServerCookie;
|
|
||||||
import org.keycloak.common.util.UriUtils;
|
|
||||||
|
|
||||||
import javax.security.cert.X509Certificate;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
|
||||||
* @version $Revision: 1 $
|
|
||||||
*/
|
|
||||||
public class ServletHttpFacade implements HttpFacade {
|
|
||||||
protected final RequestFacade requestFacade = new RequestFacade();
|
|
||||||
protected final ResponseFacade responseFacade = new ResponseFacade();
|
|
||||||
protected HttpServletRequest request;
|
|
||||||
protected HttpServletResponse response;
|
|
||||||
protected MultivaluedHashMap<String, String> queryParameters;
|
|
||||||
|
|
||||||
public ServletHttpFacade(HttpServletRequest request, HttpServletResponse response) {
|
|
||||||
this.request = request;
|
|
||||||
this.response = response;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected class RequestFacade implements Request {
|
|
||||||
|
|
||||||
private InputStream inputStream;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMethod() {
|
|
||||||
return request.getMethod();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getURI() {
|
|
||||||
StringBuffer buf = request.getRequestURL();
|
|
||||||
if (request.getQueryString() != null) {
|
|
||||||
buf.append('?').append(request.getQueryString());
|
|
||||||
}
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getRelativePath() {
|
|
||||||
String uri = request.getRequestURI();
|
|
||||||
String contextPath = request.getContextPath();
|
|
||||||
String servletPath = uri.substring(uri.indexOf(contextPath) + contextPath.length());
|
|
||||||
|
|
||||||
if ("".equals(servletPath)) {
|
|
||||||
servletPath = "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
return servletPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSecure() {
|
|
||||||
return request.isSecure();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getFirstParam(String param) {
|
|
||||||
return request.getParameter(param);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getQueryParamValue(String param) {
|
|
||||||
if (queryParameters == null) {
|
|
||||||
queryParameters = UriUtils.decodeQueryString(request.getQueryString());
|
|
||||||
}
|
|
||||||
return queryParameters.getFirst(param);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MultivaluedHashMap<String, String> getQueryParameters() {
|
|
||||||
if (queryParameters == null) {
|
|
||||||
queryParameters = UriUtils.decodeQueryString(request.getQueryString());
|
|
||||||
}
|
|
||||||
return queryParameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Cookie getCookie(String cookieName) {
|
|
||||||
if (request.getCookies() == null) return null;
|
|
||||||
javax.servlet.http.Cookie cookie = null;
|
|
||||||
for (javax.servlet.http.Cookie c : request.getCookies()) {
|
|
||||||
if (c.getName().equals(cookieName)) {
|
|
||||||
cookie = c;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cookie == null) return null;
|
|
||||||
return new Cookie(cookie.getName(), cookie.getValue(), cookie.getVersion(), cookie.getDomain(), cookie.getPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHeader(String name) {
|
|
||||||
return request.getHeader(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getHeaders(String name) {
|
|
||||||
Enumeration<String> values = request.getHeaders(name);
|
|
||||||
List<String> list = new LinkedList<>();
|
|
||||||
while (values.hasMoreElements()) list.add(values.nextElement());
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream getInputStream() {
|
|
||||||
return getInputStream(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream getInputStream(boolean buffered) {
|
|
||||||
if (inputStream != null) {
|
|
||||||
return inputStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buffered) {
|
|
||||||
try {
|
|
||||||
return inputStream = new BufferedInputStream(request.getInputStream());
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
return request.getInputStream();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getRemoteAddr() {
|
|
||||||
return request.getRemoteAddr();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setError(AuthenticationError error) {
|
|
||||||
request.setAttribute(AuthenticationError.class.getName(), error);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setError(LogoutError error) {
|
|
||||||
request.setAttribute(LogoutError.class.getName(), error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public boolean isEnded() {
|
|
||||||
return responseFacade.isEnded();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected class ResponseFacade implements Response {
|
|
||||||
protected boolean ended;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setStatus(int status) {
|
|
||||||
response.setStatus(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addHeader(String name, String value) {
|
|
||||||
response.addHeader(name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setHeader(String name, String value) {
|
|
||||||
response.setHeader(name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void resetCookie(String name, String path) {
|
|
||||||
setCookie(name, "", path, null, 0, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setCookie(String name, String value, String path, String domain, int maxAge, boolean secure, boolean httpOnly) {
|
|
||||||
StringBuilder cookieBuf = new StringBuilder();
|
|
||||||
ServerCookie.appendCookieValue(cookieBuf, 1, name, value, path, domain, null, maxAge, secure, httpOnly, null);
|
|
||||||
String cookie = cookieBuf.toString();
|
|
||||||
response.addHeader("Set-Cookie", cookie);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public OutputStream getOutputStream() {
|
|
||||||
try {
|
|
||||||
return response.getOutputStream();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendError(int code) {
|
|
||||||
try {
|
|
||||||
response.sendError(code);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendError(int code, String message) {
|
|
||||||
try {
|
|
||||||
response.sendError(code, message);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void end() {
|
|
||||||
ended = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEnded() {
|
|
||||||
return ended;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Request getRequest() {
|
|
||||||
return requestFacade;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Response getResponse() {
|
|
||||||
return responseFacade;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public X509Certificate[] getCertificateChain() {
|
|
||||||
throw new IllegalStateException("Not supported yet");
|
|
||||||
}
|
|
||||||
}
|
|
15
pom.xml
15
pom.xml
|
@ -1003,16 +1003,6 @@
|
||||||
<artifactId>keycloak-adapter-spi</artifactId>
|
<artifactId>keycloak-adapter-spi</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-servlet-adapter-spi</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-jakarta-servlet-adapter-spi</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<artifactId>keycloak-adapter-core</artifactId>
|
<artifactId>keycloak-adapter-core</artifactId>
|
||||||
|
@ -1063,11 +1053,6 @@
|
||||||
<artifactId>keycloak-js-adapter-jar</artifactId>
|
<artifactId>keycloak-js-adapter-jar</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-saml-jakarta-servlet-filter-adapter</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<artifactId>keycloak-saml-as7-adapter</artifactId>
|
<artifactId>keycloak-saml-as7-adapter</artifactId>
|
||||||
|
|
Loading…
Reference in a new issue