KEYCLOAK-7523 better context path detection in PathBasedKeycloakConfigResolver
This commit is contained in:
parent
49407c2e4f
commit
fca6da3a5a
3 changed files with 186 additions and 7 deletions
|
@ -99,6 +99,12 @@
|
|||
<version>${cxf.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.io.File;
|
|||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
@ -34,13 +35,35 @@ public class PathBasedKeycloakConfigResolver implements KeycloakConfigResolver {
|
|||
|
||||
@Override
|
||||
public KeycloakDeployment resolve(OIDCHttpFacade.Request request) {
|
||||
String path = request.getURI();
|
||||
String[] urlTokens = path.split("/");
|
||||
String uri = request.getURI();
|
||||
String relativePath = request.getRelativePath();
|
||||
String webContext = null;
|
||||
if (relativePath == null || !uri.contains(relativePath)) {
|
||||
String[] urlTokens = uri.split("/");
|
||||
if (urlTokens.length < 4) {
|
||||
throw new IllegalStateException("Not able to determine the web-context to load the correspondent keycloak.json file");
|
||||
}
|
||||
|
||||
String webContext = urlTokens[3];
|
||||
webContext = urlTokens[3];
|
||||
} else {
|
||||
URI parsedURI = URI.create(uri);
|
||||
String path = parsedURI.getPath();
|
||||
path = path.substring(0, path.indexOf(relativePath));
|
||||
while (path.startsWith("/")) {
|
||||
path = path.substring(1);
|
||||
}
|
||||
webContext = path;
|
||||
if ("".equals(webContext)) {
|
||||
path = relativePath;
|
||||
while (path.startsWith("/")) {
|
||||
path = path.substring(1);
|
||||
}
|
||||
if (path.contains("/")) {
|
||||
path = path.substring(0, path.indexOf("/"));
|
||||
}
|
||||
webContext = path;
|
||||
}
|
||||
}
|
||||
|
||||
KeycloakDeployment deployment = cache.get(webContext);
|
||||
if (null == deployment) {
|
||||
|
@ -54,7 +77,8 @@ public class PathBasedKeycloakConfigResolver implements KeycloakConfigResolver {
|
|||
keycloakConfig = karafEtc;
|
||||
}
|
||||
|
||||
String absolutePath = keycloakConfig + File.separator + webContext + "-keycloak.json";
|
||||
String absolutePath = keycloakConfig + File.separator + webContext + ("".equals(webContext) ? "" : "-")
|
||||
+ "keycloak.json";
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = new FileInputStream(absolutePath);
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* Copyright 2018 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.osgi;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.keycloak.adapters.KeycloakDeployment;
|
||||
import org.keycloak.adapters.OIDCHttpFacade;
|
||||
import org.keycloak.adapters.spi.AuthenticationError;
|
||||
import org.keycloak.adapters.spi.HttpFacade;
|
||||
import org.keycloak.adapters.spi.LogoutError;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
public class PathBasedKeycloakConfigResolverTest {
|
||||
|
||||
@Test
|
||||
public void relativeURIsAndContexts() throws Exception {
|
||||
PathBasedKeycloakConfigResolver resolver = new PathBasedKeycloakConfigResolver();
|
||||
|
||||
assertNotNull(populate(resolver, "test")
|
||||
.resolve(new MockRequest("http://localhost/test/a/b/c?d=e", "/a/b/c")));
|
||||
|
||||
assertNotNull(populate(resolver, "test")
|
||||
.resolve(new MockRequest("http://localhost/test/a/b/c?d=e", "/a/b")));
|
||||
|
||||
// means default context and actually we use first segment
|
||||
assertNotNull(populate(resolver, "test")
|
||||
.resolve(new MockRequest("http://localhost/test/a/b/c?d=e", "/test/a/b/c")));
|
||||
|
||||
assertNotNull(populate(resolver, "test/a")
|
||||
.resolve(new MockRequest("http://localhost/test/a/b/c?d=e", "/b/c")));
|
||||
|
||||
assertNotNull(populate(resolver, "")
|
||||
.resolve(new MockRequest("http://localhost/", "/")));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private PathBasedKeycloakConfigResolver populate(PathBasedKeycloakConfigResolver resolver, String context)
|
||||
throws Exception {
|
||||
Field f = PathBasedKeycloakConfigResolver.class.getDeclaredField("cache");
|
||||
f.setAccessible(true);
|
||||
Map<String, KeycloakDeployment> cache = (Map<String, KeycloakDeployment>) f.get(resolver);
|
||||
cache.clear();
|
||||
cache.put(context, new KeycloakDeployment());
|
||||
|
||||
return resolver;
|
||||
}
|
||||
|
||||
private class MockRequest implements OIDCHttpFacade.Request {
|
||||
|
||||
private String uri;
|
||||
private String relativePath;
|
||||
|
||||
public MockRequest(String uri, String relativePath) {
|
||||
this.uri = uri;
|
||||
this.relativePath = relativePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethod() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getURI() {
|
||||
return this.uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRelativePath() {
|
||||
return this.relativePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecure() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFirstParam(String param) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQueryParamValue(String param) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpFacade.Cookie getCookie(String cookieName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHeader(String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getHeaders(String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream(boolean buffered) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRemoteAddr() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setError(AuthenticationError error) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setError(LogoutError error) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue