Compare commits
398
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4bbd603a0e | ||
|
|
23d0afbfd8 | ||
|
|
e3995c0154 | ||
|
|
e4185496fd | ||
|
|
c7ce279aef | ||
|
|
156ce0c0ea | ||
|
|
0f047ac9f5 | ||
|
|
f0c5752ef9 | ||
|
|
351dbffaf2 | ||
|
|
811cd3a04a | ||
|
|
ae573f4814 | ||
|
|
7e072abf74 | ||
|
|
e96c6a4bcb | ||
|
|
7d2d7e41d9 | ||
|
|
626004e782 | ||
|
|
3846cfdb4f | ||
|
|
902b799bdf | ||
|
|
465675ac28 | ||
|
|
2ace312501 | ||
|
|
c00d89aec3 | ||
|
|
61fe554617 | ||
|
|
5a66f577eb | ||
|
|
e29ccebc21 | ||
|
|
27b5e1aae2 | ||
|
|
71e6f52f7d | ||
|
|
b303acaaba | ||
|
|
118e998570 | ||
|
|
f3fcac2d8d | ||
|
|
b5ae7e836d | ||
|
|
a27097e9ef | ||
|
|
003f27e9bd | ||
|
|
76cccc3f2b | ||
|
|
80be4c9dbc | ||
|
|
5d7ba39e0c | ||
|
|
e2118856ca | ||
|
|
3ee760ed23 | ||
|
|
eba47b3c89 | ||
|
|
b121306749 | ||
|
|
4097a81142 | ||
|
|
ce6f73ce74 | ||
|
|
1eec2747ef | ||
|
|
6bfdc9451d | ||
|
|
a66fe003d3 | ||
|
|
7cb39c2dfc | ||
|
|
90b5dd60fd | ||
|
|
a719b73808 | ||
|
|
1c38cec10f | ||
|
|
e7c25f76a7 | ||
|
|
94928323ee | ||
|
|
e4a91c0706 | ||
|
|
a7c6eb4999 | ||
|
|
1b14f9e73e | ||
|
|
569378b446 | ||
|
|
a8943fb323 | ||
|
|
1a541889f4 | ||
|
|
b672229efc | ||
|
|
2b11938084 | ||
|
|
97e3b26a5c | ||
|
|
7e20a65989 | ||
|
|
47721957b7 | ||
|
|
068785f227 | ||
|
|
a96c9d34c9 | ||
|
|
3d0512efd8 | ||
|
|
abea430802 | ||
|
|
2a2e6c839b | ||
|
|
6696c0f0b2 | ||
|
|
958185ec51 | ||
|
|
e6a64e234b | ||
|
|
b793e42c53 | ||
|
|
f80811a065 | ||
|
|
ea3417253f | ||
|
|
7174c0b4ec | ||
|
|
0a9055e112 | ||
|
|
f939818252 | ||
|
|
b8416dfa3e | ||
|
|
63efee6e15 | ||
|
|
c3855510ef | ||
|
|
20f8e5e572 | ||
|
|
047fdb55a2 | ||
|
|
be36f5358c | ||
|
|
21dcea87c5 | ||
|
|
79c4d3e7cf | ||
|
|
a60fdcedcd | ||
|
|
dac6c6bd7e | ||
|
|
867de9de50 | ||
|
|
74442ae820 | ||
|
|
d7a90817f2 | ||
|
|
c9b218db71 | ||
|
|
7c031505e2 | ||
|
|
03e43f8964 | ||
|
|
b5c7be574b | ||
|
|
eea315a83b | ||
|
|
ce9f4bf97a | ||
|
|
5d5a200413 | ||
|
|
874dbcb3e1 | ||
|
|
10219c1157 | ||
|
|
00fb36437d | ||
|
|
4a012b73ea | ||
|
|
fce16fe030 | ||
|
|
67149ce3c3 | ||
|
|
49ba71fd8f | ||
|
|
0dee393071 | ||
|
|
464535ac81 | ||
|
|
efa5949f69 | ||
|
|
3f3d50b9ad | ||
|
|
e567dcb888 | ||
|
|
f2ba699520 | ||
|
|
c055ffb083 | ||
|
|
5fd3c9161d | ||
|
|
5fd00a0def | ||
|
|
64f8d7ce25 | ||
|
|
b8da95e901 | ||
|
|
cccddebfd0 | ||
|
|
5a8ff72cb6 | ||
|
|
ecfabe4ebe | ||
|
|
8a0fa521c4 | ||
|
|
09348b2aff | ||
|
|
896e216f99 | ||
|
|
35e60e0aa4 | ||
|
|
6d1c33ccdc | ||
|
|
f669fdf0df | ||
|
|
30ad2899b8 | ||
|
|
94ce97b972 | ||
|
|
3a7fd9e732 | ||
|
|
503ad712dc | ||
|
|
f9e40326c1 | ||
|
|
76029c7006 | ||
|
|
92cce7a6d4 | ||
|
|
916ba573bc | ||
|
|
6c34b4c418 | ||
|
|
5467d67c91 | ||
|
|
c3d9f4704e | ||
|
|
4541acc628 | ||
|
|
19cfbbf7ff | ||
|
|
ff6fcd30d9 | ||
|
|
d69fe27cf9 | ||
|
|
ca324c29e8 | ||
|
|
b4532ec629 | ||
|
|
3ee269da87 | ||
|
|
b1127ffafe | ||
|
|
37de8e9f69 | ||
|
|
4d4ee33d1d | ||
|
|
4daf6aaec5 | ||
|
|
6bb04617a6 | ||
|
|
7b03eed9c8 | ||
|
|
b466f4d0b6 | ||
|
|
b8e5fd2b99 | ||
|
|
b72b01bb9d | ||
|
|
603052c594 | ||
|
|
106599b52c | ||
|
|
17748d5ba8 | ||
|
|
4caa40fd0a | ||
|
|
674fb31a2c | ||
|
|
c5d9301951 | ||
|
|
5f43a6a342 | ||
|
|
6587cfa084 | ||
|
|
6a528a3ee6 | ||
|
|
2be78a0239 | ||
|
|
4408cdb5c7 | ||
|
|
a3288d5f8e | ||
|
|
9cae8b79e4 | ||
|
|
0bd2e63162 | ||
|
|
9ffc11d04f | ||
|
|
af66c5dbd2 | ||
|
|
83136c1bd8 | ||
|
|
d22c58ee30 | ||
|
|
de6301e65a | ||
|
|
c02c07d78e | ||
|
|
f48509c32c | ||
|
|
c5b06f23e9 | ||
|
|
fc8a8b1dd8 | ||
|
|
bf73375a5c | ||
|
|
4240295af9 | ||
|
|
3afb635110 | ||
|
|
c36b3cd296 | ||
|
|
683fe6fa03 | ||
|
|
0a8995efc7 | ||
|
|
c398f6619f | ||
|
|
33c38ceb8b | ||
|
|
b0b28e6282 | ||
|
|
792ffdf39b | ||
|
|
36314c51d6 | ||
|
|
24b7e318ca | ||
|
|
cf485c3fc9 | ||
|
|
5666bfe88b | ||
|
|
27268044ae | ||
|
|
c860ca61c3 | ||
|
|
1782d220c7 | ||
|
|
c35c6e6ab7 | ||
|
|
0e2332196d | ||
|
|
a8bcdfb401 | ||
|
|
96e481fe45 | ||
|
|
87b17a6e6c | ||
|
|
6035e5c831 | ||
|
|
9d35891e7d | ||
|
|
00677a6b92 | ||
|
|
697caaa805 | ||
|
|
fda491a966 | ||
|
|
92504e8ba3 | ||
|
|
bb900f9db8 | ||
|
|
819a60932e | ||
|
|
e4a6ee19d1 | ||
|
|
aef682cd5b | ||
|
|
dd6502013e | ||
|
|
ecbf6e5386 | ||
|
|
2721e6a5e4 | ||
|
|
e3c9fa25a3 | ||
|
|
6d91ab674b | ||
|
|
6f4ab8870e | ||
|
|
0b3ae30473 | ||
|
|
94ba85c210 | ||
|
|
2117db5e6d | ||
|
|
116bfb05c2 | ||
|
|
aee6d16f58 | ||
|
|
ae29e36e1f | ||
|
|
02220558e6 | ||
|
|
12bdf48ecc | ||
|
|
bd1072d2eb | ||
|
|
61c5a332b4 | ||
|
|
75d517a1e8 | ||
|
|
8993ca08ad | ||
|
|
afd906b9a9 | ||
|
|
c083c1c4cf | ||
|
|
d78bc37253 | ||
|
|
d0ee1e6ee5 | ||
|
|
c16c02b0cf | ||
|
|
7fd237b40b | ||
|
|
a993f6fb75 | ||
|
|
5f20df00d0 | ||
|
|
186b10ab53 | ||
|
|
06762ba13d | ||
|
|
08ca03051c | ||
|
|
8f82440103 | ||
|
|
9485a63157 | ||
|
|
37b625fd99 | ||
|
|
8e53ccf5ab | ||
|
|
7c0c48da01 | ||
|
|
ff5010cdd0 | ||
|
|
0940c922ef | ||
|
|
83ff0eab10 | ||
|
|
c66ff60c58 | ||
|
|
feaf834184 | ||
|
|
805e9288fa | ||
|
|
641069d4fd | ||
|
|
a06fd31412 | ||
|
|
07aa718cb9 | ||
|
|
f186ea12c6 | ||
|
|
dc05134e41 | ||
|
|
f96c3312e2 | ||
|
|
d1579f62a3 | ||
|
|
86fb18395e | ||
|
|
bc28223a77 | ||
|
|
f923211e9f | ||
|
|
6f2ba821a6 | ||
|
|
8839278da7 | ||
|
|
485ba4a3e4 | ||
|
|
bd25040e22 | ||
|
|
c4a1764801 | ||
|
|
3c48ee39d9 | ||
|
|
a787cfa33a | ||
|
|
1bd2f0e98f | ||
|
|
393fae74b3 | ||
|
|
a2f6c16764 | ||
|
|
a70461b726 | ||
|
|
6b8ead6c4b | ||
|
|
8b023f57f9 | ||
|
|
eebf0b0499 | ||
|
|
63a01b1e1f | ||
|
|
913c94dbd1 | ||
|
|
0c414eee80 | ||
|
|
b0ccce397a | ||
|
|
6731c55429 | ||
|
|
fdb618219f | ||
|
|
89f4b87038 | ||
|
|
ea869a3008 | ||
|
|
1412fed265 | ||
|
|
de72542151 | ||
|
|
03d0488335 | ||
|
|
925d5e1dea | ||
|
|
d8b3654011 | ||
|
|
51c7917853 | ||
|
|
d30bf938ee | ||
|
|
5d8f449ea0 | ||
|
|
290f6ed2ad | ||
|
|
98a46c4497 | ||
|
|
d02ffd33b3 | ||
|
|
a5b73a365d | ||
|
|
71df504834 | ||
|
|
8cfbb8d0b3 | ||
|
|
0f4b8be2b0 | ||
|
|
af97a84108 | ||
|
|
e28f402b6b | ||
|
|
0dfbe01c73 | ||
|
|
90900b1a1f | ||
|
|
4295f4ec31 | ||
|
|
c530a061cc | ||
|
|
04ad634986 | ||
|
|
d4b9c3c014 | ||
|
|
bc3515fd1b | ||
|
|
b033ce0669 | ||
|
|
7035a4647d | ||
|
|
39345b0b61 | ||
|
|
8b8e694c60 | ||
|
|
a98f085be6 | ||
|
|
128ff12f8f | ||
|
|
e28652489e | ||
|
|
dae0fafc8a | ||
|
|
19eed51582 | ||
|
|
9ff22f596d | ||
|
|
e1af9f133f | ||
|
|
26e253f4a5 | ||
|
|
2854a2006e | ||
|
|
518824e41b | ||
|
|
3bf1904269 | ||
|
|
2c2a332f80 | ||
|
|
8759b42e6b | ||
|
|
bf937452c6 | ||
|
|
9243430b75 | ||
|
|
b21d5bbf04 | ||
|
|
5119dc3ad5 | ||
|
|
476dd1cef5 | ||
|
|
a8ba3eb7f9 | ||
|
|
d3b270d025 | ||
|
|
b8f3c8a445 | ||
|
|
eb46f403d6 | ||
|
|
9c0ec8cb10 | ||
|
|
d268412738 | ||
|
|
e360aadcd4 | ||
|
|
f88b3cddb6 | ||
|
|
56548fcaf0 | ||
|
|
fce9cc205c | ||
|
|
701b7acd80 | ||
|
|
819181007c | ||
|
|
7cf52044b2 | ||
|
|
d1468eaa45 | ||
|
|
afb4a59b19 | ||
|
|
b1a05dfce2 | ||
|
|
62a1c187a2 | ||
|
|
1db3134df8 | ||
|
|
ffc0d7fc7c | ||
|
|
fe2f65daac | ||
|
|
ef8adc15f4 | ||
|
|
1ac9bd510b | ||
|
|
4d0d28c222 | ||
|
|
6b0c58bab3 | ||
|
|
3716fa44ac | ||
|
|
d3dee07956 | ||
|
|
986540ab34 | ||
|
|
c9aa5e638e | ||
|
|
8d879867b5 | ||
|
|
92027e4c57 | ||
|
|
081ad09ed8 | ||
|
|
b0d88be420 | ||
|
|
57d3c44bb7 | ||
|
|
a70cab502c | ||
|
|
12b2e72162 | ||
|
|
a45a2acc4c | ||
|
|
8cbdbb2fed | ||
|
|
9e2ab2750a | ||
|
|
aabd47ecdf | ||
|
|
248da4687a | ||
|
|
2b44cb70af | ||
|
|
906538e6aa | ||
|
|
75c354fd94 | ||
|
|
9bd5d31c1f | ||
|
|
903a4dd849 | ||
|
|
de6eab6d5d | ||
|
|
8c1a3253fb | ||
|
|
375e01a074 | ||
|
|
74f5c1c160 | ||
|
|
5f889dd3c6 | ||
|
|
50ccb5e5f6 | ||
|
|
9793e6aa25 | ||
|
|
2dd6a2e655 | ||
|
|
1840cc54e4 | ||
|
|
7190820fc4 | ||
|
|
80e9b08bb6 | ||
|
|
4d762159ef | ||
|
|
a7bc294a08 | ||
|
|
8e0cc2a5ea | ||
|
|
bc12193c3c | ||
|
|
7dd7b6b984 | ||
|
|
711aa83d31 | ||
|
|
a6e1413d58 | ||
|
|
a4ec32ba66 | ||
|
|
9a19e95b60 | ||
|
|
f0bbcbf0fd | ||
|
|
223713bc53 | ||
|
|
330f2acc29 | ||
|
|
4010e5e247 | ||
|
|
574fd42534 | ||
|
|
9083e5fe5c | ||
|
|
1eb2d894e5 | ||
|
|
9b75b603e3 | ||
|
|
faf830dc77 | ||
|
|
a3a1761eb7 | ||
|
|
1dd2a90e20 | ||
|
|
bd706418c9 |
No files matched your search
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+20
@@ -206,6 +206,16 @@ public class AdapterDeploymentContext {
|
||||
public void setBearerOnly(boolean bearerOnly) {
|
||||
delegate.setBearerOnly(bearerOnly);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutodetectBearerOnly() {
|
||||
return delegate.isAutodetectBearerOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAutodetectBearerOnly(boolean autodetectBearerOnly) {
|
||||
delegate.setAutodetectBearerOnly(autodetectBearerOnly);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnableBasicAuth() {
|
||||
@@ -277,6 +287,16 @@ public class AdapterDeploymentContext {
|
||||
delegate.setSslRequired(sslRequired);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getConfidentialPort() {
|
||||
return delegate.getConfidentialPort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConfidentialPort(int confidentialPort) {
|
||||
delegate.setConfidentialPort(confidentialPort);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TokenStore getTokenStore() {
|
||||
return delegate.getTokenStore();
|
||||
|
||||
+6
-5
@@ -71,9 +71,10 @@ public class BasicAuthRequestAuthenticator extends BearerTokenRequestAuthenticat
|
||||
AccessTokenResponse atr=null;
|
||||
try {
|
||||
String userpw=new String(Base64.decode(tokenString));
|
||||
String[] parts=userpw.split(":");
|
||||
|
||||
atr = getToken(parts[0], parts[1]);
|
||||
int seperatorIndex = userpw.indexOf(":");
|
||||
String user = userpw.substring(0, seperatorIndex);
|
||||
String pw = userpw.substring(seperatorIndex + 1);
|
||||
atr = getToken(user, pw);
|
||||
tokenString = atr.getToken();
|
||||
} catch (Exception e) {
|
||||
log.debug("Failed to obtain token", e);
|
||||
@@ -82,8 +83,8 @@ public class BasicAuthRequestAuthenticator extends BearerTokenRequestAuthenticat
|
||||
}
|
||||
|
||||
return authenticateToken(exchange, atr.getToken());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private AccessTokenResponse getToken(String username, String password) throws Exception {
|
||||
AccessTokenResponse tokenResponse=null;
|
||||
HttpClient client = deployment.getClient();
|
||||
|
||||
+13
@@ -23,6 +23,8 @@ import org.keycloak.adapters.spi.AuthChallenge;
|
||||
import org.keycloak.adapters.spi.AuthOutcome;
|
||||
import org.keycloak.adapters.spi.HttpFacade;
|
||||
import org.keycloak.common.VerificationException;
|
||||
import org.keycloak.jose.jws.JWSInput;
|
||||
import org.keycloak.jose.jws.JWSInputException;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
|
||||
import javax.security.cert.X509Certificate;
|
||||
@@ -83,6 +85,16 @@ public class BearerTokenRequestAuthenticator {
|
||||
}
|
||||
|
||||
protected AuthOutcome authenticateToken(HttpFacade exchange, String tokenString) {
|
||||
log.debug("Verifying access_token");
|
||||
if (log.isTraceEnabled()) {
|
||||
try {
|
||||
JWSInput jwsInput = new JWSInput(tokenString);
|
||||
String wireString = jwsInput.getWireString();
|
||||
log.tracef("\taccess_token: %s", wireString.substring(0, wireString.lastIndexOf(".")) + ".signature");
|
||||
} catch (JWSInputException e) {
|
||||
log.errorf(e, "Failed to parse access_token: %s", tokenString);
|
||||
}
|
||||
}
|
||||
try {
|
||||
token = AdapterRSATokenVerifier.verifyToken(tokenString, deployment);
|
||||
} catch (VerificationException e) {
|
||||
@@ -124,6 +136,7 @@ public class BearerTokenRequestAuthenticator {
|
||||
}
|
||||
surrogate = chain[0].getSubjectDN().getName();
|
||||
}
|
||||
log.debug("successful authorized");
|
||||
return AuthOutcome.AUTHENTICATED;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,8 @@ import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.apache.http.client.params.ClientPNames;
|
||||
import org.apache.http.client.params.CookiePolicy;
|
||||
|
||||
/**
|
||||
* Abstraction for creating HttpClients. Allows SSL configuration.
|
||||
@@ -289,6 +291,7 @@ public class HttpClientBuilder {
|
||||
cm = new SingleClientConnManager(registry);
|
||||
}
|
||||
BasicHttpParams params = new BasicHttpParams();
|
||||
params.setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
|
||||
|
||||
if (proxyHost != null) {
|
||||
params.setParameter(ConnRoutePNames.DEFAULT_PROXY, proxyHost);
|
||||
|
||||
+11
@@ -68,6 +68,7 @@ public class KeycloakDeployment {
|
||||
|
||||
protected String scope;
|
||||
protected SslRequired sslRequired = SslRequired.ALL;
|
||||
protected int confidentialPort = -1;
|
||||
protected TokenStore tokenStore = TokenStore.SESSION;
|
||||
protected String stateCookieName = "OAuth_Token_Request_State";
|
||||
protected boolean useResourceRoleMappings;
|
||||
@@ -153,6 +154,8 @@ public class KeycloakDeployment {
|
||||
log.debug("resolveUrls");
|
||||
}
|
||||
|
||||
authServerBaseUrl = authUrlBuilder.build().toString();
|
||||
|
||||
String login = authUrlBuilder.clone().path(ServiceUrlConstants.AUTH_PATH).build(getRealm()).toString();
|
||||
authUrl = KeycloakUriBuilder.fromUri(login);
|
||||
realmInfoUrl = authUrlBuilder.clone().path(ServiceUrlConstants.REALM_INFO_PATH).build(getRealm()).toString();
|
||||
@@ -277,6 +280,14 @@ public class KeycloakDeployment {
|
||||
this.sslRequired = sslRequired;
|
||||
}
|
||||
|
||||
public int getConfidentialPort() {
|
||||
return confidentialPort;
|
||||
}
|
||||
|
||||
public void setConfidentialPort(int confidentialPort) {
|
||||
this.confidentialPort = confidentialPort;
|
||||
}
|
||||
|
||||
public TokenStore getTokenStore() {
|
||||
return tokenStore;
|
||||
}
|
||||
|
||||
+5
@@ -78,6 +78,11 @@ public class KeycloakDeploymentBuilder {
|
||||
} else {
|
||||
deployment.setSslRequired(SslRequired.EXTERNAL);
|
||||
}
|
||||
|
||||
if (adapterConfig.getConfidentialPort() != -1) {
|
||||
deployment.setConfidentialPort(adapterConfig.getConfidentialPort());
|
||||
}
|
||||
|
||||
if (adapterConfig.getTokenStore() != null) {
|
||||
deployment.setTokenStore(TokenStore.valueOf(adapterConfig.getTokenStore().toUpperCase()));
|
||||
} else {
|
||||
|
||||
+26
-2
@@ -66,7 +66,7 @@ public class OAuthRequestAuthenticator {
|
||||
this.reqAuthenticator = requestAuthenticator;
|
||||
this.facade = facade;
|
||||
this.deployment = deployment;
|
||||
this.sslRedirectPort = sslRedirectPort;
|
||||
this.sslRedirectPort = deployment.getConfidentialPort() != -1 ? deployment.getConfidentialPort() : sslRedirectPort;
|
||||
this.tokenStore = tokenStore;
|
||||
}
|
||||
|
||||
@@ -170,6 +170,9 @@ public class OAuthRequestAuthenticator {
|
||||
String maxAge = getQueryParamValue(OAuth2Constants.MAX_AGE);
|
||||
url = UriUtils.stripQueryParam(url, OAuth2Constants.MAX_AGE);
|
||||
|
||||
String uiLocales = getQueryParamValue(OAuth2Constants.UI_LOCALES_PARAM);
|
||||
url = UriUtils.stripQueryParam(url, OAuth2Constants.UI_LOCALES_PARAM);
|
||||
|
||||
KeycloakUriBuilder redirectUriBuilder = deployment.getAuthUrl().clone()
|
||||
.queryParam(OAuth2Constants.RESPONSE_TYPE, OAuth2Constants.CODE)
|
||||
.queryParam(OAuth2Constants.CLIENT_ID, deployment.getResourceName())
|
||||
@@ -188,6 +191,9 @@ public class OAuthRequestAuthenticator {
|
||||
if (maxAge != null && maxAge.length() > 0) {
|
||||
redirectUriBuilder.queryParam(OAuth2Constants.MAX_AGE, maxAge);
|
||||
}
|
||||
if (uiLocales != null && uiLocales.length() > 0) {
|
||||
redirectUriBuilder.queryParam(OAuth2Constants.UI_LOCALES_PARAM, uiLocales);
|
||||
}
|
||||
|
||||
scope = TokenUtil.attachOIDCScope(scope);
|
||||
redirectUriBuilder.queryParam(OAuth2Constants.SCOPE, scope);
|
||||
@@ -344,6 +350,14 @@ public class OAuthRequestAuthenticator {
|
||||
tokenString = tokenResponse.getToken();
|
||||
refreshToken = tokenResponse.getRefreshToken();
|
||||
idTokenString = tokenResponse.getIdToken();
|
||||
|
||||
log.debug("Verifying tokens");
|
||||
if (log.isTraceEnabled()) {
|
||||
logToken("\taccess_token", tokenString);
|
||||
logToken("\tid_token", idTokenString);
|
||||
logToken("\trefresh_token", refreshToken);
|
||||
}
|
||||
|
||||
try {
|
||||
token = AdapterRSATokenVerifier.verifyToken(tokenString, deployment);
|
||||
if (idTokenString != null) {
|
||||
@@ -376,7 +390,8 @@ public class OAuthRequestAuthenticator {
|
||||
protected String stripOauthParametersFromRedirect() {
|
||||
KeycloakUriBuilder builder = KeycloakUriBuilder.fromUri(facade.getRequest().getURI())
|
||||
.replaceQueryParam(OAuth2Constants.CODE, null)
|
||||
.replaceQueryParam(OAuth2Constants.STATE, null);
|
||||
.replaceQueryParam(OAuth2Constants.STATE, null)
|
||||
.replaceQueryParam(OAuth2Constants.SESSION_STATE, null);
|
||||
return builder.build().toString();
|
||||
}
|
||||
|
||||
@@ -398,4 +413,13 @@ public class OAuthRequestAuthenticator {
|
||||
return originalUri;
|
||||
}
|
||||
|
||||
private void logToken(String name, String token) {
|
||||
try {
|
||||
JWSInput jwsInput = new JWSInput(token);
|
||||
String wireString = jwsInput.getWireString();
|
||||
log.tracef("\t%s: %s", name, wireString.substring(0, wireString.lastIndexOf(".")) + ".signature");
|
||||
} catch (JWSInputException e) {
|
||||
log.errorf(e, "Failed to parse %s: %s", name, token);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -32,7 +32,7 @@ import java.util.Map;
|
||||
*/
|
||||
public class ClientIdAndSecretCredentialsProvider implements ClientCredentialsProvider {
|
||||
|
||||
private static Logger logger = Logger.getLogger(ClientCredentialsProviderUtils.class);
|
||||
private static Logger logger = Logger.getLogger(ClientIdAndSecretCredentialsProvider.class);
|
||||
|
||||
public static final String PROVIDER_ID = CredentialRepresentation.SECRET;
|
||||
|
||||
|
||||
+41
-18
@@ -33,6 +33,7 @@ import org.keycloak.authorization.client.ClientAuthorizationContext;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig;
|
||||
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.EnforcementMode;
|
||||
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.MethodConfig;
|
||||
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.PathConfig;
|
||||
import org.keycloak.representations.idm.authorization.Permission;
|
||||
|
||||
@@ -96,9 +97,9 @@ public abstract class AbstractPolicyEnforcer {
|
||||
return createEmptyAuthorizationContext(true);
|
||||
}
|
||||
|
||||
Set<String> requiredScopes = getRequiredScopes(pathConfig, request);
|
||||
MethodConfig methodConfig = getRequiredScopes(pathConfig, request);
|
||||
|
||||
if (isAuthorized(pathConfig, requiredScopes, accessToken, httpFacade)) {
|
||||
if (isAuthorized(pathConfig, methodConfig, accessToken, httpFacade)) {
|
||||
try {
|
||||
return createAuthorizationContext(accessToken, pathConfig);
|
||||
} catch (Exception e) {
|
||||
@@ -108,7 +109,7 @@ public abstract class AbstractPolicyEnforcer {
|
||||
|
||||
LOGGER.debugf("Sending challenge to the client. Path [%s]", pathConfig);
|
||||
|
||||
if (!challenge(pathConfig, requiredScopes, httpFacade)) {
|
||||
if (!challenge(pathConfig, methodConfig, httpFacade)) {
|
||||
LOGGER.debugf("Challenge not sent, sending default forbidden response. Path [%s]", pathConfig);
|
||||
handleAccessDenied(httpFacade);
|
||||
}
|
||||
@@ -118,9 +119,9 @@ public abstract class AbstractPolicyEnforcer {
|
||||
return createEmptyAuthorizationContext(false);
|
||||
}
|
||||
|
||||
protected abstract boolean challenge(PathConfig pathConfig, Set<String> requiredScopes, OIDCHttpFacade facade);
|
||||
protected abstract boolean challenge(PathConfig pathConfig, MethodConfig methodConfig, OIDCHttpFacade facade);
|
||||
|
||||
protected boolean isAuthorized(PathConfig actualPathConfig, Set<String> requiredScopes, AccessToken accessToken, OIDCHttpFacade httpFacade) {
|
||||
protected boolean isAuthorized(PathConfig actualPathConfig, MethodConfig methodConfig, AccessToken accessToken, OIDCHttpFacade httpFacade) {
|
||||
Request request = httpFacade.getRequest();
|
||||
PolicyEnforcerConfig enforcerConfig = getEnforcerConfig();
|
||||
|
||||
@@ -146,7 +147,7 @@ public abstract class AbstractPolicyEnforcer {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hasResourceScopePermission(requiredScopes, permission, actualPathConfig)) {
|
||||
if (hasResourceScopePermission(methodConfig, permission)) {
|
||||
LOGGER.debugf("Authorization GRANTED for path [%s]. Permissions [%s].", actualPathConfig, permissions);
|
||||
if (request.getMethod().equalsIgnoreCase("DELETE") && actualPathConfig.isInstance()) {
|
||||
this.paths.remove(actualPathConfig);
|
||||
@@ -155,7 +156,7 @@ public abstract class AbstractPolicyEnforcer {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (hasResourceScopePermission(requiredScopes, permission, actualPathConfig)) {
|
||||
if (hasResourceScopePermission(methodConfig, permission)) {
|
||||
hasPermission = true;
|
||||
return true;
|
||||
}
|
||||
@@ -166,7 +167,7 @@ public abstract class AbstractPolicyEnforcer {
|
||||
return true;
|
||||
}
|
||||
|
||||
LOGGER.debugf("Authorization FAILED for path [%s]. No enough permissions [%s].", actualPathConfig, permissions);
|
||||
LOGGER.debugf("Authorization FAILED for path [%s]. Not enough permissions [%s].", actualPathConfig, permissions);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -186,9 +187,29 @@ public abstract class AbstractPolicyEnforcer {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean hasResourceScopePermission(Set<String> requiredScopes, Permission permission, PathConfig actualPathConfig) {
|
||||
private boolean hasResourceScopePermission(MethodConfig methodConfig, Permission permission) {
|
||||
List<String> requiredScopes = methodConfig.getScopes();
|
||||
Set<String> allowedScopes = permission.getScopes();
|
||||
return (allowedScopes.containsAll(requiredScopes) || allowedScopes.isEmpty());
|
||||
|
||||
if (allowedScopes.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
PolicyEnforcerConfig.ScopeEnforcementMode enforcementMode = methodConfig.getScopesEnforcementMode();
|
||||
|
||||
if (PolicyEnforcerConfig.ScopeEnforcementMode.ALL.equals(enforcementMode)) {
|
||||
return allowedScopes.containsAll(requiredScopes);
|
||||
}
|
||||
|
||||
if (PolicyEnforcerConfig.ScopeEnforcementMode.ANY.equals(enforcementMode)) {
|
||||
for (String requiredScope : requiredScopes) {
|
||||
if (allowedScopes.contains(requiredScope)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return requiredScopes.isEmpty();
|
||||
}
|
||||
|
||||
protected AuthzClient getAuthzClient() {
|
||||
@@ -236,20 +257,22 @@ public abstract class AbstractPolicyEnforcer {
|
||||
return request.getRelativePath();
|
||||
}
|
||||
|
||||
private Set<String> getRequiredScopes(PathConfig pathConfig, Request request) {
|
||||
Set<String> requiredScopes = new HashSet<>();
|
||||
|
||||
requiredScopes.addAll(pathConfig.getScopes());
|
||||
|
||||
private MethodConfig getRequiredScopes(PathConfig pathConfig, Request request) {
|
||||
String method = request.getMethod();
|
||||
|
||||
for (PolicyEnforcerConfig.MethodConfig methodConfig : pathConfig.getMethods()) {
|
||||
for (MethodConfig methodConfig : pathConfig.getMethods()) {
|
||||
if (methodConfig.getMethod().equals(method)) {
|
||||
requiredScopes.addAll(methodConfig.getScopes());
|
||||
return methodConfig;
|
||||
}
|
||||
}
|
||||
|
||||
return requiredScopes;
|
||||
MethodConfig methodConfig = new MethodConfig();
|
||||
|
||||
methodConfig.setMethod(request.getMethod());
|
||||
methodConfig.setScopes(pathConfig.getScopes());
|
||||
methodConfig.setScopesEnforcementMode(PolicyEnforcerConfig.ScopeEnforcementMode.ANY);
|
||||
|
||||
return methodConfig;
|
||||
}
|
||||
|
||||
private AuthorizationContext createAuthorizationContext(AccessToken accessToken, PathConfig pathConfig) {
|
||||
|
||||
+8
-7
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
package org.keycloak.adapters.authorization;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.adapters.OIDCHttpFacade;
|
||||
@@ -26,6 +26,7 @@ import org.keycloak.authorization.client.AuthzClient;
|
||||
import org.keycloak.authorization.client.representation.PermissionRequest;
|
||||
import org.keycloak.authorization.client.resource.PermissionResource;
|
||||
import org.keycloak.authorization.client.resource.ProtectionResource;
|
||||
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig;
|
||||
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.PathConfig;
|
||||
|
||||
/**
|
||||
@@ -40,9 +41,9 @@ public class BearerTokenPolicyEnforcer extends AbstractPolicyEnforcer {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean challenge(PathConfig pathConfig, Set<String> requiredScopes, OIDCHttpFacade facade) {
|
||||
protected boolean challenge(PathConfig pathConfig, PolicyEnforcerConfig.MethodConfig methodConfig, OIDCHttpFacade facade) {
|
||||
if (getEnforcerConfig().getUserManagedAccess() != null) {
|
||||
challengeUmaAuthentication(pathConfig, requiredScopes, facade);
|
||||
challengeUmaAuthentication(pathConfig, methodConfig, facade);
|
||||
} else {
|
||||
challengeEntitlementAuthentication(facade);
|
||||
}
|
||||
@@ -61,10 +62,10 @@ public class BearerTokenPolicyEnforcer extends AbstractPolicyEnforcer {
|
||||
}
|
||||
}
|
||||
|
||||
private void challengeUmaAuthentication(PathConfig pathConfig, Set<String> requiredScopes, OIDCHttpFacade facade) {
|
||||
private void challengeUmaAuthentication(PathConfig pathConfig, PolicyEnforcerConfig.MethodConfig methodConfig, OIDCHttpFacade facade) {
|
||||
HttpFacade.Response response = facade.getResponse();
|
||||
AuthzClient authzClient = getAuthzClient();
|
||||
String ticket = getPermissionTicket(pathConfig, requiredScopes, authzClient);
|
||||
String ticket = getPermissionTicket(pathConfig, methodConfig, authzClient);
|
||||
String clientId = authzClient.getConfiguration().getResource();
|
||||
String authorizationServerUri = authzClient.getServerConfiguration().getIssuer().toString() + "/authz/authorize";
|
||||
response.setStatus(401);
|
||||
@@ -74,12 +75,12 @@ public class BearerTokenPolicyEnforcer extends AbstractPolicyEnforcer {
|
||||
}
|
||||
}
|
||||
|
||||
private String getPermissionTicket(PathConfig pathConfig, Set<String> requiredScopes, AuthzClient authzClient) {
|
||||
private String getPermissionTicket(PathConfig pathConfig, PolicyEnforcerConfig.MethodConfig methodConfig, AuthzClient authzClient) {
|
||||
ProtectionResource protection = authzClient.protection();
|
||||
PermissionResource permission = protection.permission();
|
||||
PermissionRequest permissionRequest = new PermissionRequest();
|
||||
permissionRequest.setResourceSetId(pathConfig.getId());
|
||||
permissionRequest.setScopes(requiredScopes);
|
||||
permissionRequest.setScopes(new HashSet<>(methodConfig.getScopes()));
|
||||
return permission.forResource(permissionRequest).getTicket();
|
||||
}
|
||||
}
|
||||
+8
-7
@@ -35,6 +35,7 @@ import org.keycloak.authorization.client.representation.EntitlementResponse;
|
||||
import org.keycloak.authorization.client.representation.PermissionRequest;
|
||||
import org.keycloak.authorization.client.representation.PermissionResponse;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig;
|
||||
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.PathConfig;
|
||||
import org.keycloak.representations.idm.authorization.Permission;
|
||||
|
||||
@@ -50,14 +51,14 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isAuthorized(PathConfig pathConfig, Set<String> requiredScopes, AccessToken accessToken, OIDCHttpFacade httpFacade) {
|
||||
protected boolean isAuthorized(PathConfig pathConfig, PolicyEnforcerConfig.MethodConfig methodConfig, AccessToken accessToken, OIDCHttpFacade httpFacade) {
|
||||
AccessToken original = accessToken;
|
||||
|
||||
if (super.isAuthorized(pathConfig, requiredScopes, accessToken, httpFacade)) {
|
||||
if (super.isAuthorized(pathConfig, methodConfig, accessToken, httpFacade)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
accessToken = requestAuthorizationToken(pathConfig, requiredScopes, httpFacade);
|
||||
accessToken = requestAuthorizationToken(pathConfig, methodConfig, httpFacade);
|
||||
|
||||
if (accessToken == null) {
|
||||
return false;
|
||||
@@ -78,11 +79,11 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
|
||||
|
||||
original.setAuthorization(authorization);
|
||||
|
||||
return super.isAuthorized(pathConfig, requiredScopes, accessToken, httpFacade);
|
||||
return super.isAuthorized(pathConfig, methodConfig, accessToken, httpFacade);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean challenge(PathConfig pathConfig, Set<String> requiredScopes, OIDCHttpFacade facade) {
|
||||
protected boolean challenge(PathConfig pathConfig, PolicyEnforcerConfig.MethodConfig methodConfig, OIDCHttpFacade facade) {
|
||||
handleAccessDenied(facade);
|
||||
return true;
|
||||
}
|
||||
@@ -100,7 +101,7 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
|
||||
}
|
||||
}
|
||||
|
||||
private AccessToken requestAuthorizationToken(PathConfig pathConfig, Set<String> requiredScopes, OIDCHttpFacade httpFacade) {
|
||||
private AccessToken requestAuthorizationToken(PathConfig pathConfig, PolicyEnforcerConfig.MethodConfig methodConfig, OIDCHttpFacade httpFacade) {
|
||||
try {
|
||||
String accessToken = httpFacade.getSecurityContext().getTokenString();
|
||||
AuthzClient authzClient = getAuthzClient();
|
||||
@@ -111,7 +112,7 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
|
||||
PermissionRequest permissionRequest = new PermissionRequest();
|
||||
|
||||
permissionRequest.setResourceSetId(pathConfig.getId());
|
||||
permissionRequest.setScopes(requiredScopes);
|
||||
permissionRequest.setScopes(new HashSet<>(methodConfig.getScopes()));
|
||||
|
||||
PermissionResponse permissionResponse = authzClient.protection().permission().forResource(permissionRequest);
|
||||
AuthorizationRequest authzRequest = new AuthorizationRequest(permissionResponse.getTicket());
|
||||
|
||||
+1
-1
@@ -81,7 +81,7 @@ public class JWKPublicKeyLocator implements PublicKeyLocator {
|
||||
|
||||
|
||||
private PublicKey lookupCachedKey(int publicKeyCacheTtl, int currentTime, String kid) {
|
||||
if (lastRequestTime + publicKeyCacheTtl > currentTime) {
|
||||
if (lastRequestTime + publicKeyCacheTtl > currentTime && kid != null) {
|
||||
return currentKeys.get(kid);
|
||||
} else {
|
||||
return null;
|
||||
|
||||
+19
@@ -17,7 +17,9 @@
|
||||
package org.keycloak.adapters;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.keycloak.representations.adapters.config.AdapterConfig;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@@ -46,4 +48,21 @@ public class KeycloakDeploymentTest {
|
||||
|
||||
assertTrue(keycloakDeployment.isOAuthQueryParameterEnabled());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stripDefaultPorts() {
|
||||
KeycloakDeployment keycloakDeployment = new KeycloakDeployment();
|
||||
keycloakDeployment.setRealm("test");
|
||||
AdapterConfig config = new AdapterConfig();
|
||||
config.setAuthServerUrl("http://localhost:80/auth");
|
||||
keycloakDeployment.setAuthServerBaseUrl(config);
|
||||
|
||||
assertEquals("http://localhost/auth", keycloakDeployment.getAuthServerBaseUrl());
|
||||
|
||||
config.setAuthServerUrl("https://localhost:443/auth");
|
||||
keycloakDeployment.setAuthServerBaseUrl(config);
|
||||
|
||||
assertEquals("https://localhost/auth", keycloakDeployment.getAuthServerBaseUrl());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-as7-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-as7-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-as7-integration-pom</artifactId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak AS7 / JBoss EAP 6 Integration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak Jetty Integration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -159,10 +159,12 @@
|
||||
var callback = parseCallback(window.location.href);
|
||||
|
||||
if (callback) {
|
||||
setupCheckLoginIframe();
|
||||
window.history.replaceState({}, null, callback.newUrl);
|
||||
processCallback(callback, initPromise);
|
||||
return;
|
||||
return setupCheckLoginIframe().success(function() {
|
||||
window.history.replaceState({}, null, callback.newUrl);
|
||||
processCallback(callback, initPromise);
|
||||
}).error(function (e) {
|
||||
initPromise.setError();
|
||||
});
|
||||
} else if (initOptions) {
|
||||
if (initOptions.token && initOptions.refreshToken) {
|
||||
setToken(initOptions.token, initOptions.refreshToken, initOptions.idToken);
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
req.onreadystatechange = function () {
|
||||
if (req.readyState === 4) {
|
||||
if (req.status === 204) {
|
||||
if (req.status === 204 || req.status === 1223) {
|
||||
init = {
|
||||
clientId: clientId,
|
||||
origin: origin
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak OIDC Client Adapter Modules</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-boot-container-bundle</artifactId>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+5
-3
@@ -132,10 +132,8 @@ public class KeycloakAutoConfiguration {
|
||||
loginConfig.addFirstAuthMethod("KEYCLOAK");
|
||||
|
||||
deploymentInfo.setLoginConfig(loginConfig);
|
||||
|
||||
deploymentInfo.addInitParameter("keycloak.config.resolver", KeycloakSpringBootConfigResolver.class.getName());
|
||||
deploymentInfo.addSecurityConstraints(getSecurityConstraints());
|
||||
|
||||
deploymentInfo.addServletExtension(new KeycloakServletExtension());
|
||||
}
|
||||
|
||||
@@ -157,7 +155,6 @@ public class KeycloakAutoConfiguration {
|
||||
undertowSecurityConstraint.addWebResourceCollections(webResourceCollection);
|
||||
|
||||
}
|
||||
|
||||
undertowSecurityConstraints.add(undertowSecurityConstraint);
|
||||
}
|
||||
return undertowSecurityConstraints;
|
||||
@@ -280,6 +277,11 @@ public class KeycloakAutoConfiguration {
|
||||
|
||||
for (String authRole : constraint.getAuthRoles()) {
|
||||
tomcatConstraint.addAuthRole(authRole);
|
||||
if(authRole.equals("*") || authRole.equals("**")) {
|
||||
// For some reasons embed tomcat don't set the auth constraint on true when wildcard is
|
||||
// used
|
||||
tomcatConstraint.setAuthConstraint(true);
|
||||
}
|
||||
}
|
||||
|
||||
for (KeycloakSpringBootProperties.SecurityCollection collection : constraint.getSecurityCollections()) {
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+1
-5
@@ -45,11 +45,7 @@ public class HttpHeaderInspectingApiRequestMatcher implements RequestMatcher {
|
||||
*/
|
||||
@Override
|
||||
public boolean matches(HttpServletRequest request) {
|
||||
boolean ajax = X_REQUESTED_WITH_HEADER_AJAX_VALUE.equals(request.getHeader(X_REQUESTED_WITH_HEADER));
|
||||
boolean html = request.getHeader(HttpHeaders.ACCEPT) != null && request.getHeader(HttpHeaders.ACCEPT).contains(
|
||||
MediaType.TEXT_HTML_VALUE);
|
||||
|
||||
return ajax || !html;
|
||||
return X_REQUESTED_WITH_HEADER_AJAX_VALUE.equals(request.getHeader(X_REQUESTED_WITH_HEADER));
|
||||
}
|
||||
|
||||
}
|
||||
+15
-17
@@ -17,7 +17,16 @@
|
||||
|
||||
package org.keycloak.adapters.springsecurity.authentication;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.http.HttpHeaders;
|
||||
import org.keycloak.adapters.AdapterDeploymentContext;
|
||||
import org.keycloak.adapters.spi.HttpFacade;
|
||||
import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@@ -26,17 +35,6 @@ import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import org.keycloak.adapters.AdapterDeploymentContext;
|
||||
import org.keycloak.adapters.spi.HttpFacade;
|
||||
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
|
||||
import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
||||
/**
|
||||
* Provides a Keycloak {@link AuthenticationEntryPoint authentication entry point}. Uses a
|
||||
* {@link RequestMatcher} to determine if the request is an interactive login request or a
|
||||
@@ -62,15 +60,14 @@ public class KeycloakAuthenticationEntryPoint implements AuthenticationEntryPoin
|
||||
private final RequestMatcher apiRequestMatcher;
|
||||
private String loginUri = DEFAULT_LOGIN_URI;
|
||||
private String realm = DEFAULT_REALM;
|
||||
|
||||
|
||||
private AdapterDeploymentContext adapterDeploymentContext;
|
||||
|
||||
/**
|
||||
* Creates a new Keycloak authentication entry point.
|
||||
*/
|
||||
public KeycloakAuthenticationEntryPoint(AdapterDeploymentContext adapterDeploymentContext) {
|
||||
this(DEFAULT_API_REQUEST_MATCHER);
|
||||
this.adapterDeploymentContext = adapterDeploymentContext;
|
||||
this(adapterDeploymentContext, DEFAULT_API_REQUEST_MATCHER);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,14 +77,15 @@ public class KeycloakAuthenticationEntryPoint implements AuthenticationEntryPoin
|
||||
* @param apiRequestMatcher the <code>RequestMatcher</code> to use to determine
|
||||
* if the current request is an API request or a browser request (required)
|
||||
*/
|
||||
public KeycloakAuthenticationEntryPoint(RequestMatcher apiRequestMatcher) {
|
||||
public KeycloakAuthenticationEntryPoint(AdapterDeploymentContext adapterDeploymentContext, RequestMatcher apiRequestMatcher) {
|
||||
Assert.notNull(apiRequestMatcher, "apiRequestMatcher required");
|
||||
Assert.notNull(adapterDeploymentContext, "adapterDeploymentContext required");
|
||||
this.adapterDeploymentContext = adapterDeploymentContext;
|
||||
this.apiRequestMatcher = apiRequestMatcher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException
|
||||
{
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
|
||||
HttpFacade facade = new SimpleHttpFacade(request, response);
|
||||
if (apiRequestMatcher.matches(request) || adapterDeploymentContext.resolveDeployment(facade).isBearerOnly()) {
|
||||
commenceUnauthorizedResponse(request, response);
|
||||
|
||||
+15
@@ -23,9 +23,11 @@ import org.keycloak.adapters.springsecurity.AdapterDeploymentContextFactoryBean;
|
||||
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationEntryPoint;
|
||||
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
|
||||
import org.keycloak.adapters.springsecurity.authentication.KeycloakLogoutHandler;
|
||||
import org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticatedActionsFilter;
|
||||
import org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter;
|
||||
import org.keycloak.adapters.springsecurity.filter.KeycloakCsrfRequestMatcher;
|
||||
import org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter;
|
||||
import org.keycloak.adapters.springsecurity.filter.KeycloakSecurityContextRequestFilter;
|
||||
import org.keycloak.adapters.springsecurity.management.HttpSessionManager;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -41,6 +43,7 @@ import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.security.web.authentication.logout.LogoutFilter;
|
||||
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
|
||||
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
||||
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
|
||||
|
||||
/**
|
||||
* Provides a convenient base class for creating a {@link WebSecurityConfigurer}
|
||||
@@ -91,6 +94,11 @@ public abstract class KeycloakWebSecurityConfigurerAdapter extends WebSecurityCo
|
||||
return new KeycloakPreAuthActionsFilter(httpSessionManager());
|
||||
}
|
||||
|
||||
@Bean
|
||||
protected KeycloakAuthenticatedActionsFilter keycloakAuthenticatedActionsFilter() {
|
||||
return new KeycloakAuthenticatedActionsFilter();
|
||||
}
|
||||
|
||||
protected KeycloakCsrfRequestMatcher keycloakCsrfRequestMatcher() {
|
||||
return new KeycloakCsrfRequestMatcher();
|
||||
}
|
||||
@@ -117,6 +125,8 @@ public abstract class KeycloakWebSecurityConfigurerAdapter extends WebSecurityCo
|
||||
.and()
|
||||
.addFilterBefore(keycloakPreAuthActionsFilter(), LogoutFilter.class)
|
||||
.addFilterBefore(keycloakAuthenticationProcessingFilter(), BasicAuthenticationFilter.class)
|
||||
.addFilterBefore(keycloakAuthenticatedActionsFilter(), BasicAuthenticationFilter.class)
|
||||
.addFilterAfter(keycloakSecurityContextRequestFilter(), SecurityContextHolderAwareRequestFilter.class)
|
||||
.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint())
|
||||
.and()
|
||||
.logout()
|
||||
@@ -124,4 +134,9 @@ public abstract class KeycloakWebSecurityConfigurerAdapter extends WebSecurityCo
|
||||
.logoutUrl("/sso/logout").permitAll()
|
||||
.logoutSuccessUrl("/");
|
||||
}
|
||||
|
||||
@Bean
|
||||
protected KeycloakSecurityContextRequestFilter keycloakSecurityContextRequestFilter() {
|
||||
return new KeycloakSecurityContextRequestFilter();
|
||||
}
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2017 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.springsecurity.filter;
|
||||
|
||||
import org.keycloak.KeycloakPrincipal;
|
||||
import org.keycloak.KeycloakSecurityContext;
|
||||
import org.keycloak.adapters.AdapterDeploymentContext;
|
||||
import org.keycloak.adapters.KeycloakDeployment;
|
||||
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
|
||||
import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.web.filter.GenericFilterBean;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public class KeycloakSecurityContextRequestFilter extends GenericFilterBean implements ApplicationContextAware {
|
||||
|
||||
private static final String FILTER_APPLIED = KeycloakSecurityContext.class.getPackage().getName() + ".token-refreshed";
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
private AdapterDeploymentContext deploymentContext;
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
|
||||
if (request.getAttribute(FILTER_APPLIED) != null) {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
|
||||
|
||||
KeycloakSecurityContext keycloakSecurityContext = getKeycloakPrincipal();
|
||||
|
||||
if (keycloakSecurityContext instanceof RefreshableKeycloakSecurityContext) {
|
||||
RefreshableKeycloakSecurityContext refreshableSecurityContext = (RefreshableKeycloakSecurityContext) keycloakSecurityContext;
|
||||
|
||||
if (refreshableSecurityContext.isActive()) {
|
||||
KeycloakDeployment deployment = resolveDeployment(request, response);
|
||||
|
||||
if (deployment.isAlwaysRefreshToken()) {
|
||||
if (refreshableSecurityContext.refreshExpiredToken(false)) {
|
||||
request.setAttribute(KeycloakSecurityContext.class.getName(), refreshableSecurityContext);
|
||||
} else {
|
||||
clearAuthenticationContext();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
clearAuthenticationContext();
|
||||
}
|
||||
}
|
||||
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initFilterBean() throws ServletException {
|
||||
deploymentContext = applicationContext.getBean(AdapterDeploymentContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
private KeycloakSecurityContext getKeycloakPrincipal() {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
|
||||
if (authentication != null) {
|
||||
Object principal = authentication.getPrincipal();
|
||||
|
||||
if (principal instanceof KeycloakPrincipal) {
|
||||
return KeycloakPrincipal.class.cast(principal).getKeycloakSecurityContext();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private KeycloakDeployment resolveDeployment(ServletRequest servletRequest, ServletResponse servletResponse) {
|
||||
return deploymentContext.resolveDeployment(new SimpleHttpFacade(HttpServletRequest.class.cast(servletRequest), HttpServletResponse.class.cast(servletResponse)));
|
||||
}
|
||||
|
||||
private void clearAuthenticationContext() {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
}
|
||||
+2
-7
@@ -39,14 +39,9 @@ public class HttpHeaderInspectingApiRequestMatcherTest {
|
||||
request = new MockHttpServletRequest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatches() throws Exception {
|
||||
assertTrue(apiRequestMatcher.matches(request));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchesBrowserRequest() throws Exception {
|
||||
request.addHeader(HttpHeaders.ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
|
||||
request.addHeader(HttpHeaders.ACCEPT, "application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
|
||||
assertFalse(apiRequestMatcher.matches(request));
|
||||
}
|
||||
|
||||
@@ -55,7 +50,7 @@ public class HttpHeaderInspectingApiRequestMatcherTest {
|
||||
request.addHeader(
|
||||
HttpHeaderInspectingApiRequestMatcher.X_REQUESTED_WITH_HEADER,
|
||||
HttpHeaderInspectingApiRequestMatcher.X_REQUESTED_WITH_HEADER_AJAX_VALUE);
|
||||
|
||||
assertTrue(apiRequestMatcher.matches(request));
|
||||
}
|
||||
|
||||
}
|
||||
+26
-12
@@ -17,24 +17,27 @@
|
||||
|
||||
package org.keycloak.adapters.springsecurity.authentication;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.apache.http.HttpHeaders;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import org.keycloak.adapters.AdapterDeploymentContext;
|
||||
import org.keycloak.adapters.KeycloakDeployment;
|
||||
import org.keycloak.adapters.spi.HttpFacade;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import org.mockito.Mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||
|
||||
/**
|
||||
* Keycloak authentication entry point tests.
|
||||
@@ -46,13 +49,16 @@ public class KeycloakAuthenticationEntryPointTest {
|
||||
private MockHttpServletResponse response;
|
||||
@Mock
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
|
||||
@Mock
|
||||
private AdapterDeploymentContext adapterDeploymentContext;
|
||||
|
||||
|
||||
@Mock
|
||||
private KeycloakDeployment keycloakDeployment;
|
||||
|
||||
@Mock
|
||||
private RequestMatcher requestMatcher;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
@@ -86,8 +92,8 @@ public class KeycloakAuthenticationEntryPointTest {
|
||||
public void testCommenceWithUnauthorizedWithAccept() throws Exception {
|
||||
request.addHeader(HttpHeaders.ACCEPT, "application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
|
||||
authenticationEntryPoint.commence(request, response, null);
|
||||
assertEquals(HttpStatus.UNAUTHORIZED.value(), response.getStatus());
|
||||
assertNotNull(response.getHeader(HttpHeaders.WWW_AUTHENTICATE));
|
||||
assertEquals(HttpStatus.FOUND.value(), response.getStatus());
|
||||
assertNull(response.getHeader(HttpHeaders.WWW_AUTHENTICATE));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -100,6 +106,14 @@ public class KeycloakAuthenticationEntryPointTest {
|
||||
assertEquals(logoutUri, response.getHeader("Location"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCommenceWithCustomRequestMatcher() throws Exception {
|
||||
new KeycloakAuthenticationEntryPoint(adapterDeploymentContext, requestMatcher)
|
||||
.commence(request, response, null);
|
||||
|
||||
verify(requestMatcher).matches(request);
|
||||
}
|
||||
|
||||
private void configureBrowserRequest() {
|
||||
request.addHeader(HttpHeaders.ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak Tomcat Integration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@@ -40,7 +40,7 @@
|
||||
<dependency>
|
||||
<groupId>org.wildfly.common</groupId>
|
||||
<artifactId>wildfly-common</artifactId>
|
||||
<version>1.2.0.Beta1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wildfly.security</groupId>
|
||||
|
||||
+20
-18
@@ -50,27 +50,29 @@ public class KeycloakConfigurationServletListener implements ServletContextListe
|
||||
ServletContext servletContext = sce.getServletContext();
|
||||
String configResolverClass = servletContext.getInitParameter("keycloak.config.resolver");
|
||||
KeycloakConfigResolver configResolver;
|
||||
AdapterDeploymentContext deploymentContext;
|
||||
AdapterDeploymentContext deploymentContext = (AdapterDeploymentContext) servletContext.getAttribute(AdapterDeploymentContext.class.getName());
|
||||
|
||||
if (configResolverClass != null) {
|
||||
try {
|
||||
configResolver = (KeycloakConfigResolver) servletContext.getClassLoader().loadClass(configResolverClass).newInstance();
|
||||
deploymentContext = new AdapterDeploymentContext(configResolver);
|
||||
} catch (Exception ex) {
|
||||
deploymentContext = new AdapterDeploymentContext(new KeycloakDeployment());
|
||||
}
|
||||
} else {
|
||||
InputStream is = getConfigInputStream(servletContext);
|
||||
|
||||
KeycloakDeployment deployment;
|
||||
|
||||
if (is == null) {
|
||||
deployment = new KeycloakDeployment();
|
||||
if (deploymentContext == null) {
|
||||
if (configResolverClass != null) {
|
||||
try {
|
||||
configResolver = (KeycloakConfigResolver) servletContext.getClassLoader().loadClass(configResolverClass).newInstance();
|
||||
deploymentContext = new AdapterDeploymentContext(configResolver);
|
||||
} catch (Exception ex) {
|
||||
deploymentContext = new AdapterDeploymentContext(new KeycloakDeployment());
|
||||
}
|
||||
} else {
|
||||
deployment = KeycloakDeploymentBuilder.build(is);
|
||||
}
|
||||
InputStream is = getConfigInputStream(servletContext);
|
||||
|
||||
deploymentContext = new AdapterDeploymentContext(deployment);
|
||||
KeycloakDeployment deployment;
|
||||
|
||||
if (is == null) {
|
||||
deployment = new KeycloakDeployment();
|
||||
} else {
|
||||
deployment = KeycloakDeploymentBuilder.build(is);
|
||||
}
|
||||
|
||||
deploymentContext = new AdapterDeploymentContext(deployment);
|
||||
}
|
||||
}
|
||||
|
||||
servletContext.setAttribute(ADAPTER_DEPLOYMENT_CONTEXT_ATTRIBUTE, deploymentContext);
|
||||
|
||||
+4
-1
@@ -30,8 +30,10 @@ import org.keycloak.KeycloakPrincipal;
|
||||
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
|
||||
import org.wildfly.security.auth.callback.AuthenticationCompleteCallback;
|
||||
import org.wildfly.security.auth.callback.EvidenceVerifyCallback;
|
||||
import org.wildfly.security.auth.callback.IdentityCredentialCallback;
|
||||
import org.wildfly.security.auth.callback.SecurityIdentityCallback;
|
||||
import org.wildfly.security.auth.server.SecurityIdentity;
|
||||
import org.wildfly.security.credential.BearerTokenCredential;
|
||||
import org.wildfly.security.evidence.Evidence;
|
||||
import org.wildfly.security.http.HttpAuthenticationException;
|
||||
|
||||
@@ -63,8 +65,9 @@ final class SecurityIdentityUtil {
|
||||
}
|
||||
|
||||
SecurityIdentityCallback securityIdentityCallback = new SecurityIdentityCallback();
|
||||
IdentityCredentialCallback credentialCallback = new IdentityCredentialCallback(new BearerTokenCredential(KeycloakPrincipal.class.cast(principal).getKeycloakSecurityContext().getTokenString()), true);
|
||||
|
||||
callbackHandler.handle(new Callback[]{AuthenticationCompleteCallback.SUCCEEDED, securityIdentityCallback});
|
||||
callbackHandler.handle(new Callback[]{credentialCallback, AuthenticationCompleteCallback.SUCCEEDED, securityIdentityCallback});
|
||||
|
||||
SecurityIdentity securityIdentity = securityIdentityCallback.getSecurityIdentity();
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak WildFly Integration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
+4
-8
@@ -71,11 +71,10 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP
|
||||
KeycloakAdapterConfigService service = KeycloakAdapterConfigService.getInstance();
|
||||
if (service.isSecureDeployment(deploymentUnit) && service.isDeploymentConfigured(deploymentUnit)) {
|
||||
addKeycloakAuthData(phaseContext, service);
|
||||
} else if (service.isElytronEnabled(deploymentUnit)) {
|
||||
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
|
||||
addConfigurationListener(warMetaData);
|
||||
}
|
||||
|
||||
addConfigurationListener(deploymentUnit);
|
||||
|
||||
// FYI, Undertow Extension will find deployments that have auth-method set to KEYCLOAK
|
||||
|
||||
// todo notsure if we need this
|
||||
@@ -104,10 +103,6 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP
|
||||
loginConfig.setAuthMethod("KEYCLOAK");
|
||||
loginConfig.setRealmName(service.getRealmName(deploymentUnit));
|
||||
KeycloakLogger.ROOT_LOGGER.deploymentSecured(deploymentUnit.getName());
|
||||
|
||||
if (service.isElytronEnabled(deploymentUnit)) {
|
||||
addConfigurationListener(warMetaData);
|
||||
}
|
||||
}
|
||||
|
||||
private void addJSONData(String json, WarMetaData warMetaData) {
|
||||
@@ -130,7 +125,8 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP
|
||||
webMetaData.setContextParams(contextParams);
|
||||
}
|
||||
|
||||
private void addConfigurationListener(WarMetaData warMetaData) {
|
||||
private void addConfigurationListener(DeploymentUnit deploymentUnit) {
|
||||
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
|
||||
if (warMetaData == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
+7
-5
@@ -276,11 +276,13 @@ public final class KeycloakAdapterConfigService {
|
||||
}
|
||||
|
||||
private void setJSONValues(ModelNode json, ModelNode values) {
|
||||
for (Property prop : new ArrayList<>(values.asPropertyList())) {
|
||||
String name = prop.getName();
|
||||
ModelNode value = prop.getValue();
|
||||
if (value.isDefined()) {
|
||||
json.get(name).set(value);
|
||||
synchronized (values) {
|
||||
for (Property prop : new ArrayList<>(values.asPropertyList())) {
|
||||
String name = prop.getName();
|
||||
ModelNode value = prop.getValue();
|
||||
if (value.isDefined()) {
|
||||
json.get(name).set(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -186,7 +186,12 @@ public class SharedAttributeDefinitons {
|
||||
.setDefaultValue(new ModelNode(false))
|
||||
.build();
|
||||
|
||||
|
||||
protected static final SimpleAttributeDefinition CONFIDENTIAL_PORT =
|
||||
new SimpleAttributeDefinitionBuilder("confidential-port", ModelType.INT, true)
|
||||
.setXmlName("confidential-port")
|
||||
.setAllowExpression(true)
|
||||
.setDefaultValue(new ModelNode(8443))
|
||||
.build();
|
||||
|
||||
|
||||
protected static final List<SimpleAttributeDefinition> ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
|
||||
@@ -196,6 +201,7 @@ public class SharedAttributeDefinitons {
|
||||
ATTRIBUTES.add(TRUSTSTORE);
|
||||
ATTRIBUTES.add(TRUSTSTORE_PASSWORD);
|
||||
ATTRIBUTES.add(SSL_REQUIRED);
|
||||
ATTRIBUTES.add(CONFIDENTIAL_PORT);
|
||||
ATTRIBUTES.add(ALLOW_ANY_HOSTNAME);
|
||||
ATTRIBUTES.add(DISABLE_TRUST_MANAGER);
|
||||
ATTRIBUTES.add(CONNECTION_POOL_SIZE);
|
||||
|
||||
+3
@@ -30,6 +30,7 @@ keycloak.realm.realm-public-key=Public key of the realm
|
||||
keycloak.realm.auth-server-url=Base URL of the Realm Auth Server
|
||||
keycloak.realm.disable-trust-manager=Adapter will not use a trust manager when making adapter HTTPS requests
|
||||
keycloak.realm.ssl-required=Specify if SSL is required (valid values are all, external and none)
|
||||
keycloak.realm.confidential-port=Specify the confidential port (SSL/TLS) used by the Realm Auth Server
|
||||
keycloak.realm.allow-any-hostname=SSL Setting
|
||||
keycloak.realm.truststore=Truststore used for adapter client HTTPS requests
|
||||
keycloak.realm.truststore-password=Password of the Truststore
|
||||
@@ -60,6 +61,7 @@ keycloak.secure-deployment.realm-public-key=Public key of the realm
|
||||
keycloak.secure-deployment.auth-server-url=Base URL of the Realm Auth Server
|
||||
keycloak.secure-deployment.disable-trust-manager=Adapter will not use a trust manager when making adapter HTTPS requests
|
||||
keycloak.secure-deployment.ssl-required=Specify if SSL is required (valid values are all, external and none)
|
||||
keycloak.secure-deployment.confidential-port=Specify the confidential port (SSL/TLS) used by the Realm Auth Server
|
||||
keycloak.secure-deployment.allow-any-hostname=SSL Setting
|
||||
keycloak.secure-deployment.truststore=Truststore used for adapter client HTTPS requests
|
||||
keycloak.secure-deployment.truststore-password=Password of the Truststore
|
||||
@@ -100,6 +102,7 @@ keycloak.secure-server.realm-public-key=Public key of the realm
|
||||
keycloak.secure-server.auth-server-url=Base URL of the Realm Auth Server
|
||||
keycloak.secure-server.disable-trust-manager=Adapter will not use a trust manager when making adapter HTTPS requests
|
||||
keycloak.secure-server.ssl-required=Specify if SSL is required (valid values are all, external and none)
|
||||
keycloak.secure-server.confidential-port=Specify the confidential port (SSL/TLS) used by the Realm Auth Server
|
||||
keycloak.secure-server.allow-any-hostname=SSL Setting
|
||||
keycloak.secure-server.truststore=Truststore used for adapter client HTTPS requests
|
||||
keycloak.secure-server.truststore-password=Password of the Truststore
|
||||
|
||||
+2
@@ -58,6 +58,7 @@
|
||||
<xs:element name="expose-token" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="disable-trust-manager" type="xs:boolean" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="ssl-required" type="xs:string" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="confidential-port" type="xs:integer" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="cors-allowed-methods" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="cors-exposed-headers" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="realm-public-key" type="xs:string" minOccurs="1" maxOccurs="1"/>
|
||||
@@ -100,6 +101,7 @@
|
||||
<xs:element name="connection-pool-size" type="xs:integer" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="expose-token" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="ssl-required" type="xs:string" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="confidential-port" type="xs:integer" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="realm-public-key" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="credential" type="credential-type" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="redirect-rewrite-rule" type="redirect-rewrite-rule-type" minOccurs="0" maxOccurs="1"/>
|
||||
|
||||
+1
@@ -51,6 +51,7 @@ public class SubsystemParsingTestCase extends AbstractSubsystemBaseTest {
|
||||
node.get("auth-url").set("http://localhost:8080/auth-server/rest/realms/demo/protocol/openid-connect/login");
|
||||
node.get("code-url").set("http://localhost:8080/auth-server/rest/realms/demo/protocol/openid-connect/access/codes");
|
||||
node.get("ssl-required").set("external");
|
||||
node.get("confidential-port").set(443);
|
||||
node.get("expose-token").set(true);
|
||||
|
||||
ModelNode jwtCredential = new ModelNode();
|
||||
|
||||
+4
@@ -22,6 +22,7 @@
|
||||
<truststore>truststore.jks</truststore>
|
||||
<truststore-password>secret</truststore-password>
|
||||
<ssl-required>EXTERNAL</ssl-required>
|
||||
<confidential-port>443</confidential-port>
|
||||
<allow-any-hostname>false</allow-any-hostname>
|
||||
<disable-trust-manager>true</disable-trust-manager>
|
||||
<connection-pool-size>20</connection-pool-size>
|
||||
@@ -56,6 +57,7 @@
|
||||
</realm-public-key>
|
||||
<auth-server-url>http://localhost:8080/auth</auth-server-url>
|
||||
<ssl-required>EXTERNAL</ssl-required>
|
||||
<confidential-port>443</confidential-port>
|
||||
<credential name="secret">0aa31d98-e0aa-404c-b6e0-e771dba1e798</credential>
|
||||
<redirect-rewrite-rule name="^/wsmaster/api/(.*)$">api/$1/</redirect-rewrite-rule>
|
||||
</secure-deployment>
|
||||
@@ -84,5 +86,7 @@
|
||||
<realm>jboss-infra</realm>
|
||||
<resource>wildfly-console</resource>
|
||||
<public-client>true</public-client>
|
||||
<ssl-required>EXTERNAL</ssl-required>
|
||||
<confidential-port>443</confidential-port>
|
||||
</secure-server>
|
||||
</subsystem>
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak Adapters</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-saml-eap-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak SAML EAP Integration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-saml-eap-integration-pom</artifactId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
+3
-2
@@ -16,7 +16,6 @@
|
||||
*/
|
||||
package org.keycloak.subsystem.saml.as7;
|
||||
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
|
||||
*/
|
||||
@@ -46,6 +45,8 @@ public class Constants {
|
||||
static final String SIGN_REQUEST = "signRequest";
|
||||
static final String VALIDATE_RESPONSE_SIGNATURE = "validateResponseSignature";
|
||||
static final String VALIDATE_ASSERTION_SIGNATURE = "validateAssertionSignature";
|
||||
static final String ASSERTION_CONSUMER_SERVICE_URL = "assertionConsumerServiceUrl";
|
||||
|
||||
static final String REQUEST_BINDING = "requestBinding";
|
||||
static final String BINDING_URL = "bindingUrl";
|
||||
static final String VALIDATE_REQUEST_SIGNATURE = "validateRequestSignature";
|
||||
@@ -69,7 +70,6 @@ public class Constants {
|
||||
static final String SIGNATURES_REQUIRED = "signaturesRequired";
|
||||
}
|
||||
|
||||
|
||||
static class XML {
|
||||
static final String SECURE_DEPLOYMENT = "secure-deployment";
|
||||
static final String SERVICE_PROVIDER = "SP";
|
||||
@@ -122,5 +122,6 @@ public class Constants {
|
||||
static final String ALIAS = "alias";
|
||||
static final String FILE = "file";
|
||||
static final String SIGNATURES_REQUIRED = "signaturesRequired";
|
||||
static final String ASSERTION_CONSUMER_SERVICE_URL = "assertionConsumerServiceUrl";
|
||||
}
|
||||
}
|
||||
+6
-1
@@ -56,8 +56,13 @@ abstract class SingleSignOnDefinition {
|
||||
new SimpleAttributeDefinitionBuilder(Constants.Model.BINDING_URL, ModelType.STRING, true)
|
||||
.setXmlName(Constants.XML.BINDING_URL)
|
||||
.build();
|
||||
|
||||
static final SimpleAttributeDefinition ASSERTION_CONSUMER_SERVICE_URL =
|
||||
new SimpleAttributeDefinitionBuilder(Constants.Model.ASSERTION_CONSUMER_SERVICE_URL, ModelType.STRING, true)
|
||||
.setXmlName(Constants.XML.ASSERTION_CONSUMER_SERVICE_URL)
|
||||
.build();
|
||||
|
||||
static final SimpleAttributeDefinition[] ATTRIBUTES = {SIGN_REQUEST, VALIDATE_RESPONSE_SIGNATURE, VALIDATE_ASSERTION_SIGNATURE, REQUEST_BINDING, RESPONSE_BINDING, BINDING_URL};
|
||||
static final SimpleAttributeDefinition[] ATTRIBUTES = {SIGN_REQUEST, VALIDATE_RESPONSE_SIGNATURE, VALIDATE_ASSERTION_SIGNATURE, REQUEST_BINDING, RESPONSE_BINDING, BINDING_URL, ASSERTION_CONSUMER_SERVICE_URL};
|
||||
|
||||
static final HashMap<String, SimpleAttributeDefinition> ATTRIBUTE_MAP = new HashMap<>();
|
||||
|
||||
|
||||
+1
@@ -71,6 +71,7 @@ keycloak-saml.IDP.SingleSignOnService.validateAssertionSignature=Validate an SSO
|
||||
keycloak-saml.IDP.SingleSignOnService.requestBinding=HTTP method to use for requests
|
||||
keycloak-saml.IDP.SingleSignOnService.responseBinding=HTTP method to use for responses
|
||||
keycloak-saml.IDP.SingleSignOnService.bindingUrl=SSO endpoint URL
|
||||
keycloak-saml.IDP.SingleSignOnService.assertionConsumerServiceUrl=Endpoint of Assertion Consumer Service at SP
|
||||
keycloak-saml.IDP.SingleLogoutService=Single logout configuration
|
||||
keycloak-saml.IDP.SingleLogoutService.validateRequestSignature=Validate a SingleLogoutService request signature
|
||||
keycloak-saml.IDP.SingleLogoutService.validateResponseSignature=Validate a SingleLogoutService response signature
|
||||
|
||||
+5
@@ -152,6 +152,11 @@
|
||||
<xs:documentation>SSO endpoint URL</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="assertionConsumerServiceUrl" type="xs:string" use="optional">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Endpoint of Assertion Consumer Service at SP</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="single-logout-type">
|
||||
<xs:attribute name="validateRequestSignature" type="xs:boolean" use="optional">
|
||||
|
||||
+2
-1
@@ -44,7 +44,8 @@
|
||||
validateResponseSignature="true"
|
||||
validateAssertionSignature="true"
|
||||
requestBinding="POST"
|
||||
bindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"/>
|
||||
bindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"
|
||||
assertionConsumerServiceUrl="acsUrl"/>
|
||||
<SingleLogoutService
|
||||
validateRequestSignature="true"
|
||||
validateResponseSignature="true"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -56,6 +56,8 @@ import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.apache.http.client.params.ClientPNames;
|
||||
import org.apache.http.client.params.CookiePolicy;
|
||||
|
||||
/**
|
||||
* Abstraction for creating HttpClients. Allows SSL configuration.
|
||||
@@ -288,6 +290,7 @@ public class HttpClientBuilder {
|
||||
cm = new SingleClientConnManager(registry);
|
||||
}
|
||||
BasicHttpParams params = new BasicHttpParams();
|
||||
params.setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
|
||||
|
||||
if (proxyHost != null) {
|
||||
params.setParameter(ConnRoutePNames.DEFAULT_PROXY, proxyHost);
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak SAML Jetty Integration</name>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak SAML Client Adapter Modules</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak SAML Tomcat Integration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+3
-2
@@ -103,9 +103,10 @@ class ElytronHttpFacade implements HttpFacade {
|
||||
|
||||
if (anonymousAuthorizationCallback.isAuthorized()) {
|
||||
callbackHandler.handle(new Callback[]{AuthenticationCompleteCallback.SUCCEEDED, new SecurityIdentityCallback()});
|
||||
request.authenticationComplete(response -> response.forward(getRequest().getRelativePath()));
|
||||
} else {
|
||||
request.noAuthenticationInProgress(response -> response.forward(getRequest().getRelativePath()));
|
||||
}
|
||||
|
||||
request.authenticationComplete(response -> response.forward(getRequest().getRelativePath()));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unexpected error processing callbacks during logout.", e);
|
||||
}
|
||||
|
||||
+35
-31
@@ -49,46 +49,50 @@ public class KeycloakConfigurationServletListener implements ServletContextListe
|
||||
|
||||
protected static Logger log = Logger.getLogger(KeycloakConfigurationServletListener.class);
|
||||
|
||||
static final String ADAPTER_DEPLOYMENT_CONTEXT_ATTRIBUTE = AdapterDeploymentContext.class.getName() + ".elytron";
|
||||
static final String ADAPTER_DEPLOYMENT_CONTEXT_ATTRIBUTE = SamlDeploymentContext.class.getName() + ".elytron";
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
ServletContext servletContext = sce.getServletContext();
|
||||
String configResolverClass = servletContext.getInitParameter("keycloak.config.resolver");
|
||||
SamlDeploymentContext deploymentContext = null;
|
||||
if (configResolverClass != null) {
|
||||
try {
|
||||
throw new RuntimeException("Not implemented yet");
|
||||
//configResolver = (SamlConfigResolver) deploymentInfo.getClassLoader().loadClass(configResolverClass).newInstance();
|
||||
//deploymentContext = new AdapterDeploymentContext(configResolver);
|
||||
//log.info("Using " + configResolverClass + " to resolve Keycloak configuration on a per-request basis.");
|
||||
} catch (Exception ex) {
|
||||
log.warn("The specified resolver " + configResolverClass + " could NOT be loaded. Keycloak is unconfigured and will deny all requests. Reason: " + ex.getMessage());
|
||||
//deploymentContext = new AdapterDeploymentContext(new KeycloakDeployment());
|
||||
}
|
||||
} else {
|
||||
InputStream is = getConfigInputStream(servletContext);
|
||||
final SamlDeployment deployment;
|
||||
if (is == null) {
|
||||
log.warn("No adapter configuration. Keycloak is unconfigured and will deny all requests.");
|
||||
deployment = new DefaultSamlDeployment();
|
||||
} else {
|
||||
SamlDeploymentContext deploymentContext = (SamlDeploymentContext) servletContext.getAttribute(SamlDeployment.class.getName());
|
||||
|
||||
if (deploymentContext == null) {
|
||||
if (configResolverClass != null) {
|
||||
try {
|
||||
ResourceLoader loader = new ResourceLoader() {
|
||||
@Override
|
||||
public InputStream getResourceAsStream(String resource) {
|
||||
return servletContext.getResourceAsStream(resource);
|
||||
}
|
||||
};
|
||||
deployment = new DeploymentBuilder().build(is, loader);
|
||||
} catch (ParsingException e) {
|
||||
throw new RuntimeException(e);
|
||||
throw new RuntimeException("Not implemented yet");
|
||||
//configResolver = (SamlConfigResolver) deploymentInfo.getClassLoader().loadClass(configResolverClass).newInstance();
|
||||
//deploymentContext = new AdapterDeploymentContext(configResolver);
|
||||
//log.info("Using " + configResolverClass + " to resolve Keycloak configuration on a per-request basis.");
|
||||
} catch (Exception ex) {
|
||||
log.warn("The specified resolver " + configResolverClass + " could NOT be loaded. Keycloak is unconfigured and will deny all requests. Reason: " + ex.getMessage());
|
||||
//deploymentContext = new AdapterDeploymentContext(new KeycloakDeployment());
|
||||
}
|
||||
} else {
|
||||
InputStream is = getConfigInputStream(servletContext);
|
||||
final SamlDeployment deployment;
|
||||
if (is == null) {
|
||||
log.warn("No adapter configuration. Keycloak is unconfigured and will deny all requests.");
|
||||
deployment = new DefaultSamlDeployment();
|
||||
} else {
|
||||
try {
|
||||
ResourceLoader loader = new ResourceLoader() {
|
||||
@Override
|
||||
public InputStream getResourceAsStream(String resource) {
|
||||
return servletContext.getResourceAsStream(resource);
|
||||
}
|
||||
};
|
||||
deployment = new DeploymentBuilder().build(is, loader);
|
||||
} catch (ParsingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
deploymentContext = new SamlDeploymentContext(deployment);
|
||||
log.debug("Keycloak is using a per-deployment configuration.");
|
||||
}
|
||||
deploymentContext = new SamlDeploymentContext(deployment);
|
||||
servletContext.setAttribute(ADAPTER_DEPLOYMENT_CONTEXT_ATTRIBUTE, deploymentContext);
|
||||
log.debug("Keycloak is using a per-deployment configuration.");
|
||||
}
|
||||
|
||||
servletContext.setAttribute(ADAPTER_DEPLOYMENT_CONTEXT_ATTRIBUTE, deploymentContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak SAML Wildfly Integration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<version>3.4.0.CR1-SNAPSHOT</version>
|
||||
<version>3.4.2.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -101,5 +101,10 @@
|
||||
<artifactId>keycloak-saml-wildfly-adapter</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-saml-wildfly-elytron-adapter</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
+6
@@ -46,6 +46,9 @@ public class Constants {
|
||||
static final String SIGN_REQUEST = "signRequest";
|
||||
static final String VALIDATE_RESPONSE_SIGNATURE = "validateResponseSignature";
|
||||
static final String VALIDATE_ASSERTION_SIGNATURE = "validateAssertionSignature";
|
||||
static final String ASSERTION_CONSUMER_SERVICE_URL = "assertionConsumerServiceUrl";
|
||||
|
||||
|
||||
static final String REQUEST_BINDING = "requestBinding";
|
||||
static final String BINDING_URL = "bindingUrl";
|
||||
static final String VALIDATE_REQUEST_SIGNATURE = "validateRequestSignature";
|
||||
@@ -122,5 +125,8 @@ public class Constants {
|
||||
static final String ALIAS = "alias";
|
||||
static final String FILE = "file";
|
||||
static final String SIGNATURES_REQUIRED = "signaturesRequired";
|
||||
static final String ASSERTION_CONSUMER_SERVICE_URL = "assertionConsumerServiceUrl";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+30
@@ -25,10 +25,12 @@ import org.jboss.as.web.common.WarMetaData;
|
||||
import org.jboss.dmr.ModelNode;
|
||||
import org.jboss.metadata.javaee.spec.ParamValueMetaData;
|
||||
import org.jboss.metadata.web.jboss.JBossWebMetaData;
|
||||
import org.jboss.metadata.web.spec.ListenerMetaData;
|
||||
import org.jboss.metadata.web.spec.LoginConfigMetaData;
|
||||
import org.jboss.staxmapper.FormattingXMLStreamWriter;
|
||||
import org.jboss.staxmapper.XMLExtendedStreamWriter;
|
||||
import org.keycloak.adapters.saml.AdapterConstants;
|
||||
import org.keycloak.adapters.saml.elytron.KeycloakConfigurationServletListener;
|
||||
import org.keycloak.subsystem.adapter.saml.extension.logging.KeycloakLogger;
|
||||
|
||||
import javax.xml.stream.XMLOutputFactory;
|
||||
@@ -52,6 +54,8 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP
|
||||
if (Configuration.INSTANCE.getSecureDeployment(deploymentUnit) != null) {
|
||||
addKeycloakSamlAuthData(phaseContext);
|
||||
}
|
||||
|
||||
addConfigurationListener(deploymentUnit);
|
||||
}
|
||||
|
||||
private void addKeycloakSamlAuthData(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
|
||||
@@ -124,4 +128,30 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP
|
||||
public void undeploy(DeploymentUnit du) {
|
||||
|
||||
}
|
||||
|
||||
private void addConfigurationListener(DeploymentUnit deploymentUnit) {
|
||||
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
|
||||
if (warMetaData == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
JBossWebMetaData webMetaData = warMetaData.getMergedJBossWebMetaData();
|
||||
if (webMetaData == null) {
|
||||
webMetaData = new JBossWebMetaData();
|
||||
warMetaData.setMergedJBossWebMetaData(webMetaData);
|
||||
}
|
||||
|
||||
LoginConfigMetaData loginConfig = webMetaData.getLoginConfig();
|
||||
if (loginConfig == null) {
|
||||
return;
|
||||
}
|
||||
if (!loginConfig.getAuthMethod().equals("KEYCLOAK-SAML")) {
|
||||
return;
|
||||
}
|
||||
ListenerMetaData listenerMetaData = new ListenerMetaData();
|
||||
|
||||
listenerMetaData.setListenerClass(KeycloakConfigurationServletListener.class.getName());
|
||||
|
||||
webMetaData.getListeners().add(listenerMetaData);
|
||||
}
|
||||
}
|
||||
Loaded 100 of 1600 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user