Joergen Bech
Joergen Bech

Reputation: 1475

WSFederationAuthenticationModule: RedirectToIdentityProvider: Does the realm have to be a subset of the request URL?

Like so many others dealing with WIF in .NET I ran into the usual error:

ID3206: A SignInResponse message may only redirect within the current web application.

I wrote a custom authentication module where I overrode RedirectToIdentityProvider as suggested in Error - A SignInResponse message may only redirect within the current web application - MVC 2.0 application.

The suggested code sample did not take into account that the request URL might include parameters, i.e. it would simply append a trailing slash to the full URL. Eventually I expanded that code to what you see below but still used the realm in order to decide whether or not to process the URL:

Public Overrides Sub RedirectToIdentityProvider(ByVal uniqueId As String, ByVal returnUrl As String, ByVal persist As Boolean)
    Dim absoluteUri As String = HttpContext.Current.Request.Url.AbsoluteUri
    Dim ciAbsoluteUri As String = absoluteUri.ToLowerInvariant

    Dim realm As String = MyBase.Realm
    Dim ciRealm As String = realm.ToLowerInvariant

    'If Realm ends with a trailing slash, the returnUrl should include a trailing slash in the same position.
    'This trailing slash may or may not be the end of the returnUrl, depending on whether or not additional parameters have been provided.
    If realm.EndsWith("/") Then
        If Not ciAbsoluteUri.StartsWith(ciRealm) Then
            Dim realmWithoutSlash As String = realm.Substring(0, realm.Length - 1)
            Dim ciRealmWithoutSlash As String = realmWithoutSlash.ToLowerInvariant
            If ciAbsoluteUri.StartsWith(ciRealmWithoutSlash) Then
                'Realm ends with a slash and AbsoluteUri contains Realm but without a slash.
                Dim absolutePath As String = HttpContext.Current.Request.Url.AbsolutePath
                returnUrl = returnUrl.Replace(absolutePath, absolutePath & "/")
            End If
        End If
    End If

    MyBase.RedirectToIdentityProvider(uniqueId, returnUrl, persist)

End Sub

(This could have been written more compactly but that is besides the point.)

The code in the original post includes the following comment

//Compare if Request Url +"/" is equal to the Realm, so only root access is corrected
//https://localhost/AppName plus "/" is equal to https://localhost/AppName/
//This is to avoid MVC urls

It is perfectly possible to set the realm and audienceUri in the web.config file and the identifier on the AD FS 2.0 side to something other than a subset of the request URL as long as the value is a valid URI. For example, a bogus value of "http://corp.com" would suffice. However, using such a value would mean that the request URL would not be processed by the RedirectToIdentityProvider override.

My questions are:

What is the reason for having the realm being a subset of the request URL in an MVC application and - more importantly - is there a reason for requiring the same for a non-MVC application?

Could I not just ignore the realm and ensure that the URL includes a slash at the end (in case of no parameters) or before a list of parameters?

Upvotes: 0

Views: 1119

Answers (1)

paullem
paullem

Reputation: 1311

Just some basics: Realm is WIF language for EntityID in metadata. It should be a URI. Which means that it doesn't have to be a URL. Almost all implementations are very tolerant and do accept any string in EntityID.
Returnurl in this case means the url where the browser will go after the user has been authenticated and WIF has set the session cookie. It should be within the app (why else authenticate). If you really do want the application root then the ending slash is a good idea indeed (because of cookiepath). So the usage of Realm (in this particular case) is a mistake.

Upvotes: 2

Related Questions