Skip to content

Commit

Permalink
Merge branch 'ws-fed11-3.4.0.Final'
Browse files Browse the repository at this point in the history
Merge local development for 3.4.0.Final into master
  • Loading branch information
Alistair Doswald committed Dec 12, 2017
2 parents 77e08af + bb4a50f commit a8ba285
Show file tree
Hide file tree
Showing 36 changed files with 462 additions and 372 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# WS-Federation for keycloak

* Currently working on 2.5.5.Final
* Currently working on 3.4.0.Final

## Install

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

#Install jar
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/
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/

#Install module file
install -v -m0755 -o keycloak -g keycloak -D module.xml /opt/keycloak/modules/system/layers/wsfed/com/quest/keycloak-wsfed/main/
Expand Down
2 changes: 1 addition & 1 deletion module.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<module xmlns="urn:jboss:module:1.1" name="com.quest.keycloak-wsfed">

<resources>
<resource-root path="keycloak-wsfed-2.5.5.Final.jar"/>
<resource-root path="keycloak-wsfed-3.4.0.Final.jar"/>
</resources>

<dependencies>
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>2.5.5.Final</version>
<version>3.4.0.Final</version>
</parent>

<groupId>com.quest</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public Response validate(PublicKey key, WSFedIdentityProviderConfig config, Even
if(!isSignatureValid(extractSamlDocument(doc).getDocumentElement(), key)) {
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
event.error(Errors.INVALID_SIGNATURE);
return ErrorPage.error(session, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
return ErrorPage.error(session, null, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
}

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

if(!isValidAudienceRestriction(URI.create(config.getWsFedRealm()))) {
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
event.error(Errors.INVALID_SAML_RESPONSE);
return ErrorPage.error(session, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
return ErrorPage.error(session, null, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
}

} catch (Exception e) {
logger.error("Unable to validate signature", e);
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
event.error(Errors.INVALID_SAML_RESPONSE);
return ErrorPage.error(session, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
return ErrorPage.error(session, null, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
}

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public Response validate(PublicKey key, WSFedIdentityProviderConfig config, Even
if(!AssertionUtil.isSignatureValid(extractSamlDocument(doc).getDocumentElement(), key)) {
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
event.error(Errors.INVALID_SIGNATURE);
return ErrorPage.error(session, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
return ErrorPage.error(session, null, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
}

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

if(!isValidAudienceRestriction(URI.create(config.getWsFedRealm()))) {
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
event.error(Errors.INVALID_SAML_RESPONSE);
return ErrorPage.error(session, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
return ErrorPage.error(session, null, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
}

} catch (Exception e) {
logger.error("Unable to validate signature", e);
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
event.error(Errors.INVALID_SAML_RESPONSE);
return ErrorPage.error(session, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
return ErrorPage.error(session, null, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
}

return null;
Expand Down
22 changes: 12 additions & 10 deletions src/main/java/com/quest/keycloak/broker/wsfed/WSFedEndpoint.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

package com.quest.keycloak.broker.wsfed;

import static org.keycloak.models.ClientSessionModel.Action.AUTHENTICATE;

import java.io.ByteArrayInputStream;
import java.io.IOException;
Expand Down Expand Up @@ -68,6 +67,8 @@
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.ClientSessionCode;
import org.keycloak.services.messages.Messages;
import org.keycloak.sessions.AuthenticationSessionModel;
import org.keycloak.sessions.CommonClientSessionModel;
import org.picketlink.identity.federation.core.wstrust.wrappers.Lifetime;
import org.picketlink.identity.federation.core.wstrust.wrappers.RequestSecurityTokenResponse;
import org.picketlink.identity.federation.core.wstrust.wrappers.RequestSecurityTokenResponseCollection;
Expand Down Expand Up @@ -161,7 +162,7 @@ protected Response execute(String wsfedAction, String wsfedResult, String contex
if (wsfedAction.compareTo(WSFedConstants.WSFED_SIGNOUT_CLEANUP_ACTION) == 0)
return handleSignoutResponse(context);

return ErrorPage.error(session, Messages.INVALID_REQUEST);
return ErrorPage.error(session, null, Messages.INVALID_REQUEST);
}

protected Response handleSignoutRequest(String context) {
Expand All @@ -171,7 +172,7 @@ protected Response handleSignoutRequest(String context) {
logger.error("no valid user session");
event.event(EventType.LOGOUT);
event.error(Errors.USER_SESSION_NOT_FOUND);
return ErrorPage.error(session, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR);
return ErrorPage.error(session, null, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR);
}

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

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

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

// set authorization code and redirectUri
identity.setCode(map.get("code"));
Expand Down Expand Up @@ -314,7 +316,7 @@ protected Response handleWsFedResponse(String wsfedResponse, String context) {
if (hasExpired(rstr)) {
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
event.error(Errors.EXPIRED_CODE);
return ErrorPage.error(session, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
return ErrorPage.error(session, null, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
}

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,12 @@
import org.jboss.logging.Logger;
import org.keycloak.broker.provider.AbstractIdentityProvider;
import org.keycloak.broker.provider.AuthenticationRequest;
import org.keycloak.broker.provider.BrokeredIdentityContext;
import org.keycloak.broker.provider.IdentityBrokerException;
import org.keycloak.broker.provider.IdentityProviderDataMarshaller;
import org.keycloak.broker.provider.util.SimpleHttp;
import org.keycloak.common.util.PemUtils;
import org.keycloak.common.util.StreamUtil;
import org.keycloak.events.EventBuilder;
import org.keycloak.models.ClientSessionModel;
import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.KeyManager;
import org.keycloak.models.KeycloakSession;
Expand All @@ -62,7 +60,7 @@ public Response performLogin(AuthenticationRequest request) {
String destinationUrl = getConfig().getSingleSignOnServiceUrl();
String reply = request.getRedirectUri();
String wsFedRealm = getConfig().getWsFedRealm();
String context = request.getState();
String context = request.getState().getEncodedState();
// not sure how valuable this null-check is in real life, but it breaks in the tests without it.
if( request.getHttpRequest() != null && request.getHttpRequest().getUri() != null ) {
MultivaluedMap<String, String> params = request.getHttpRequest().getUri().getQueryParameters();
Expand All @@ -89,10 +87,6 @@ public Response retrieveToken(KeycloakSession session, FederatedIdentityModel id
return Response.ok(identity.getToken()).build();
}

@Override
public void attachUserSession(UserSessionModel userSession, ClientSessionModel clientSession, BrokeredIdentityContext context) {
}

@Override
public Response keycloakInitiatedBrowserLogout(KeycloakSession session, UserSessionModel userSession, UriInfo uriInfo, RealmModel realm) {
String singleLogoutServiceUrl = getConfig().getSingleLogoutServiceUrl();
Expand Down Expand Up @@ -123,7 +117,7 @@ public void backchannelLogout(KeycloakSession session, UserSessionModel userSess
if (singleLogoutServiceUrl == null || singleLogoutServiceUrl.trim().equals("") || !getConfig().isBackchannelSupported()) return;

try {
int status = SimpleHttp.doGet(singleLogoutServiceUrl)
int status = SimpleHttp.doGet(singleLogoutServiceUrl, session)
.param(WSFedConstants.WSFED_ACTION, WSFedConstants.WSFED_SIGNOUT_ACTION)
.param(WSFedConstants.WSFED_REALM, getConfig().getWsFedRealm()).asStatus();

Expand Down
Loading

0 comments on commit a8ba285

Please sign in to comment.