IdentityServer3.WsFederation icon indicating copy to clipboard operation
IdentityServer3.WsFederation copied to clipboard

WS-Federation not getting redirected to client application

Open sajanep opened this issue 9 years ago • 2 comments

Hello, I am trying to perform a single sign out from Identity Server. I am using below code for the same(from my relying party application) ` protected void btnSignout_Click(object sender, EventArgs e) { ClaimsPrincipal claimsPrincipal = Thread.CurrentPrincipal as ClaimsPrincipal; if (claimsPrincipal.Identity.IsAuthenticated) { var sam = FederatedAuthentication.SessionAuthenticationModule; sam.SignOut();

            var signOutRequest = new SignOutRequestMessage(new Uri(
                        FederatedAuthentication.WSFederationAuthenticationModule.Issuer));
            signOutRequest.Reply = "http://localhost:44302/Account/SignOut.aspx";

            Response.Redirect(signOutRequest.WriteQueryString());
        }
    }       `

But I am not getting redirected to the sign out page in app and remain in identity server itself. Code which is written in Identity Server hosted app is like below

`public void Configuration(IAppBuilder app) {

         var idSrvSvcFactory = new IdentityServerServiceFactory()
                            .UseInMemoryUsers(Users.Get())
                            .UseInMemoryClients(Clients.Get())
                            .UseInMemoryScopes(StandardScopes.All);

        var wsFedOptions = new IdentityServerOptions
        {
            SiteName = "IdentityServer3 with WsFed",
            SigningCertificate = LoadCertificate(),
            Factory = idSrvSvcFactory,
            PluginConfiguration = ConfigureWsFederation,
            AuthenticationOptions = new AuthenticationOptions {
                EnableSignOutPrompt = false,
                EnablePostSignOutAutoRedirect = true,
                PostSignOutAutoRedirectDelay = 0,
            }
        };         

        app.Map("/identity", idsrvApp =>
        {
            idsrvApp.UseIdentityServer(wsFedOptions);
        });
    }

    private X509Certificate2 LoadCertificate()
    {
        return new X509Certificate2(
            string.Format(@"{0}\bin\idsrv3test.pfx", AppDomain.CurrentDomain.BaseDirectory), "idsrv3test");
    }

    private void ConfigureWsFederation(IAppBuilder pluginApp, IdentityServerOptions options)
    {
        var factory = new WsFederationServiceFactory(options.Factory);
        factory.UseInMemoryRelyingParties(RelyingParties.Get());

        var wsFedOptions = new WsFederationPluginOptions
        {
            IdentityServerOptions = options,
            Factory = factory
        };

        pluginApp.UseWsFederationPlugin(wsFedOptions);
    }`

The code to add a relying party is like below

public static class RelyingParties
    {
        public static IEnumerable<RelyingParty> Get()
        {
            return new List<RelyingParty>
            {
                new RelyingParty 
                {
                    Name = "TestApp",
                    Enabled = true,
                    Realm = "http://localhost:44302",
                    ReplyUrl = "http://localhost:44302",
                    IncludeAllClaimsForUser = true,
                    PostLogoutRedirectUris = new List<string>{ "http://localhost:44302/Account/SignOut.aspx" }
                }
            };
        }
    }

Can someone tell me how to re-direct back to my client application on sign-out?

sajanep avatar Sep 15 '16 13:09 sajanep

private async Task<IHttpActionResult> ProcessSignOutAsync(SignOutRequestMessage msg)
        {
            // in order to determine redirect url wreply and wtrealm must be non-empty
            if (String.IsNullOrWhiteSpace(msg.Reply) || String.IsNullOrWhiteSpace(msg.GetParameter("wtrealm")))
            {
                if (!String.IsNullOrWhiteSpace(msg.Reply))
                {
                    return RedirectToLogOut(msg.Reply);
                }
                return RedirectToLogOut();
            }

            var result = await _signOutValidator.ValidateAsync(msg);
            if (result.IsError)
            {
                Logger.Error(result.Error);
                await _events.RaiseFailureWsFederationEndpointEventAsync(
                    WsFederationEventConstants.Operations.SignOut,
                    result.RelyingParty.Realm,
                    User as ClaimsPrincipal,
                    Request.RequestUri.AbsoluteUri,
                    result.Error);

                return BadRequest(result.Error);
            }

            if (await _redirectUriValidator.IsPostLogoutRedirectUriValidAsync(msg.Reply, result.RelyingParty) == false)
            {
                const string error = "invalid_signout_reply_uri";

                Logger.Error(error);
                await _events.RaiseFailureWsFederationEndpointEventAsync(
                    WsFederationEventConstants.Operations.SignOut,
                    result.RelyingParty.Realm,
                    User as ClaimsPrincipal,
                    Request.RequestUri.AbsoluteUri,
                    error);

                return BadRequest(error);
            }

            await _events.RaiseSuccessfulWsFederationEndpointEventAsync(
                    WsFederationEventConstants.Operations.SignOut,
                    result.RelyingParty.Realm,
                    User as ClaimsPrincipal,
                    Request.RequestUri.AbsoluteUri);

            return RedirectToLogOut(msg.Reply);
        }

Do following change in this WsFederationController it will work

divyang4481 avatar Jan 17 '17 09:01 divyang4481

Sure, it will work but there won't be any validation on the request or redirect uri...

scottbrady91 avatar Jan 17 '17 09:01 scottbrady91