2

Been fighting with trying to extract the bearer token after authenticating against ADFS...

I have an API that will accept a Bearer token and validate it against ADFS.

I have a Web Forms (.net 4.5.1) app that I am modifying to use ADFS 3.0 to implement SSO authentication. So far it authenticates properly against the ADFS server (presents to ADFS login page and logs in).

My issue is that I now want the WebForms app to call my Web API using the bearer token I hope is present somewhere in the returned response from ADFS, but where is it and how can I retrieve it?

I tried using the SecurityTokenValidated and the SecurityTokenReceived WsFederationAuthenticationNotifications events as in the following:

public void ConfigureAuth(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions());

            app.UseWsFederationAuthentication(
                new WsFederationAuthenticationOptions
                {
                    AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType, // "WS-Fed Auth (Primary)",
                    Wtrealm = realm,
                    MetadataAddress = metadata,
                    Notifications = new WsFederationAuthenticationNotifications
                    {
                        AuthenticationFailed = context =>
                        {
                            context.HandleResponse();
                            context.Response.Redirect("Home/Error?message=" + context.Exception.Message);
                            return Task.FromResult(0);
                        },

                        SecurityTokenValidated = token =>
                            {
                                Token = token.AuthenticationTicket.ToString();
                                return Task.FromResult(0);
                            },

                        SecurityTokenReceived = token =>
                        {
                            Token = token.ToString();
                            return Task.FromResult(0);
                        }
                    }
                });
}

But I can't find the token anywhere in the objects returned by the events... What am I missing?

Thanks for all help.

zukanta
  • 2,691
  • 2
  • 19
  • 25

1 Answers1

1

The token you receive as part of your web sign on is not suitable for calling a web API, for two reasons: A) the audience of the token is the webform app, while the web API should only accept tokens where the audience correspond to the web API - doing otherwise will open you up to man in the middle attacks and B) the token you get form ADFS is a SAML token, which can be pretty big hence unsuitable to be included an in HTTP header (the canonical way of including a bearer token for calling a web API). If you decide to ignore the above and use that token anyway - in Acquiring an Access token by using JWT used for AzureBearerAuthentication you can find the code necessary to extract the bits of the incoming token. It works with both openid connect and oauth middleware.

Community
  • 1
  • 1
vibronet
  • 7,364
  • 2
  • 19
  • 21
  • Thanks for you help but I'm confused here. I first tested with a Windows client that authenticated against ADFS and sent it's bearer token to my API, which then revalidates it using OWIN and that seemed the way to go according to examples out there... How does that method need to change to do things properly when a WebForms App replaces the Windows Client? (I would like my API to not have to care about what is calling it) – zukanta Nov 17 '15 at 15:22
  • The API does not care indeed. The difference is that while in the Windows client you obtained a token specifically for the API, with the web app (doesn't matter if forms or mvc) you are trying to repurpose for the API a token you obtained for signing in the web app. Tokens aren't fungible, they are like bank checks - one check written for me cannot be cashed by you and vice versa – vibronet Nov 17 '15 at 16:13
  • Vittorio, I am a fan of your work. Super glad you took the time to anwer my question. Now I have looked at many of your articles during my research and many many others but couldn't find an example for On-Premise ADFS/webforms/WCF API (not a Web API per se)... If I shouldn't send the token from my web app to my API, how's the API supposed to authenticate its caller? – zukanta Nov 17 '15 at 20:00
  • Far too kind. My pleasure! Adfs 2 and 3 offer no modern authentication flow for a web app to access a web API. Adfs in windows server 2016, currently in preview, offer all the flows that azure ad makes available for that purpose: code grant, openid connect hybrid, onbehalfof. – vibronet Nov 17 '15 at 20:26
  • So I guess with the current state of technology (ADFS 3), I have no choice but to proceed with my plan of building/retrieving a bearer token in my webforms app and send it to the API? – zukanta Nov 17 '15 at 20:37