Skip to content

Commit

Permalink
[KEYCLOAK-883] - Code cleanup and refactoring.
Browse files Browse the repository at this point in the history
  • Loading branch information
pedroigor committed Feb 13, 2015
1 parent 7df5a83 commit b0fb737
Show file tree
Hide file tree
Showing 30 changed files with 771 additions and 569 deletions.
Expand Up @@ -31,6 +31,7 @@ public class FederatedIdentity {
private String lastName;
private String email;
private String token;
private String identityProviderId;

public FederatedIdentity(String id) {
if (id == null) {
Expand Down Expand Up @@ -92,4 +93,25 @@ public void setToken(String token) {
public String getToken() {
return this.token;
}

public String getIdentityProviderId() {
return this.identityProviderId;
}

public void setIdentityProviderId(String identityProviderId) {
this.identityProviderId = identityProviderId;
}

@Override
public String toString() {
return "{" +
"id='" + id + '\'' +
", username='" + username + '\'' +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
", token='" + token + '\'' +
", identityProviderId='" + identityProviderId + '\'' +
'}';
}
}
@@ -0,0 +1,32 @@
/*
* JBoss, Home of Professional Open Source
*
* Copyright 2013 Red Hat, Inc. and/or its affiliates.
*
* 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.broker.provider;

/**
* @author pedroigor
*/
public class IdentityBrokerException extends RuntimeException {

public IdentityBrokerException(String message) {
super(message);
}

public IdentityBrokerException(String message, Throwable t) {
super(message, t);
}
}
Expand Up @@ -68,5 +68,12 @@ public interface IdentityProvider<C extends IdentityProviderModel> extends Provi
*/
AuthenticationResponse handleResponse(AuthenticationRequest request);

/**
* <p>Returns a {@link javax.ws.rs.core.Response} containing the token previously stored during the authentication process for a
* specific user.</p>
*
* @param identity
* @return
*/
Response retrieveToken(FederatedIdentityModel identity);
}
Expand Up @@ -25,6 +25,7 @@
import org.keycloak.broker.provider.AuthenticationRequest;
import org.keycloak.broker.provider.AuthenticationResponse;
import org.keycloak.broker.provider.FederatedIdentity;
import org.keycloak.broker.provider.IdentityBrokerException;
import org.keycloak.models.FederatedIdentityModel;

import javax.ws.rs.core.Response;
Expand Down Expand Up @@ -68,7 +69,7 @@ public AuthenticationResponse handleRequest(AuthenticationRequest request) {

return AuthenticationResponse.temporaryRedirect(authorizationUrl);
} catch (Exception e) {
throw new RuntimeException("Could not create authentication request.", e);
throw new IdentityBrokerException("Could not create authentication request.", e);
}
}

Expand All @@ -85,9 +86,9 @@ public AuthenticationResponse handleResponse(AuthenticationRequest request) {

if (error != null) {
if (error.equals("access_denied")) {
throw new RuntimeException("Access denied.");
throw new IdentityBrokerException("Access denied.");
} else {
throw new RuntimeException(error);
throw new IdentityBrokerException(error);
}
}

Expand All @@ -111,9 +112,9 @@ public AuthenticationResponse handleResponse(AuthenticationRequest request) {
return AuthenticationResponse.end(federatedIdentity);
}

throw new RuntimeException("No authorization code from identity provider.");
throw new IdentityBrokerException("No authorization code from identity provider.");
} catch (Exception e) {
throw new RuntimeException("Could not process response from identity provider.", e);
throw new IdentityBrokerException("Could not process response from identity provider.", e);
}
}

Expand All @@ -132,7 +133,7 @@ protected String extractTokenFromResponse(String response, String tokenName) {
try {
return mapper.readTree(response).get(tokenName).getTextValue();
} catch (IOException e) {
throw new RuntimeException("Could not extract token [" + tokenName + "] from response [" + response + "].", e);
throw new IdentityBrokerException("Could not extract token [" + tokenName + "] from response [" + response + "].", e);
}
} else {
Matcher matcher = Pattern.compile(tokenName + "=([^&]+)").matcher(response);
Expand All @@ -149,7 +150,7 @@ protected FederatedIdentity getFederatedIdentity(String response) {
String accessToken = extractTokenFromResponse(response, OAUTH2_PARAMETER_ACCESS_TOKEN);

if (accessToken == null) {
throw new RuntimeException("No access token from server.");
throw new IdentityBrokerException("No access token from server.");
}

return doGetFederatedIdentity(accessToken);
Expand Down
Expand Up @@ -21,6 +21,7 @@
import org.keycloak.broker.oidc.util.SimpleHttp;
import org.keycloak.broker.provider.AuthenticationRequest;
import org.keycloak.broker.provider.FederatedIdentity;
import org.keycloak.broker.provider.IdentityBrokerException;
import org.keycloak.jose.jws.JWSInput;

import javax.ws.rs.core.UriBuilder;
Expand Down Expand Up @@ -62,7 +63,7 @@ protected FederatedIdentity getFederatedIdentity(String response) {
String accessToken = extractTokenFromResponse(response, OAUTH2_PARAMETER_ACCESS_TOKEN);

if (accessToken == null) {
throw new RuntimeException("No access_token from server.");
throw new IdentityBrokerException("No access_token from server.");
}

String idToken = extractTokenFromResponse(response, OIDC_PARAMETER_ID_TOKEN);
Expand Down Expand Up @@ -101,13 +102,13 @@ protected FederatedIdentity getFederatedIdentity(String response) {

return identity;
} catch (Exception e) {
throw new RuntimeException("Could not fetch attributes from userinfo endpoint.", e);
throw new IdentityBrokerException("Could not fetch attributes from userinfo endpoint.", e);
}
}

private void validateIdToken(String idToken) {
if (idToken == null) {
throw new RuntimeException("No id_token from server.");
throw new IdentityBrokerException("No id_token from server.");
}

try {
Expand All @@ -131,10 +132,10 @@ private void validateIdToken(String idToken) {
}
}

throw new RuntimeException("Wrong issuer from id_token..");
throw new IdentityBrokerException("Wrong issuer from id_token..");
}
} catch (IOException e) {
throw new RuntimeException("Could not decode id token.", e);
throw new IdentityBrokerException("Could not decode id token.", e);
}
}

Expand Down
Expand Up @@ -22,6 +22,7 @@
import org.keycloak.broker.provider.AuthenticationRequest;
import org.keycloak.broker.provider.AuthenticationResponse;
import org.keycloak.broker.provider.FederatedIdentity;
import org.keycloak.broker.provider.IdentityBrokerException;
import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.protocol.saml.SAML2AuthnRequestBuilder;
import org.keycloak.protocol.saml.SAML2NameIDPolicyBuilder;
Expand Down Expand Up @@ -112,11 +113,11 @@ public AuthenticationResponse handleRequest(AuthenticationRequest request) {
PublicKey publicKey = request.getRealm().getPublicKey();

if (privateKey == null) {
throw new RuntimeException("Identity Provider [" + getConfig().getName() + "] wants a signed authentication request. But the Realm [" + request.getRealm().getName() + "] does not have a private key.");
throw new IdentityBrokerException("Identity Provider [" + getConfig().getName() + "] wants a signed authentication request. But the Realm [" + request.getRealm().getName() + "] does not have a private key.");
}

if (publicKey == null) {
throw new RuntimeException("Identity Provider [" + getConfig().getName() + "] wants a signed authentication request. But the Realm [" + request.getRealm().getName() + "] does not have a public key.");
throw new IdentityBrokerException("Identity Provider [" + getConfig().getName() + "] wants a signed authentication request. But the Realm [" + request.getRealm().getName() + "] does not have a public key.");
}

KeyPair keypair = new KeyPair(publicKey, privateKey);
Expand All @@ -131,7 +132,7 @@ public AuthenticationResponse handleRequest(AuthenticationRequest request) {
return AuthenticationResponse.fromResponse(authnRequestBuilder.redirectBinding().request());
}
} catch (Exception e) {
throw new RuntimeException("Could not create authentication request.", e);
throw new IdentityBrokerException("Could not create authentication request.", e);
}
}

Expand All @@ -145,7 +146,7 @@ public AuthenticationResponse handleResponse(AuthenticationRequest request) {
String samlResponse = getRequestParameter(request, SAML_RESPONSE_PARAMETER);

if (samlResponse == null) {
throw new RuntimeException("No response from SAML identity provider.");
throw new IdentityBrokerException("No response from SAML identity provider.");
}

try {
Expand All @@ -167,7 +168,7 @@ public AuthenticationResponse handleResponse(AuthenticationRequest request) {

return AuthenticationResponse.end(identity);
} catch (Exception e) {
throw new RuntimeException("Could not process response from SAML identity provider.", e);
throw new IdentityBrokerException("Could not process response from SAML identity provider.", e);
}
}

Expand All @@ -194,7 +195,7 @@ private AssertionType getAssertion(String samlResponse, AuthenticationRequest re
List<RTChoiceType> assertions = responseType.getAssertions();

if (assertions.isEmpty()) {
throw new RuntimeException("No assertion from response.");
throw new IdentityBrokerException("No assertion from response.");
}

RTChoiceType rtChoiceType = assertions.get(0);
Expand Down Expand Up @@ -234,7 +235,7 @@ private void validateStatusResponse(ResponseType responseType) {
detailMessage.append("none");
}

throw new RuntimeException("Authentication failed with code [" + statusCode.getValue() + " and detail [" + detailMessage.toString() + ".");
throw new IdentityBrokerException("Authentication failed with code [" + statusCode.getValue() + " and detail [" + detailMessage.toString() + ".");
}
}

Expand All @@ -246,7 +247,7 @@ private ResponseType decryptAssertion(ResponseType responseType, PrivateKey priv
Element enc = DocumentUtil.getElement(doc, new QName(JBossSAMLConstants.ENCRYPTED_ASSERTION.get()));

if (enc == null) {
throw new RuntimeException("No encrypted assertion found.");
throw new IdentityBrokerException("No encrypted assertion found.");
}

String oldID = enc.getAttribute(JBossSAMLConstants.ID.get());
Expand All @@ -265,7 +266,7 @@ private ResponseType decryptAssertion(ResponseType responseType, PrivateKey priv

return responseType;
} catch (Exception e) {
throw new RuntimeException("Could not decrypt assertion.", e);
throw new IdentityBrokerException("Could not decrypt assertion.", e);
}
}

Expand Down
2 changes: 2 additions & 0 deletions events/api/src/main/java/org/keycloak/events/Details.java
Expand Up @@ -12,6 +12,8 @@ public interface Details {
String REDIRECT_URI = "redirect_uri";
String RESPONSE_TYPE = "response_type";
String AUTH_METHOD = "auth_method";
String IDENTITY_PROVIDER = "identity_provider";
String IDENTITY_PROVIDER_IDENTITY = "identity_provider_identity";
String REGISTER_METHOD = "register_method";
String USERNAME = "username";
String REMEMBER_ME = "remember_me";
Expand Down
1 change: 0 additions & 1 deletion events/api/src/main/java/org/keycloak/events/Errors.java
Expand Up @@ -35,7 +35,6 @@ public interface Errors {

String NOT_ALLOWED = "not_allowed";

String IDENTITY_PROVIDER_NOT_FOUND = "identity_provider_not_found";
String FEDERATED_IDENTITY_EMAIL_EXISTS = "federated_identity_email_exists";
String FEDERATED_IDENTITY_USERNAME_EXISTS = "federated_identity_username_exists";
String FEDERATED_IDENTITY_DISABLED_REGISTRATION = "federated_identity_disabled_registration";
Expand Down
11 changes: 10 additions & 1 deletion events/api/src/main/java/org/keycloak/events/EventType.java
Expand Up @@ -48,5 +48,14 @@ public enum EventType {
UNREGISTER_NODE,

USER_INFO_REQUEST,
USER_INFO_REQUEST_ERROR
USER_INFO_REQUEST_ERROR,

IDENTITY_PROVIDER_LOGIN,
IDENTITY_PROVIDER_LOGIN_ERROR,
IDENTITY_PROVIDER_RESPONSE,
IDENTITY_PROVIDER_RESPONSE_ERROR,
IDENTITY_PROVIDER_RETRIEVE_TOKEN,
IDENTITY_PROVIDER_RETRIEVE_TOKEN_ERROR,
IDENTITY_PROVIDER_ACCCOUNT_LINKING,
IDENTITY_PROVIDER_ACCCOUNT_LINKING_ERROR,
}
Expand Up @@ -83,7 +83,7 @@ module.controller('GlobalCtrl', function($scope, $http, $location, Auth) {
$scope.identity = Auth.getIdentity();

$scope.loadSocialProfile = function() {
$http.get('http://localhost:8081/auth/broker/facebook-identity-provider-realm/facebook/token').success(function(data) {
$http.get('http://localhost:8081/auth/realms/facebook-identity-provider-realm/broker/facebook/token').success(function(data) {
var accessTokenParameter = 'access_token=';
var accessToken = data.substring(data.indexOf(accessTokenParameter) + accessTokenParameter.length, data.indexOf('&'));

Expand Down
Expand Up @@ -83,7 +83,7 @@ module.controller('GlobalCtrl', function($scope, $http, $location, Auth) {
$scope.identity = Auth.getIdentity();

$scope.loadSocialProfile = function() {
$http.get('http://localhost:8081/auth/broker/google-identity-provider-realm/google/token').success(function(data) {
$http.get('http://localhost:8081/auth/realms/google-identity-provider-realm/broker/google/token').success(function(data) {
var accessToken = data.access_token;

var req = {
Expand Down
Expand Up @@ -31,7 +31,7 @@
"name": "http://localhost:8080/auth/",
"enabled": true,
"redirectUris": [
"http://localhost:8080/auth/broker/saml-broker-authentication-realm/saml-identity-provider"
"http://localhost:8080/auth/realms/saml-broker-authentication-realm/broker/saml-identity-provider"
],
"attributes": {
"saml.assertion.signature": "true",
Expand Down
Expand Up @@ -114,7 +114,7 @@ public void filter(ClientRequestContext requestContext) throws IOException {
}

private String getIdentityProviderTokenUrl() {
return this.authServer + "/broker/" + this.realmName + "/" + this.identityProvider.getId() + "/token";
return this.authServer + "/realms/" + this.realmName + "/broker/" + this.identityProvider.getId() + "/token";
}

private void initKeyCloakClient(ServletConfig config) {
Expand Down
Expand Up @@ -719,7 +719,7 @@ module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload
}
}, true);

$scope.callbackUrl = $location.absUrl().replace(/\/admin.*/, "/broker/") + realm.realm + "/" ;
$scope.callbackUrl = $location.absUrl().replace(/\/admin.*/, "/realms/") + realm.realm + "/broker/" ;

$scope.addProvider = function(provider) {
$location.url("/create/identity-provider/" + realm.realm + "/" + provider.id);
Expand Down
Expand Up @@ -61,7 +61,7 @@ public IdentityProviderBean(RealmModel realm, URI baseURI, UriInfo uriInfo) {
}
}

String loginUrl = Urls.identityProviderAuthnRequest(baseURI, identityProvider, realm).toString();
String loginUrl = Urls.identityProviderAuthnRequest(baseURI, identityProvider.getId(), realm.getName()).toString();
providers.add(new IdentityProvider(identityProvider.getId(), identityProvider.getName(), loginUrl));
}
}
Expand Down
Expand Up @@ -879,7 +879,7 @@ public Response loginPage(@QueryParam(OpenIDConnect.RESPONSE_TYPE_PARAM) String
}

return Response.temporaryRedirect(
Urls.identityProviderAuthnRequest(this.uriInfo.getBaseUri(), identityProviderModel, realm, accessCode)).build();
Urls.identityProviderAuthnRequest(this.uriInfo.getBaseUri(), idpHint, this.realm.getName(), accessCode)).build();
}

response = authManager.checkNonFormAuthentication(session, clientSession, realm, uriInfo, request, clientConnection, headers, event);
Expand All @@ -898,7 +898,7 @@ public Response loginPage(@QueryParam(OpenIDConnect.RESPONSE_TYPE_PARAM) String
if (!identityProviders.isEmpty()) {
if (identityProviders.size() == 1) {
return Response.temporaryRedirect(
Urls.identityProviderAuthnRequest(this.uriInfo.getBaseUri(), identityProviders.get(0), this.realm, accessCode))
Urls.identityProviderAuthnRequest(this.uriInfo.getBaseUri(), identityProviders.get(0).getId(), this.realm.getName(), accessCode))
.build();
}

Expand Down

0 comments on commit b0fb737

Please sign in to comment.