keycloak-aplcache

Merge pull request #1050 from patriot1burke/master saml

3/16/2015 2:31:47 PM

Details

diff --git a/broker/core/src/main/java/org/keycloak/broker/provider/AbstractIdentityProvider.java b/broker/core/src/main/java/org/keycloak/broker/provider/AbstractIdentityProvider.java
old mode 100644
new mode 100755
index f38d840..bc007ae
--- a/broker/core/src/main/java/org/keycloak/broker/provider/AbstractIdentityProvider.java
+++ b/broker/core/src/main/java/org/keycloak/broker/provider/AbstractIdentityProvider.java
@@ -18,6 +18,10 @@
 package org.keycloak.broker.provider;
 
 import org.keycloak.models.IdentityProviderModel;
+import org.keycloak.models.RealmModel;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
 
 /**
  * @author Pedro Igor
@@ -35,6 +39,11 @@ public abstract class AbstractIdentityProvider<C extends IdentityProviderModel> 
     }
 
     @Override
+    public Response export(UriInfo uriInfo, RealmModel realm, String format) {
+        return Response.noContent().build();
+    }
+
+    @Override
     public void close() {
         // no-op
     }
diff --git a/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProvider.java b/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProvider.java
old mode 100644
new mode 100755
index ac1e3dc..f754eeb
--- a/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProvider.java
+++ b/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProvider.java
@@ -19,9 +19,11 @@ package org.keycloak.broker.provider;
 
 import org.keycloak.models.FederatedIdentityModel;
 import org.keycloak.models.IdentityProviderModel;
+import org.keycloak.models.RealmModel;
 import org.keycloak.provider.Provider;
 
 import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
 
 /**
  * @author Pedro Igor
@@ -76,4 +78,12 @@ public interface IdentityProvider<C extends IdentityProviderModel> extends Provi
      * @return
      */
     Response retrieveToken(FederatedIdentityModel identity);
+
+    /**
+     * Export a representation of the IdentityProvider in a specific format.  For example, a SAML EntityDescriptor
+     *
+     * @return
+     */
+    Response export(UriInfo uriInfo, RealmModel realm, String format);
+
 }
diff --git a/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProvider.java b/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProvider.java
old mode 100644
new mode 100755
index 1ad696c..c136c1d
--- a/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProvider.java
+++ b/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProvider.java
@@ -24,6 +24,8 @@ 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.models.IdentityProviderModel;
+import org.keycloak.models.RealmModel;
 import org.keycloak.protocol.saml.SAML2AuthnRequestBuilder;
 import org.keycloak.protocol.saml.SAML2NameIDPolicyBuilder;
 import org.picketlink.common.constants.JBossSAMLConstants;
@@ -55,6 +57,7 @@ import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
+import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriBuilder;
@@ -85,7 +88,8 @@ public class SAMLIdentityProvider extends AbstractIdentityProvider<SAMLIdentityP
     public AuthenticationResponse handleRequest(AuthenticationRequest request) {
         try {
             UriInfo uriInfo = request.getUriInfo();
-            String issuerURL = UriBuilder.fromUri(uriInfo.getBaseUri()).build().toString();
+            RealmModel realm = request.getRealm();
+            String issuerURL = getEntityId(uriInfo, realm);
             String destinationUrl = getConfig().getSingleSignOnServiceUrl();
             String nameIDPolicyFormat = getConfig().getNameIDPolicyFormat();
 
@@ -109,15 +113,15 @@ public class SAMLIdentityProvider extends AbstractIdentityProvider<SAMLIdentityP
                     .relayState(request.getState());
 
             if (getConfig().isWantAuthnRequestsSigned()) {
-                PrivateKey privateKey = request.getRealm().getPrivateKey();
-                PublicKey publicKey = request.getRealm().getPublicKey();
+                PrivateKey privateKey = realm.getPrivateKey();
+                PublicKey publicKey = realm.getPublicKey();
 
                 if (privateKey == null) {
-                    throw new IdentityBrokerException("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 [" + realm.getName() + "] does not have a private key.");
                 }
 
                 if (publicKey == null) {
-                    throw new IdentityBrokerException("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 [" + realm.getName() + "] does not have a public key.");
                 }
 
                 KeyPair keypair = new KeyPair(publicKey, privateKey);
@@ -136,6 +140,10 @@ public class SAMLIdentityProvider extends AbstractIdentityProvider<SAMLIdentityP
         }
     }
 
+    private String getEntityId(UriInfo uriInfo, RealmModel realm) {
+        return UriBuilder.fromUri(uriInfo.getBaseUri()).path("realms").path(realm.getName()).build().toString();
+    }
+
     @Override
     public String getRelayState(AuthenticationRequest request) {
         return getRequestParameter(request, RELAY_STATE_PARAMETER);
@@ -283,4 +291,45 @@ public class SAMLIdentityProvider extends AbstractIdentityProvider<SAMLIdentityP
 
         return requestParameters.getFirst(parameterName);
     }
+
+    @Override
+    public Response export(UriInfo uriInfo, RealmModel realm, String format) {
+
+        String authnBinding = JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get();
+
+        if (getConfig().isPostBindingAuthnRequest()) {
+            authnBinding = JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get();
+        }
+
+        String assertionConsumerService = uriInfo.getBaseUriBuilder().path("realms").path(realm.getName()).path("broker").path(getConfig().getProviderId()).build().toString();
+
+
+
+        String descriptor =
+                "<EntityDescriptor entityID=\"" + getEntityId(uriInfo, realm) + "\n" +
+                "    <SPSSODescriptor AuthnRequestsSigned=\"" + getConfig().isWantAuthnRequestsSigned() + "\n" +
+                "            protocolSupportEnumeration=\"urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol http://schemas.xmlsoap.org/ws/2003/07/secext\">\n" +
+                "        <NameIDFormat>" + getConfig().getNameIDPolicyFormat() + "\n" +
+                "        </NameIDFormat>\n" +
+// todo single logout service description
+//                "        <SingleLogoutService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\" Location=\"http://localhost:8081/sales-metadata/\"/>\n" +
+                "        <AssertionConsumerService\n" +
+                "                Binding=\"" + authnBinding + "\" Location=\"" + assertionConsumerService + "\n" +
+                "                index=\"1\" isDefault=\"true\" />\n";
+        if (getConfig().isWantAuthnRequestsSigned()) {
+            descriptor +=
+                "        <KeyDescriptor use=\"signing\">\n" +
+                "            <dsig:KeyInfo xmlns:dsig=\"http://www.w3.org/2000/09/xmldsig#\">\n" +
+                "                <dsig:X509Data>\n" +
+                "                    <dsig:X509Certificate>\n" + realm.getCertificatePem() + "\n" +
+                "                    </dsig:X509Certificate>\n" +
+                "                </dsig:X509Data>\n" +
+                "            </dsig:KeyInfo>\n" +
+                "        </KeyDescriptor>\n";
+        }
+        descriptor +=
+                "    </SPSSODescriptor>\n" +
+                "</EntityDescriptor>\n";
+        return Response.ok(descriptor, MediaType.APPLICATION_XML_TYPE).build();
+    }
 }
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js
index 8200486..c34debe 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js
@@ -188,6 +188,24 @@ module.config([ '$routeProvider', function($routeProvider) {
             },
             controller : 'RealmIdentityProviderCtrl'
         })
+        .when('/realms/:realm/identity-provider-settings/provider/:provider_id/:id/export', {
+            templateUrl : resourceUrl + '/partials/realm-identity-provider-export.html',
+            resolve : {
+                realm : function(RealmLoader) {
+                    return RealmLoader();
+                },
+                serverInfo : function(ServerInfoLoader) {
+                    return ServerInfoLoader();
+                },
+                identityProvider : function(IdentityProviderLoader) {
+                    return IdentityProviderLoader();
+                },
+                providerFactory : function(IdentityProviderFactoryLoader) {
+                    return IdentityProviderFactoryLoader();
+                }
+            },
+            controller : 'RealmIdentityProviderExportCtrl'
+        })
         .when('/realms/:realm/default-roles', {
             templateUrl : resourceUrl + '/partials/realm-default-roles.html',
             resolve : {
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/realm.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/realm.js
index 3873df1..27884c4 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/realm.js
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/realm.js
@@ -796,7 +796,11 @@ module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload
             $scope.identityProvider.config.postBindingResponse = $scope.getBoolean($scope.identityProvider.config.postBindingResponse);
             $scope.identityProvider.config.wantAuthnRequestsSigned = $scope.getBoolean($scope.identityProvider.config.wantAuthnRequestsSigned);
         } else {
+            $scope.identityProvider.config.validateSignature = true;
+            $scope.identityProvider.config.postBindingAuthnRequest = true;
             $scope.identityProvider.config.postBindingResponse = true;
+            $scope.identityProvider.config.wantAuthnRequestsSigned = true;
+            $scope.identityProvider.config.nameIDPolicyFormat = 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient';
         }
     }
 
@@ -809,6 +813,30 @@ module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload
     }
 });
 
+module.controller('RealmIdentityProviderExportCtrl', function(realm, identityProvider, $scope, $http, IdentityProviderExport) {
+    $scope.realm = realm;
+    $scope.identityProvider = identityProvider;
+    $scope.download = null;
+    $scope.exported = "";
+    $scope.exportedType = "";
+
+    var url = IdentityProviderExport.url({realm: realm.realm, id: identityProvider.id}) ;
+    $http.get(url).success(function(data, status, headers, config) {
+        $scope.exportedType = headers('Content-Type');
+        $scope.exported = data;
+    });
+
+    $scope.download = function() {
+        var suffix = "txt";
+        if ($scope.exportedType == 'application/xml') {
+            suffix = 'xml';
+        } else if ($scope.exportedType == 'application/json') {
+            suffix = 'json';
+        }
+        saveAs(new Blob([$scope.exported], { type: $scope.exportedType }), 'keycloak.' + suffix);
+    }
+});
+
 module.controller('RealmTokenDetailCtrl', function($scope, Realm, realm, $http, $location, $route, Dialog, Notifications, TimeUnit) {
     console.log('RealmTokenDetailCtrl');
 
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js
index 53bcf1f..7638383 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js
@@ -1117,6 +1117,16 @@ module.factory('IdentityProvider', function($resource) {
     });
 });
 
+module.factory('IdentityProviderExport', function($resource) {
+    var url = authUrl + '/admin/realms/:realm/identity-provider/:id/export';
+    return {
+        url : function(parameters)
+        {
+            return url.replace(':realm', parameters.realm).replace(':id', parameters.id);
+        }
+    }
+});
+
 module.factory('IdentityProviderFactory', function($resource) {
     return $resource(authUrl + '/admin/realms/:realm/identity-provider/providers/:provider_id', {
         realm : '@realm',
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-identity-provider-export.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-identity-provider-export.html
new file mode 100755
index 0000000..fc97a02
--- /dev/null
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-identity-provider-export.html
@@ -0,0 +1,26 @@
+<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
+<div id="content-area" class="col-md-9" role="main">
+
+    <data-kc-navigation data-kc-current="social" data-kc-realm="realm.realm" data-kc-social="realm.social"></data-kc-navigation>
+    <div id="content">
+        <ol class="breadcrumb">
+            <li><a href="#/realms/{{realm.realm}}/identity-provider-settings">Identity Providers</a></li>
+            <li class="active"><a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.id}}">{{identityProvider.name}} Provider</a></li>
+            <li class="active">{{identityProvider.name}} Provider Export</li>
+        </ol>
+        <h2 class="pull-left">{{identityProvider.name}} Provider Export</h2>
+        <form class="form-horizontal" name="realmForm" novalidate>
+            <fieldset class="border-top">
+                <div class="form-group">
+                    <div class="col-sm-12">
+                        <textarea class="form-control" rows="20" kc-select-action="click">{{exported}}</textarea>
+                    </div>
+                </div>
+            </fieldset>
+        </form>
+
+        <div class="pull-right form-actions">
+            <a class="btn btn-primary btn-lg" data-ng-click="download()" type="submit">Download</a>
+        </div>
+    </div>
+</div>
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-identity-provider-saml.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-identity-provider-saml.html
index af51a48..dbe80fd 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-identity-provider-saml.html
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-identity-provider-saml.html
@@ -47,7 +47,16 @@
                     <div class="form-group clearfix" data-ng-show="!importFile">
                         <label class="col-sm-2 control-label" for="nameIDPolicyFormat">NameID Policy Format</label>
                         <div class="col-sm-4">
-                            <input class="form-control" id="nameIDPolicyFormat" type="text" ng-model="identityProvider.config.nameIDPolicyFormat">
+                            <select id="nameIDPolicyFormat" ng-model="identityProvider.config.nameIDPolicyFormat">
+                                <option value="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">Transient</option>
+                                <option value="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">Persistent</option>
+                                <option value="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">Email</option>
+                                <option value="urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos">Kerberos</option>
+                                <option value="urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName">X.509 Subject Name</option>
+                                <option value="urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName">Windows Domain Qualified Name</option>
+                                <option value="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">Unspecified</option>
+                            </select>
+                            <!-- <input class="form-control" id="nameIDPolicyFormat" type="text" ng-model="identityProvider.config.nameIDPolicyFormat"> -->
                         </div>
                         <span tooltip-placement="right" tooltip="Specifies the URI reference corresponding to a name identifier format. Defaults to urn:oasis:names:tc:SAML:2.0:nameid-format:persistent." class="fa fa-info-circle"></span>
                     </div>
@@ -124,6 +133,7 @@
                 </fieldset>
 
                 <div class="pull-right form-actions">
+                    <a class="btn btn-lg btn-primary" href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.id}}/export" data-ng-show="!importFile && !newIdentityProvider">Export</a>
                     <button kc-save data-ng-show="!importFile">Save</button>
                     <button type="submit" data-ng-click="clearFileSelect()" data-ng-show="importFile" class="btn btn-lg btn-default">Cancel</button>
                     <button type="submit" data-ng-click="uploadFile()" data-ng-show="importFile" class="btn btn-lg btn-primary">Import from SAML Metadata</button>

README.md 3(+3 -0)

diff --git a/README.md b/README.md
index 3fb26f8..3ba55db 100755
--- a/README.md
+++ b/README.md
@@ -31,6 +31,9 @@ Here's some of the features:
 * Password policies
 * OpenID Connect Support
 * SAML Support
+* Token claim and SAML assertion mappings, role name mappings, etc.  Ability to configure exactly what information you want in your tokens and SAML documents
+* IDP brokering or chaining.  You can set up Keycloak to be a child IDP to another SAML or OIDC IDP.
+* Kerberos bridging.  Logged in Kerberos users can access Keycloak SAML or OIDC applications via our Kerberos bridge.
 
 Please visit [http://keycloak.org](http://keycloak.org) for more information on Keycloak including how to download, documentation,
 and video tutorials.
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java
index bac9b03..e8ec27e 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java
@@ -1,6 +1,9 @@
 package org.keycloak.services.resources.admin;
 
 import org.jboss.resteasy.annotations.cache.NoCache;
+import org.keycloak.broker.provider.IdentityBrokerException;
+import org.keycloak.broker.provider.IdentityProvider;
+import org.keycloak.broker.provider.IdentityProviderFactory;
 import org.keycloak.models.ClientIdentityProviderMappingModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.IdentityProviderModel;
@@ -9,31 +12,42 @@ import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.models.utils.RepresentationToModel;
+import org.keycloak.provider.ProviderFactory;
 import org.keycloak.representations.idm.IdentityProviderRepresentation;
 import org.keycloak.services.resources.flows.Flows;
+import org.keycloak.social.SocialIdentityProvider;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * @author Pedro Igor
  */
 public class IdentityProviderResource {
 
+    private final RealmAuth auth;
     private final RealmModel realm;
     private final KeycloakSession session;
     private final IdentityProviderModel identityProviderModel;
 
-    public IdentityProviderResource(RealmModel realm, KeycloakSession session, IdentityProviderModel identityProviderModel) {
+    public IdentityProviderResource(RealmAuth auth, RealmModel realm, KeycloakSession session, IdentityProviderModel identityProviderModel) {
         this.realm = realm;
         this.session = session;
         this.identityProviderModel = identityProviderModel;
+        this.auth = auth;
     }
 
     @GET
@@ -46,6 +60,7 @@ public class IdentityProviderResource {
     @DELETE
     @NoCache
     public Response delete() {
+        this.auth.requireManage();
         removeClientIdentityProviders(this.realm.getApplications(), this.identityProviderModel);
         removeClientIdentityProviders(this.realm.getApplications(), this.identityProviderModel);
         this.realm.removeIdentityProviderById(this.identityProviderModel.getId());
@@ -56,6 +71,7 @@ public class IdentityProviderResource {
     @Consumes("application/json")
     public Response update(IdentityProviderRepresentation model) {
         try {
+            this.auth.requireManage();
             this.realm.updateIdentityProvider(RepresentationToModel.toModel(model));
             return Response.noContent().build();
         } catch (ModelDuplicateException e) {
@@ -63,6 +79,33 @@ public class IdentityProviderResource {
         }
     }
 
+    private IdentityProviderFactory getIdentityProviderFactory() {
+        List<ProviderFactory> allProviders = new ArrayList<ProviderFactory>();
+
+        allProviders.addAll(this.session.getKeycloakSessionFactory().getProviderFactories(IdentityProvider.class));
+        allProviders.addAll(this.session.getKeycloakSessionFactory().getProviderFactories(SocialIdentityProvider.class));
+
+        for (ProviderFactory providerFactory : allProviders) {
+            if (providerFactory.getId().equals(identityProviderModel.getProviderId())) return (IdentityProviderFactory)providerFactory;
+        }
+
+        return null;
+    }
+
+
+    @GET
+    @Path("export")
+    public Response export(@Context UriInfo uriInfo, @QueryParam("format") String format) {
+        try {
+            this.auth.requireView();
+            IdentityProviderFactory factory = getIdentityProviderFactory();
+            return factory.create(identityProviderModel).export(uriInfo, realm, format);
+        } catch (Exception e) {
+            return Flows.errors().error("Could not export public broker configuration for identity provider [" + identityProviderModel.getProviderId() + "].", Response.Status.NOT_FOUND);
+        }
+    }
+
+
     private void removeClientIdentityProviders(List<? extends ClientModel> clients, IdentityProviderModel identityProvider) {
         for (ClientModel clientModel : clients) {
             List<ClientIdentityProviderMappingModel> identityProviders = clientModel.getIdentityProviders();
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java
index d7d1a67..a046c04 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java
@@ -151,7 +151,7 @@ public class IdentityProvidersResource {
             throw new NotFoundException("Could not find identity provider: " + providerId);
         }
 
-        IdentityProviderResource identityProviderResource = new IdentityProviderResource(realm, session, identityProviderModel);
+        IdentityProviderResource identityProviderResource = new IdentityProviderResource(this.auth, realm, session, identityProviderModel);
         ResteasyProviderFactory.getInstance().injectProperties(identityProviderResource);
 
         return identityProviderResource;
diff --git a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
index 9e9282a..b4554ba 100755
--- a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
@@ -606,9 +606,6 @@ public class LoginActionsService {
         return authManager.redirectAfterSuccessfulFlow(session, realm, userSession, clientSession, request, uriInfo, clientConnection);
     }
 
-
-
-
     @Path("profile")
     @POST
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
index 4743826..fb78299 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
@@ -157,7 +157,7 @@ public class AccountTest {
         });
     }
 
-    //@Test @Ignore
+    @Test @Ignore
     public void runit() throws Exception {
         Thread.sleep(10000000);
     }
diff --git a/testsuite/integration/src/test/resources/broker-test/test-broker-realm-with-saml.json b/testsuite/integration/src/test/resources/broker-test/test-broker-realm-with-saml.json
index 60c0396..5757b28 100755
--- a/testsuite/integration/src/test/resources/broker-test/test-broker-realm-with-saml.json
+++ b/testsuite/integration/src/test/resources/broker-test/test-broker-realm-with-saml.json
@@ -8,7 +8,7 @@
     "publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgj8r0029eL0jJKXv6XbNj+QqsZO25HhZ0IjTEtb8mfh0tju/X8c6dXgILh5wU7OF00U+0mSYSE/+rrYKmY5g4oCleTe1+abavATP1tamtXGAUYqdutaXPrVn9yMsCWEPchSPZlEGq5iBJdA+xh9ejUmZJYXmln26HUVWq71/jC9GpjbRmFQ37f0X7WJoGyiqyttfKkKfUeBmRbX/0P0Zm6DVze8HjCDVPBllZE0a3HCgSF0rp0+s1xn7o91qdWKVattAVsGNjjDPz/sgwHOyyhDtSyajwXU+K/QUZ9pV4moGtwC9uIEymTylP7bu7qnxXIhfouEa+fEjAzTs0HJ5JQIDAQAB",
     "applications": [
         {
-            "name": "http://localhost:8081/auth/",
+            "name": "http://localhost:8081/auth/realms/realm-with-broker",
             "enabled": true,
             "redirectUris": [
                 "http://localhost:8081/auth/realms/realm-with-broker/broker/kc-saml-idp-basic"
diff --git a/testsuite/integration/src/test/resources/broker-test/test-broker-realm-with-saml-with-signature.json b/testsuite/integration/src/test/resources/broker-test/test-broker-realm-with-saml-with-signature.json
index 4b3c505..db027d8 100755
--- a/testsuite/integration/src/test/resources/broker-test/test-broker-realm-with-saml-with-signature.json
+++ b/testsuite/integration/src/test/resources/broker-test/test-broker-realm-with-saml-with-signature.json
@@ -8,7 +8,7 @@
     "publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgj8r0029eL0jJKXv6XbNj+QqsZO25HhZ0IjTEtb8mfh0tju/X8c6dXgILh5wU7OF00U+0mSYSE/+rrYKmY5g4oCleTe1+abavATP1tamtXGAUYqdutaXPrVn9yMsCWEPchSPZlEGq5iBJdA+xh9ejUmZJYXmln26HUVWq71/jC9GpjbRmFQ37f0X7WJoGyiqyttfKkKfUeBmRbX/0P0Zm6DVze8HjCDVPBllZE0a3HCgSF0rp0+s1xn7o91qdWKVattAVsGNjjDPz/sgwHOyyhDtSyajwXU+K/QUZ9pV4moGtwC9uIEymTylP7bu7qnxXIhfouEa+fEjAzTs0HJ5JQIDAQAB",
     "applications": [
         {
-            "name": "http://localhost:8081/auth/",
+            "name": "http://localhost:8081/auth/realms/realm-with-broker",
             "enabled": true,
             "redirectUris": [
                 "http://localhost:8081/auth/realms/realm-with-broker/broker/kc-saml-signed-idp"