Skip to content

Commit a8ba285

Browse files
author
Alistair Doswald
committed
Merge branch 'ws-fed11-3.4.0.Final'
Merge local development for 3.4.0.Final into master
2 parents 77e08af + bb4a50f commit a8ba285

36 files changed

Lines changed: 462 additions & 372 deletions

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# WS-Federation for keycloak
22

3-
* Currently working on 2.5.5.Final
3+
* Currently working on 3.4.0.Final
44

55
## Install
66

@@ -14,7 +14,7 @@ install -d -v -m755 /opt/keycloak/modules/system/layers/wsfed -o keycloak -g key
1414
install -d -v -m755 /opt/keycloak/modules/system/layers/wsfed/com/quest/keycloak-wsfed/main/ -o keycloak -g keycloak
1515

1616
#Install jar
17-
install -v -m0755 -o keycloak -g keycloak -D target/keycloak-wsfed-2.5.5.Final.jar /opt/keycloak/modules/system/layers/wsfed/com/quest/keycloak-wsfed/main/
17+
install -v -m0755 -o keycloak -g keycloak -D target/keycloak-wsfed-3.4.0.Final.jar /opt/keycloak/modules/system/layers/wsfed/com/quest/keycloak-wsfed/main/
1818

1919
#Install module file
2020
install -v -m0755 -o keycloak -g keycloak -D module.xml /opt/keycloak/modules/system/layers/wsfed/com/quest/keycloak-wsfed/main/

module.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<module xmlns="urn:jboss:module:1.1" name="com.quest.keycloak-wsfed">
44

55
<resources>
6-
<resource-root path="keycloak-wsfed-2.5.5.Final.jar"/>
6+
<resource-root path="keycloak-wsfed-3.4.0.Final.jar"/>
77
</resources>
88

99
<dependencies>

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<parent>
1818
<artifactId>keycloak-parent</artifactId>
1919
<groupId>org.keycloak</groupId>
20-
<version>2.5.5.Final</version>
20+
<version>3.4.0.Final</version>
2121
</parent>
2222

2323
<groupId>com.quest</groupId>

src/main/java/com/quest/keycloak/broker/wsfed/SAML11RequestedToken.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public Response validate(PublicKey key, WSFedIdentityProviderConfig config, Even
9494
if(!isSignatureValid(extractSamlDocument(doc).getDocumentElement(), key)) {
9595
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
9696
event.error(Errors.INVALID_SIGNATURE);
97-
return ErrorPage.error(session, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
97+
return ErrorPage.error(session, null, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
9898
}
9999

100100
XMLGregorianCalendar notBefore = samlAssertion.getConditions().getNotBefore();
@@ -104,20 +104,20 @@ public Response validate(PublicKey key, WSFedIdentityProviderConfig config, Even
104104
if(AssertionUtil.hasExpired(samlAssertion)) {
105105
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
106106
event.error(Errors.EXPIRED_CODE);
107-
return ErrorPage.error(session, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
107+
return ErrorPage.error(session, null, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
108108
}
109109

110110
if(!isValidAudienceRestriction(URI.create(config.getWsFedRealm()))) {
111111
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
112112
event.error(Errors.INVALID_SAML_RESPONSE);
113-
return ErrorPage.error(session, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
113+
return ErrorPage.error(session, null, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
114114
}
115115

116116
} catch (Exception e) {
117117
logger.error("Unable to validate signature", e);
118118
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
119119
event.error(Errors.INVALID_SAML_RESPONSE);
120-
return ErrorPage.error(session, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
120+
return ErrorPage.error(session, null, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
121121
}
122122

123123
return null;

src/main/java/com/quest/keycloak/broker/wsfed/SAML2RequestedToken.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public Response validate(PublicKey key, WSFedIdentityProviderConfig config, Even
8686
if(!AssertionUtil.isSignatureValid(extractSamlDocument(doc).getDocumentElement(), key)) {
8787
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
8888
event.error(Errors.INVALID_SIGNATURE);
89-
return ErrorPage.error(session, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
89+
return ErrorPage.error(session, null, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
9090
}
9191

9292
XMLGregorianCalendar notBefore = saml2Assertion.getConditions().getNotBefore();
@@ -96,20 +96,20 @@ public Response validate(PublicKey key, WSFedIdentityProviderConfig config, Even
9696
if(AssertionUtil.hasExpired(saml2Assertion)) {
9797
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
9898
event.error(Errors.EXPIRED_CODE);
99-
return ErrorPage.error(session, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
99+
return ErrorPage.error(session, null, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
100100
}
101101

102102
if(!isValidAudienceRestriction(URI.create(config.getWsFedRealm()))) {
103103
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
104104
event.error(Errors.INVALID_SAML_RESPONSE);
105-
return ErrorPage.error(session, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
105+
return ErrorPage.error(session, null, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
106106
}
107107

108108
} catch (Exception e) {
109109
logger.error("Unable to validate signature", e);
110110
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
111111
event.error(Errors.INVALID_SAML_RESPONSE);
112-
return ErrorPage.error(session, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
112+
return ErrorPage.error(session, null, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
113113
}
114114

115115
return null;

src/main/java/com/quest/keycloak/broker/wsfed/WSFedEndpoint.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package com.quest.keycloak.broker.wsfed;
1818

19-
import static org.keycloak.models.ClientSessionModel.Action.AUTHENTICATE;
2019

2120
import java.io.ByteArrayInputStream;
2221
import java.io.IOException;
@@ -68,6 +67,8 @@
6867
import org.keycloak.services.managers.AuthenticationManager;
6968
import org.keycloak.services.managers.ClientSessionCode;
7069
import org.keycloak.services.messages.Messages;
70+
import org.keycloak.sessions.AuthenticationSessionModel;
71+
import org.keycloak.sessions.CommonClientSessionModel;
7172
import org.picketlink.identity.federation.core.wstrust.wrappers.Lifetime;
7273
import org.picketlink.identity.federation.core.wstrust.wrappers.RequestSecurityTokenResponse;
7374
import org.picketlink.identity.federation.core.wstrust.wrappers.RequestSecurityTokenResponseCollection;
@@ -161,7 +162,7 @@ protected Response execute(String wsfedAction, String wsfedResult, String contex
161162
if (wsfedAction.compareTo(WSFedConstants.WSFED_SIGNOUT_CLEANUP_ACTION) == 0)
162163
return handleSignoutResponse(context);
163164

164-
return ErrorPage.error(session, Messages.INVALID_REQUEST);
165+
return ErrorPage.error(session, null, Messages.INVALID_REQUEST);
165166
}
166167

167168
protected Response handleSignoutRequest(String context) {
@@ -171,7 +172,7 @@ protected Response handleSignoutRequest(String context) {
171172
logger.error("no valid user session");
172173
event.event(EventType.LOGOUT);
173174
event.error(Errors.USER_SESSION_NOT_FOUND);
174-
return ErrorPage.error(session, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR);
175+
return ErrorPage.error(session, null, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR);
175176
}
176177

177178
List<UserSessionModel> userSessions = session.sessions().getUserSessionByBrokerUserId(realm, result.getSession().getBrokerUserId());
@@ -205,7 +206,7 @@ protected Response handleSignoutResponse(String context) {
205206
logger.error("no valid user session");
206207
event.event(EventType.LOGOUT);
207208
event.error(Errors.USER_SESSION_NOT_FOUND);
208-
return ErrorPage.error(session, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR);
209+
return ErrorPage.error(session, null, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR);
209210
}
210211

211212
UserSessionModel userSession = result.getSession();
@@ -214,7 +215,7 @@ protected Response handleSignoutResponse(String context) {
214215
logger.error("usersession in different state");
215216
event.event(EventType.LOGOUT);
216217
event.error(Errors.USER_SESSION_NOT_FOUND);
217-
return ErrorPage.error(session, Messages.SESSION_NOT_ACTIVE);
218+
return ErrorPage.error(session, null, Messages.SESSION_NOT_ACTIVE);
218219
}
219220

220221
return AuthenticationManager.finishBrowserLogout(session, realm, userSession, uriInfo, clientConnection, headers);
@@ -244,11 +245,12 @@ protected Response handleLoginResponse(String wsfedResponse, RequestedToken toke
244245
Map<String, String> map = getContextParameters(decodedContext);
245246
String redirectUri = URLDecoder.decode(map.get("redirectUri"), StandardCharsets.UTF_8.name());
246247
if (decodedContext.contains("&code=")) {
247-
ClientSessionCode clientCode = ClientSessionCode.parse(map.get("code"), this.session, this.session.getContext().getRealm());
248-
if (clientCode != null && clientCode.isValid(AUTHENTICATE.name(), ClientSessionCode.ActionType.LOGIN)) {
248+
//TODO not sure that we indeed have a AuthenticationSessionModel here. It could potentially be a AuthenticatedClientSessionModel
249+
ClientSessionCode.ParseResult<AuthenticationSessionModel> clientCode = ClientSessionCode.parseResult(map.get("code"), this.session, this.session.getContext().getRealm(), event, AuthenticationSessionModel.class);
250+
if (clientCode != null && clientCode.getCode().isValid(CommonClientSessionModel.Action.AUTHENTICATE.name(), ClientSessionCode.ActionType.LOGIN)) {
249251
String ACTIVE_CODE = "active_code"; // duplicating because ClientSessionCode.ACTIVE_CODE is private
250252
// restore ACTIVE_CODE note because it must have been removed by parse() if code==activeCode
251-
clientCode.getClientSession().setNote(ACTIVE_CODE, map.get("code"));
253+
clientCode.getClientSession().setClientNote(ACTIVE_CODE, map.get("code"));
252254

253255
// set authorization code and redirectUri
254256
identity.setCode(map.get("code"));
@@ -314,7 +316,7 @@ protected Response handleWsFedResponse(String wsfedResponse, String context) {
314316
if (hasExpired(rstr)) {
315317
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
316318
event.error(Errors.EXPIRED_CODE);
317-
return ErrorPage.error(session, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
319+
return ErrorPage.error(session, null, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
318320
}
319321

320322
//TODO: Do we need to handle if the IDP sent back more than one token?
@@ -348,7 +350,7 @@ else if (rstr.getTokenType().compareTo(URI.create("urn:ietf:params:oauth:token-t
348350
logger.error("assertion parsing failed", e);
349351
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
350352
event.error(Errors.INVALID_SAML_RESPONSE);
351-
return ErrorPage.error(session, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
353+
return ErrorPage.error(session, null, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
352354
}
353355
}
354356

src/main/java/com/quest/keycloak/broker/wsfed/WSFedIdentityProvider.java

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,12 @@
2929
import org.jboss.logging.Logger;
3030
import org.keycloak.broker.provider.AbstractIdentityProvider;
3131
import org.keycloak.broker.provider.AuthenticationRequest;
32-
import org.keycloak.broker.provider.BrokeredIdentityContext;
3332
import org.keycloak.broker.provider.IdentityBrokerException;
3433
import org.keycloak.broker.provider.IdentityProviderDataMarshaller;
3534
import org.keycloak.broker.provider.util.SimpleHttp;
3635
import org.keycloak.common.util.PemUtils;
3736
import org.keycloak.common.util.StreamUtil;
3837
import org.keycloak.events.EventBuilder;
39-
import org.keycloak.models.ClientSessionModel;
4038
import org.keycloak.models.FederatedIdentityModel;
4139
import org.keycloak.models.KeyManager;
4240
import org.keycloak.models.KeycloakSession;
@@ -62,7 +60,7 @@ public Response performLogin(AuthenticationRequest request) {
6260
String destinationUrl = getConfig().getSingleSignOnServiceUrl();
6361
String reply = request.getRedirectUri();
6462
String wsFedRealm = getConfig().getWsFedRealm();
65-
String context = request.getState();
63+
String context = request.getState().getEncodedState();
6664
// not sure how valuable this null-check is in real life, but it breaks in the tests without it.
6765
if( request.getHttpRequest() != null && request.getHttpRequest().getUri() != null ) {
6866
MultivaluedMap<String, String> params = request.getHttpRequest().getUri().getQueryParameters();
@@ -89,10 +87,6 @@ public Response retrieveToken(KeycloakSession session, FederatedIdentityModel id
8987
return Response.ok(identity.getToken()).build();
9088
}
9189

92-
@Override
93-
public void attachUserSession(UserSessionModel userSession, ClientSessionModel clientSession, BrokeredIdentityContext context) {
94-
}
95-
9690
@Override
9791
public Response keycloakInitiatedBrowserLogout(KeycloakSession session, UserSessionModel userSession, UriInfo uriInfo, RealmModel realm) {
9892
String singleLogoutServiceUrl = getConfig().getSingleLogoutServiceUrl();
@@ -123,7 +117,7 @@ public void backchannelLogout(KeycloakSession session, UserSessionModel userSess
123117
if (singleLogoutServiceUrl == null || singleLogoutServiceUrl.trim().equals("") || !getConfig().isBackchannelSupported()) return;
124118

125119
try {
126-
int status = SimpleHttp.doGet(singleLogoutServiceUrl)
120+
int status = SimpleHttp.doGet(singleLogoutServiceUrl, session)
127121
.param(WSFedConstants.WSFED_ACTION, WSFedConstants.WSFED_SIGNOUT_ACTION)
128122
.param(WSFedConstants.WSFED_REALM, getConfig().getWsFedRealm()).asStatus();
129123

0 commit comments

Comments
 (0)