none
Using bearer tokens (ASP.NET Identity 2.0) with WCF Data Services RRS feed

  • Question

  • I'm trying to combine WCF Data Service (5.6) with ASP.NET Identity 2.0 because I like SecurityStampValidator.

    I successfully enabled issuing tokens with

                OAuthOptions = new OAuthAuthorizationServerOptions
                {
                    TokenEndpointPath = new PathString("/Token"),
                    Provider = new ApplicationOAuthProvider(PublicClientId, UserManagerFactory),
                    AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
                    AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
                    AllowInsecureHttp = true
                };

    // Enable the application to use bearer tokens to authenticate users
    app.UseOAuthBearerTokens(OAuthOptions);

    And I can successfully retrieve HttpContexxt.Current.User.Identity in my QueryInterceptor.

    However, the security stamp is not verified.

    The usual

    // Enable the application to use a cookie to store information for the signed in user
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
     Provider = new CookieAuthenticationProvider
            {
               OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<UserManager<ApplicationUser>, CrossClientSite.Models.ApplicationUser>(TimeSpan.FromSeconds(5), (manager, user) => user.GenerateUserIdentityAsync(manager)),
            }
    });

    does not work with bearer authentication OAuthBearerAuthenticationProvider.OnValidateIdentity takes different context. And even if I just try

    app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
        {
            Provider = new OAuthBearerAuthenticationProvider
            {
                OnValidateIdentity = async (c) => { c.Rejected(); },
            }
        });

    hoping to get "401 Unauthorized" or, at least, HttpContext.Current.Request.IsAuthenticated to be false in the interceptor, it does not work (no error is returned and the request is authenticated and user info is taken from the token).

    I did manage to use HttpContext.Current.GetOwinContext() and retrieve and compare security stamp inside the interceptor, but I suspect that this is too late. After all, if I include Authorization header, the Context is authenticated and I do have User.Identity.Name, so, it does go through ASP.NET Identity pipeline.

    I do suspect that AuthorizeAttribute on ApiController's classes do something that I have to do manually in the sub-class of DataService<T> (EntityFrameworkDataService<T> in my case because I use EF 6), but I fail to find it.

    I did read about future directions of WCF Data Services and its replacement with Web API, but it seems to be in early pre-release stages.

    Any pointers on using bearer tokens with WCF Data Services will be greatly appreciated!


    Thursday, April 17, 2014 6:57 PM

Answers

  • Fred,

    thank you for pointing it out. Unfortunately, descriptions from your first link kind of don't work anymore with ASP.NET Identity 2.0. Moreover, my approach was similar to the one, recommended for OData with OAuth2 authentication.

    But in attempt to save some time for the next reader, here is how to make it work:

    1. Read http://stackoverflow.com/questions/19552991/how-do-you-reject-a-katana-bearer-tokens-identity Pay attention to the comments to the answer. The key phrase: "UseOAuthBearerTokens will register Bearer authentication middleware and authorization server middleware into the pipeline."

    2. So, based on that phrase, comment out app.UseOAuthBearerTokens(OAuthOptions);

    Once you did that, the c.Rejected() starts to behave. But to implement something similar to SecurityStampValidator you need access to UserManager from your OnValidateIdentity handler. Calling context.OwinContext.GetUserManager to get the user manager will return null.

    3. Read http://blog.iteedee.com/2014/03/asp-net-identity-2-0-cookie-token-authentication/ and notice the use of CreatePerOwinContext

    This will save you from the whole UserManagerFactory as seen in the default Web Application SPA template in Visual Studio 2013

    4. Compare context.OwinContext.GetUserManager<>().GetSecurityStampAsync() with context.Ticket.Identity.FindFirstValue(Constants.DefaultSecurityStampClaimType) and you have your own security stamp validator.

    I don't know yet the purpose of two args of the SecurityStampValidator.OnValidateIdentity.

    After doing the above, I could successfully use HttpContext.Current.User.Identity in my query interceptors.

    Bonus: OData in WebAPI 2 may not be as bad as I thought (read: http://msdn.microsoft.com/en-us/magazine/dn201742.aspx)

    Bonus 2: if you add WebApi NuGet packages, your custom OnValidateIdentity might be called twice.

    Thank you for your time!

    Friday, April 18, 2014 6:35 PM

All replies

  • Hello,

    WCF Data Services does not implement any kind of authentication of its own, but rather relies on the authentication provisions of the data service host. This means that the service assumes that any request that it receives has already been authenticated by the network host and that the host has correctly identified the principle for the request appropriately via the interfaces provided by WCF Data Services.

    You can see it here:

    http://msdn.microsoft.com/en-us/library/dd728284(v=vs.110).aspx

    So that is why no error is returned and the request is authenticated and user info is taken from the token.

    If you want the WCF Data Services has such a function, you can post this feature to:

    https://data.uservoice.com/forums/72027-wcf-data-services-feature-suggestions

    To let the team know, so that it may be supported in future release.

    Regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    Friday, April 18, 2014 2:38 AM
    Moderator
  • Fred,

    thank you for pointing it out. Unfortunately, descriptions from your first link kind of don't work anymore with ASP.NET Identity 2.0. Moreover, my approach was similar to the one, recommended for OData with OAuth2 authentication.

    But in attempt to save some time for the next reader, here is how to make it work:

    1. Read http://stackoverflow.com/questions/19552991/how-do-you-reject-a-katana-bearer-tokens-identity Pay attention to the comments to the answer. The key phrase: "UseOAuthBearerTokens will register Bearer authentication middleware and authorization server middleware into the pipeline."

    2. So, based on that phrase, comment out app.UseOAuthBearerTokens(OAuthOptions);

    Once you did that, the c.Rejected() starts to behave. But to implement something similar to SecurityStampValidator you need access to UserManager from your OnValidateIdentity handler. Calling context.OwinContext.GetUserManager to get the user manager will return null.

    3. Read http://blog.iteedee.com/2014/03/asp-net-identity-2-0-cookie-token-authentication/ and notice the use of CreatePerOwinContext

    This will save you from the whole UserManagerFactory as seen in the default Web Application SPA template in Visual Studio 2013

    4. Compare context.OwinContext.GetUserManager<>().GetSecurityStampAsync() with context.Ticket.Identity.FindFirstValue(Constants.DefaultSecurityStampClaimType) and you have your own security stamp validator.

    I don't know yet the purpose of two args of the SecurityStampValidator.OnValidateIdentity.

    After doing the above, I could successfully use HttpContext.Current.User.Identity in my query interceptors.

    Bonus: OData in WebAPI 2 may not be as bad as I thought (read: http://msdn.microsoft.com/en-us/magazine/dn201742.aspx)

    Bonus 2: if you add WebApi NuGet packages, your custom OnValidateIdentity might be called twice.

    Thank you for your time!

    Friday, April 18, 2014 6:35 PM
  • Kirill, thank you for following up. I was on the same case, your results are very helpful.
    Tuesday, April 22, 2014 7:53 AM