About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

26 Responses to External authentication with Claims and WS-Federation in MVC4 .NET4.5 Part 4: Single SignOut and Single SignOn

  1. these articles have really helped me get Single sign on/sign out working with my WSFederated MVC4 application. I do have one problem. My logout is not working correctly. I have two websites logged in using the token issued by the STS server, and that works fine. Yet, when I go to log out, I’m only getting logged out of the web application on which I hit the logout button. After I end up at the sign out page on the STS server (I’m using Thinktecure Id Server 2.0 b/c I’m following these articles), the website on which I did not hit the logout button still think it’s logged in. I looked at the source view of the logout page on the STS server, and there is only one <img src embedded in an iFrame, and in this situation, there should be two. That means the STS server isn't tracking the relying parties properly? Or it could be a code/config thing on my end. Any ideas?

    • Andras Nemes says:

      When you sign in using the thinktecture server it registers a cookie with all the applications it is currently tracking. You’ll find an example of that in the blog. Can you verify the contents of that cookie? What does it look like after you have logged in from both web apps?

      • indiecodemonkey says:

        The contents of the cookie are encrypted… so do you mean to verify the contents is just to eye up the encrypted cookie in Fiddler, or is there a better way to look? Also, does it matter that I’m running this locally in VS2012 using IIS Express and just two localhost web sites (aka, http://localhost:portnumer) or do I need to have an actual URL or real IIS web server in order to work with Thinktecture Identity Server correctly?

      • Andras Nemes says:

        No, I meant the other cookie, wsfedsignout. What value do you see there?

  2. indiecodemonkey says:

    here is the the full dump from Fiddler when signing out of one site starting with me clicking the logout button. This dump is from the first site only (http://localhost:55662), I haven’t manually logged out of the the second site yet:

    1. request to localhost/Acccount/Logoff (GET /Account/LogOff HTTP/1.1) has these cookies in the request header:

    – FedAuth=77u/PD94…;
    – FedAuth1=UXhiU1Rh…;(Fiddler displays this cookie as FedAuth1 with a plus symbol “+” next to it)

    2. the request to the Id Svr (GET /idsvr/issue/wsfed?wa=wsignout1.0&wreply=http%3a%2f%2flocalhost%3a55662%2f HTTP/1.1) has these cookies in the request header:
    – idsrvauth=77u/PD94…; wsfedsignout=http://localhost:55662/

    3. the request back to localhost (GET /?wa=wsignoutcleanup1.0 HTTP/1.1) has no cookies in the request or response headers

    Two more questions for you.
    1.Do I need to add all sites that will share the token to the section of web.config for each site?
    2. when I’m trying to share the auth token from the id svr between two sites, is it required of the user to click the “remember me” checkbox on the login page in order for that auth token to be shared, or is that not required?

    Thank again for your time and help with this. Mike

    • indiecodemonkey says:

      Here is the dump from manually logging out of the second site (locahost:55908). Sorry, forgot to include this:

      1. request to locahost:55908/Account/Logoff(GET /Account/LogOff HTTP/1.1) has these cookies in the request header:
      – FedAuth=77u/PD94…;
      – FedAuth1=cEFoUG40…; (Fiddler displays this cookie as FedAuth1 with a plus symbol “+” next to it)

      2. the request to the Id Svr (GET /idsvr/issue/wsfed?wa=wsignout1.0&wreply=http%3a%2f%2flocalhost%3a55908%2f HTTP/1.1) has no cookies in the request or response headers

      3. the next request to the Id Svr (GET /idsvr/account/signin?ReturnUrl=%2fidsvr%2fissue%2fwsfed%3fwa%3dwsignout1.0%26wreply%3dhttp%253a%252f%252flocalhost%253a55908%252f&wa=wsignout1.0&wreply=http%3a%2f%2flocalhost%3a55908%2f HTTP/1.1) has this cookie in the request header:
      – wsfedsignout=http://localhost:55908/

      • Andras Nemes says:

        OK, I see. This requires some deeper debugging as the symptoms may be pointing at an issue within the Thinktecture identity server over which I have no control. The wsfedsignout cookie is supposed to be set at sign-in already. I’ve posted an enquiry on the Thinktecture issue page. I will let you know as soon as I’ve got a reply.

    • Andras Nemes says:

      1.) no, each site using a single sign on server are independent. It is the responsibility of the identity server to hand out the correct cookies to each consuming website
      2.) you need to select the rememberme checkbox to apply single sign-on. If you have siteA and siteB both consuming the login service, and you log on from siteA without applying the RememberMe option, siteB will not be logged on automatically. To make the identity server remember that you were there before you have to choose that checkbox.
      //Andras

  3. indiecodemonkey says:

    Andras. Thank for all the help. If it means anything, I’m running version 2.1, not version 2.0, so not too sure if 2.1 is really a final release or still considered a “beta”. Where is the link to the Thinktecture issue page? Also, are you a contributor to Thinktecture?

    • Andras Nemes says:

      Mike, no, I’m a simple user like you 🙂
      I chose Thinktecture’s solution because it’s for free and is relatively small in order to get started with an identity server. Commercial products, like that of Oracle, are too big for this purpose I think.
      I opened this issue yesterday: https://github.com/thinktecture/Thinktecture.IdentityServer.v2/issues/197
      You may need to have an account on Github.
      If you feel like it you can download their sourcecode and play with it.
      //Andras

      • indiecodemonkey says:

        I do have an account on GitHub. Have you tried to quickly create two web apps yourself and verify what I’ve found before posting to GitHub? If so, I’m assuming you’re seeing the same thing I am?

        I currently work for a company where we need to add single sign on/out to the solution, I was the lucky recipient of this task which lead me to Thinktecture’s IdentityServer. The LocalSTS VS2012 extension is not that great, and I figured we’d eventually need to pick an Id Svr for when we deploy to our test servers.

        Anyhow, I’ll keep an eye on the thread, and if there is anything I can do to help track down the problem, let me know.

        Mike

      • Andras Nemes says:

        Mike, yes, i tried the same thing and saw the same behaviour. I hope the Thinktecture guys can take a look at that soon.
        //Andras

  4. indiecodemonkey says:

    Andras, it looks like Dominic replied a day or two ago with his findings about this. He says he can’t reproduce it, then gives a downloadable Fiddler trace into what was happening when it was working for him. Since we’ve last talked, I had to change direction, and we’re now taking a shared domain authtentication route using FormsAuth and the same machineKey on each of our servers. I’ll try to double check his Fiddler trace against what I was seeing when it was not working for me to see if I can identify the problem, but I might not be able to get around to it any time soon.

    • Andras Nemes says:

      Mike, yes, I’ve seen his reply as well. It might have been an error in the Visual Studio setup that I missed. I’ll redo the entire process as soon as I get the opportunity – it may take a while as this is strictly an off-the-job freetime activity from my side.
      Still I think it was a valuable exercise and it doesn’t change the underlying infrastructure of single signon and single signout.

  5. Bence Molnár says:

    First of all, András, I want to congratulate to your blog. Best .NET how-to source so far 🙂 Is the following scenario supported: I have a web app (e.g. MVC4), an STS (trusted with web app), and a WCF service (also known by the STS – so trusted). I want to call a webservice operation from my web app, of course I want to be authenticated on Webservice as well.

    I’ve implemented the following test solution (Console App calls a web service operation and using localSTS): http://msdn.microsoft.com/en-us/library/jj161104.aspx
    but I get an exception with the following message:
    The channel is configured to use interactive initializer ‘System.ServiceModel.Security.InfocardInteractiveChannelInitializer’, but the channel was Opened without calling DisplayInitializationUI. Call DisplayInitializationUI before calling Open or other methods on this channel.

    I could not found any further relevant information regarding this message. Have you ever done similar scenario?

    Thanks for your reply,

    • Andras Nemes says:

      Szevasz Bence,
      Thanks for your kind words.
      Unfortunately I’m not familiar with WCF too much – I used it before in .NET3.5 but it was before I got going with claims and before I discovered Web API to build web services.
      Can any of these links be of help maybe?

      http://social.msdn.microsoft.com/Forums/vstudio/en-US/16192692-868e-46cb-9bed-1bf60539c823/wcf-routingservice-cannot-pass-token-to-wifsecured-service?forum=wcf

      http://msdn.microsoft.com/en-us/library/bb246060.aspx

      http://code.msdn.microsoft.com/windowsdesktop/WCF-Interactive-Channel-ec0caaa8

      Good luck,
      András

      • Bence Molnár says:

        Thank you for your reply. Actually I’ve catched the original exception of the MSDN sample project (“No version of the CardSpace service was found to be installed on the machine. Please install CardSpace and retry the operation.”). Someone mentioned the same error on Identity and Access tool Reviews section, but no one wrote a solution for that. I keep finding further for the right configuration.

        However I’m interested in Web API as well. Do you restrict your Web API controllers to GET POST PUT DELETE operations, or you have multiple GET operations, and you configure your web api routes to be aware of “actions”, so it looks like an MVC controller? Why is it easier or comfortable to use Web API instead of WCF in an enterprise architecture?

        Köszi,
        Bence

      • Andras Nemes says:

        Web API is a large topic to describe in a comment field, but you can start here: Web Api hom page. You can have multiple Get() actions in the same controller: Get(), Get(int id), Get(RequestArguments args), etc. The same goes for Post(), Put(), etc. As long as you go with the default routes you won’t need to touch them at all.

        I have a series of posts where I build up a model application whose ultimate consuming layer is a Web API web service. It starts here. If you want to jump to the Web API related bits then look at this post.

        Out of the top of my head I can mention the following advantages of Web API compared to WCF:

        • It’s pure HTTP, with HTTP message to and from the service
        • Follows the same architecture as a standard MVC web project – you don’t return ActionResults but HttpResponseMessage object.
        • If you’re familiar with MVC and the basic HTTP verbs then it’s easy to get going with Web API
        • I remember how much headache I got from setting up the configuration file for WCF – there’s nothing like that for the Web API as it behaves the same way as an MVC web app
        • There are no service contracts and funny svc files
        • I also recall that getting rid of the ‘.svc’ bit from the service URI was far from straightforward – no such worries with web API
        • There’s no SOAP overhead in Web API
        • You can mix MVC and Web API in the same project without any hiccups. E.g. Web API controllers can be called from JS files for Ajax operations from MVC views in the same project

        All in all I think web API provides a very modern HTTP based web service solution that can be scaled and deployed the same way as a “normal” MVC web app. If you absolutely must support other protocols such as TCP then WCF is still the way to go. Also, WCF offers some more complex technologies, like Duplex messaging, that are not available in Web API – at least I’m not aware of anything like that.
        //András

  6. Bence Molnár says:

    I’ve already worked with Web API, but never thought to use it instead of wcf services. Maybe it’s time to discover its real power. It was convenient to let svcutil generate proper proxy class for my webservice.

    Have you already had similar kind of project, where you had a front-end web app with outsourced login to an STS, and the front-end called a back-end service, which had to know the identity of caller. (Of course I don’t want to send the userID as a method parameter in every call.) I want to use the power of security token, that was given to the front-end from the STS. I’ve found a couple of samples where the client requested for an ‘ActAs’ token, but all of them used UserName credentials, where the client app asked for login/pass.

    As a clue, I can tell, the back-end service is internal, a trusted subsystem.

    Köszi,
    Bence

    • Andras Nemes says:

      Sort of, yes, not quite the same scenario as the one you’ve described but similar. We send along the necessary claims as key-value pairs to the back-end system, but in our case the back-end is not an internal, trusted subsystem. We also send along the encrypted username / pw combination in the http header so that the back-end can further check the identity of the caller.
      //András

      • Bence Molnár says:

        at least, I could get rid of this token & STS nightmare. I’ve implemented a quite good back-end service using Web API. Now I have to get familiar writing an elegant task-based proxy class for it. Thank you for your answers.

        Köszi,
        Bence

  7. alexandis says:

    Can’t figure out, where these iframe markup generations are from? Cannot manage to receive them, trying to generate manually, but after calling FederatedSignOut all view data is ignored…

    public ActionResult SignOut()
    {
    var replyingPartyLinks = new List();
    replyingPartyLinks.Add(string.Format(“http://localhost:52895?wa={0}”, CleanUpSignOutParameter));

    // Sign out of STS.
    WSFederationAuthenticationModule.FederatedSignOut(new Uri(ConfigurationManager.AppSettings[“IssuerName”]), new Uri(“http://localhost/loginpoint.dev”));

    return View(replyingPartyLinks);
    }

  8. Oleg says:

    Hi Andras!
    Thanks for so brilliant explanation!
    Please, correct me if I`m wrong: there are two ways to approach SSO experience. The first I would call “one cookie” and the flow is: when ws-federation dance starts user don’t click “Remember me” and SAM creates a cookie with default “FedAuth” name for App1 and encrypts it with machine key instead of DPAPI, App2`s SAM happily decrypts the cookie (both apps share the same key) and authenticates user. Pros: no need a passive redirection on App2 side, very well fit for active JS client and REST API (JS client sees 401 and starts authentication), only one cookie, very simple sign out. Cons: apps have to share a machine key, if App1 made some claims transformation rest of applications never know it. The second is standard flow when user clicks “Remember me”, each SAM creates its own cookie. Pros: no need to share a machine key, each app is free to do everything with claims. Cons: WIF on REST API app side has to redirect to ip-sts instead of return 401, sign out is harder.
    What do you think, is the first approach correct?

  9. Neeraj Kathuria says:

    Logout not happening in Internet explorer but works fine in chrome and firefox ,instead my session remain active even when signout page of adfs has come using https://{DNS_name_of_RP_STS}/adfs/ls/?wa=wsignout1.0
    kindly help on this .been in this mess from a very long time

  10. Kiran says:

    Hello Andras,

    I get FedAuth and FedAuth1 cookies from ADFS. However, How can use this cookie to get the user’s identity? The relying party application (ASP.NET) needs it to initialize and get the user details from DB

    Thanks,
    Kiran

  11. Hello Andras,

    I get FedAuth and FedAuth1 cookies from ADFS. However, How can use this cookie to get the user’s identity? The relying party application (ASP.NET) needs it to initialize and get the user details from DB

    Thanks,
    Kiran

Leave a comment

Elliot Balynn's Blog

A directory of wonderful thoughts

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

Bite-size insight on Cyber Security for the not too technical.