none
ADFS 2.0 does not redirect back to 'reply' url on signout

    Question

  • I'm having a problem with ADFS 2.0 not redirecting back to the url in the wreply parameter.  I'm using the form login page (authenticationType="urn:oasis:names:tc:SAML:1.0:am:password"), if that matters.

    Essentially, I'm calling:

    try
    
    {
    
     FormsAuthentication.SignOut();
    
     WSFederationAuthenticationModule.FederatedSignOut(new Uri(issuer), new Uri(replyUri));
    
    }
    
    finally
    
    {
    
     FederatedAuthentication.SessionAuthenticationModule.DeleteSessionTokenCookie();
    
    }
    

    Unfortunately, ADFS never redirects me back to the URL that I specified.  Does anyone have any ideas?

    Thank you in advance.

    • Edited by Joel.developer Friday, October 01, 2010 5:47 AM Added more info
    Friday, October 01, 2010 5:44 AM

All replies

  • The wreply parameter is a hint to the STS, but it is not obliged to honor it, and ADFS does not. It always replies to the address you specified when creating trust with the relying party.

    What you can do is encode the desired address in the wctx parameter of the request, which will be returned with the token. Then you can redirect to the desired page.

    Thursday, November 25, 2010 8:34 PM
  • I'm having a similar issue with Federated Sign Out.  Our organization has 2 ADFS installations (1 employees, 1 for external users).  I have a claims provider trust established from the external users ADFS to the employees ADFS.  Relying parties that support both types of users establish a trust with the external users STS and can optionally authenticate users in the employees STS. 

    When an external user signs out ADFS works as expected and looks at the wreply parameter to send the user back to the relying party.  However, if an employee signs out the wreply parameter is lost in translation between the external ADFS to the employee ADFS.  Basically, when an employee signs out they are sent to the external ADFS with a wreply parameter and are then redirected to the employee ADFS but the wreply isn't passed.  Therefore, the user just sits on the sign out page.  Is there a way to tell ADFS to redirect the user in a federated sign out scenario?

    Monday, June 20, 2011 3:20 PM
  • I was mistaken...ADFS is handling it appropriately.  Howerver, there is 1 replying party where this isn't working.  I created a test application using WIF and added it as a relying party.  When I sign out I noticed that a redirectContextId is appended as a query string parameter to the federated ADFS instance.  In the application that isn't working the redirectContextId is never added to the message.  The parameters being passed look identical to the one that works minus the url in the wreply parameter.  Obviously, something isn't be set properly by the application in question but it's not obvious to me what the problem is.  Any ideas???
    Monday, June 20, 2011 9:49 PM
  • I figured out why it's happening but I don't really understand why it works the way it does....

     

    In ADFS, the relying party's identifier is https://domain.com and has a WS-Federation endpoint configured as https://domain.com/folder/page.aspx.  The redirect only works when the wreply parameter contains the WS-Federation endpoint.  I'm not sure why the application would like the token posted to a specific page....I should find that out.  I didn't realize it could pose problems. 

    Works:  https://{ADFS URL}/adfs/ls/?wa=wsignout1.0&wreply=https%3a%2f%2fdomain.com%2ffolder%2fpage.aspx

    Doesn't Work: https://{ADFS URL}/adfs/ls/?wa=wsignout1.0&wreply=https%3a%2f%2fdomain.com

     

    Does anyone know the reasoning for this behavior?

    Monday, June 20, 2011 10:15 PM
  • You can customize the SignOut page to add your own redirect logic there.

    SignOut.aspx:

        <script>
            window.onload = function()
            {
                document.getElementById( 'DivSigningOut' ).setAttribute( "class", "NotRendered" );
                document.getElementById( 'DivSigningOut' ).setAttribute( "className", "NotRendered" );
    
                document.getElementById( 'DivSignedOut' ).setAttribute( "class", "" );
                document.getElementById('DivSignedOut').setAttribute("className", "");    
                
                <% 
                if(!string.IsNullOrEmpty(RedirectedUrl))
                {
                 %>
                location.replace("<%= RedirectedUrl %>");  
                <%
                }
                 %>
            }
        </script>


    In SignOut.aspx.cs, you can add:

    protected string RedirectedUrl
        {
            get
            {
                string url = Context.Request.Url.AbsoluteUri;
                NameValueCollection nvc = HttpUtility.ParseQueryString(url);
                return nvc[YOUR_KEY];
            }
        }


    • Edited by fanyang_us Monday, September 12, 2011 1:55 PM
    Sunday, September 11, 2011 2:41 PM
  • Hi everybody,

    Are your relying parties using WS-Federation language only or  also SAML2? I have implemented the Single Log Out protocol, using SAML2, for Weblogic. In my scenario, Weblogic is working as a Service Provider

    My problem is when I reached the sign-out page I can not see my Weblogic SP in the list of applications that I have been logged out.

    I have been taking a look at the http://social.technet.microsoft.com/wiki/contents/articles/ad-fs-how-to-invoke-a-ws-federation-sign-out.aspx, nice! Do you know if there is any similar for SAML2?

    Thanks in advance,

    Luis

    Tuesday, December 06, 2011 8:30 AM
  • Im am trying to use the above to stop the sign out page for ADFS redirecting to login.microsoft.com when users sign out from Outlook on Office365.

    If I insert the script as above, the page returns an error. Please can you let me know where I am going wrong?

    The signout.aspx contains

    <%@ Page Language="C#" MasterPageFile="MasterPages/MasterPage.master" AutoEventWireup="true" CodeFile="SignOut.aspx.cs" Inherits="SignOut"
       Title="<%$ Resources:CommonResources, SignOutPageTitle%>"  EnableViewState="false" runat="server"%>
    <%@ OutputCache Location="None" %>
    <asp:Content ID="SignOutContent" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
        <div id="DivSigningOut">
        <div class="GroupXLargeMargin">
            <asp:Label Text="<%$ Resources:CommonResources, SigningOutText%>"  runat="server" />
        </div>
        <div class="GroupXXLargeMargin Spinner">
            <img src="App_Themes/Default/Spinner.gif" />
            <div class="TextSizeSmall GroupXLargeMargin">
                <asp:Label Text="<%$ Resources:CommonResources, WaitText%>" runat="server" />
            </div>
        </div>

        <asp:Repeater runat="server" ID="CleanupUrisRepeater">
            <ItemTemplate>
        <iframe class="NotShown" src="<%# HttpUtility.HtmlAttributeEncode((string)DataBinder.Eval(Container.DataItem, "Url")) %>"></iframe>
            </ItemTemplate>
        </asp:Repeater>
        </div>
        <div id="DivSignedOut" class="NotRendered">
            <div class="GroupXLargeMargin">
                <asp:Label Text="<%$ Resources:CommonResources, SucessfulSignoutText%>" runat="server" />
            </div>
            <div class="GroupXLargeMargin">
                <asp:Label Text="<%$ Resources:CommonResources, SignOutWarning%>" runat="server" />
            </div>
        </div>

        <script>
            window.onload = function()
            {
                document.getElementById( 'DivSigningOut' ).setAttribute( "class", "NotRendered" );
                document.getElementById( 'DivSigningOut' ).setAttribute( "className", "NotRendered" );

                document.getElementById( 'DivSignedOut' ).setAttribute( "class", "" );
                document.getElementById( 'DivSignedOut' ).setAttribute( "className", "" );
            
            }
        </script>
    </asp:Content>

    and SignOut.aspx.cs

    //------------------------------------------------------------
    // Copyright (c) Microsoft Corporation.  All rights reserved.
    //------------------------------------------------------------

    using System;

    using Microsoft.IdentityServer.Web.UI;

    /// <summary>
    /// This page sends WS-Federation SignOutCleanup messages to all the relying parties
    /// that the user has signed in to during this session.
    /// </summary>
    public partial class SignOut : SignOutPage
    {
        protected void Page_Load( object sender, EventArgs e )
        {
            CleanupUrisRepeater.DataSource = SignOutMessages;
            CleanupUrisRepeater.DataBind();
        }

    }

    Thanks

    Stephen

    Monday, February 20, 2012 4:47 PM
  • Bump.  It has been 3 years and this still is not possible in ADFS 2012.

    Friday, March 01, 2013 11:05 PM
  • Correct and I don't think that will change. It's reasonably well documented that ADFS doesn't honour the wreply field, at least on sign-in, because it's open to abuse. I imagine it's the same story on sign-out.

    Thursday, September 12, 2013 11:44 PM
  • The wreply URL for signout requests must be a sub-URL of the Passive Requestor Endpoint defined for the RP. The reason: Any other rule would make it more difficult for the user to verify if the signout process has completed correctly, thus opening the door for unintentional information disclosure in the 'public library browser' scenario. For sign-in, the wreply is irrelevant - this is exactly what the Passive Requestor Endpoint is used for. HTH
    Saturday, September 14, 2013 6:42 AM
  • Hi Shawn Brandt,

    I've tried the same method as you mentioned, I've set wreply value exactly as WS-Federation endpoint. But still the redirect is not happening. Could you please tell me what I am missing?

    Tuesday, February 18, 2014 6:46 AM