Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the default OAuth AccessTokenFormat implementation in OWIN for IIS host?

Web API 2 OWIN Bearer token authentication - AccessTokenFormat null?

The default /Token endpoints works fine and I could get token from there, but I need to use the AccessTokenFormat.Protect method on a ticket to generate accessToken for externalLogin.

Basically my implementation is pretty much the same as this one, and I encountered the same problem of the AccessTokenFormat is null. From the documentation it says:

The data format used to protect the information contained in the access token. If not provided by the application the default data protection provider depends on the host server. The SystemWeb host on IIS will use ASP.NET machine key data protection, and HttpListener and other self-hosted servers will use DPAPI data protection. If a different access token provider or format is assigned, a compatible instance must be assigned to the OAuthBearerAuthenticationOptions.AccessTokenProvider or OAuthBearerAuthenticationOptions.AccessTokenFormat property of the resource server.

It looks to me that if the AccessTokenFormat is not assigned, the host would provide a basic implementation for it. But I don't see it works here. Is there a way I could find the default implementation of the ISecureDataFormatAccessTokenFormat and assign it to the variable manually?

Or does anyone have other ideas how to solves this?

UPDATE: I get the source code for katana and find the OAuthAuthorizationServerMiddleware class, from the source code I could see the following code:

if (Options.AccessTokenFormat == null)
        {
            IDataProtector dataProtecter = app.CreateDataProtector(
                typeof(OAuthAuthorizationServerMiddleware).Namespace,
                "Access_Token", "v1");
            Options.AccessTokenFormat = new TicketDataFormat(dataProtecter);
        }

In my Startup.Auth, here is my code:

     static Startup()
    {
        PublicClientId = "self";

        UserManagerFactory = () => new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));

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

        OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
        OAuthBearerOptions.AccessTokenFormat = OAuthOptions.AccessTokenFormat;
        OAuthBearerOptions.AccessTokenProvider = OAuthOptions.AccessTokenProvider;
        OAuthBearerOptions.AuthenticationMode = OAuthOptions.AuthenticationMode;
        OAuthBearerOptions.AuthenticationType = OAuthOptions.AuthenticationType;
        OAuthBearerOptions.Description = OAuthOptions.Description;

        OAuthBearerOptions.Provider = new CustomBearerAuthenticationProvider();
        OAuthBearerOptions.SystemClock = OAuthOptions.SystemClock;
    }

    public void ConfigureAuth(IAppBuilder app)
    {
        // Configure the db context and user manager to use a single instance per request
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);


        app.UseOAuthAuthorizationServer(OAuthOptions);

        // Enable the application to use bearer tokens to authenticate users
        app.UseOAuthBearerTokens(OAuthOptions);
        // Enable the application to use a cookie to store information for the signed in user
        // and to use a cookie to temporarily store information about a user logging in with a third party login provider
        // Configure the sign in cookie
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            Provider = new CookieAuthenticationProvider
            {
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                    validateInterval: TimeSpan.FromMinutes(30),
                    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
            }
        });
        // Use a cookie to temporarily store information about a user logging in with a third party login provider
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

}

I also have the following in WebApiConfig

// Web API configuration and services
        // Configure Web API to use only bearer token authentication.
        config.SuppressDefaultHostAuthentication();
        config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

I'm not sure why app.UseOAuthAuthorizationServer(OAuthOptions); is not setting the accessTokenFormat

like image 473
Wei Avatar asked May 14 '14 17:05

Wei


People also ask

What is bearer token authentication in Web API?

Bearer token. A particular type of access token, with the property that anyone can use the token. In other words, a client doesn't need a cryptographic key or other secret to use a bearer token. For that reason, bearer tokens should only be used over a HTTPS, and should have relatively short expiration times.

What is OAuthAuthorizationServerOptions?

OAuthAuthorizationServerOptions() Creates an instance of authorization server options with default values.

How does Web API validate token?

Token-based authentication is a process where the user sends his credential to the server, server will validate the user details and generate a token which is sent as response to the users, and user store the token in client side, so client do further HTTP call using this token which can be added to the header and ...


1 Answers

I'm not sure why it's not setting it correctly, but I pull out the code and assign to it my self. Here's my final working code looks like:

      public void ConfigureAuth(IAppBuilder app)
    {
        // Configure the db context and user manager to use a single instance per request
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);


        OAuthOptions = new OAuthAuthorizationServerOptions()
        {
            TokenEndpointPath = new PathString("/Token"),
            Provider = new ApplicationOAuthProvider(PublicClientId, UserManagerFactory),
            AccessTokenFormat = new TicketDataFormat(app.CreateDataProtector(
               typeof(OAuthAuthorizationServerMiddleware).Namespace,
               "Access_Token", "v1")),
            RefreshTokenFormat = new TicketDataFormat(app.CreateDataProtector(
                typeof(OAuthAuthorizationServerMiddleware).Namespace,
                "Refresh_Token", "v1")),
            AccessTokenProvider = new AuthenticationTokenProvider(),
            RefreshTokenProvider = new AuthenticationTokenProvider(),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
            AllowInsecureHttp = true
        };

        OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
        OAuthBearerOptions.AccessTokenFormat = OAuthOptions.AccessTokenFormat;
        OAuthBearerOptions.AccessTokenProvider = OAuthOptions.AccessTokenProvider;
        OAuthBearerOptions.AuthenticationMode = OAuthOptions.AuthenticationMode;
        OAuthBearerOptions.AuthenticationType = OAuthOptions.AuthenticationType;
        OAuthBearerOptions.Description = OAuthOptions.Description;

        OAuthBearerOptions.Provider = new CustomBearerAuthenticationProvider();
        OAuthBearerOptions.SystemClock = OAuthOptions.SystemClock;

        app.UseOAuthAuthorizationServer(OAuthOptions);
        app.UseOAuthBearerAuthentication(OAuthBearerOptions);

        // Enable the application to use a cookie to store information for the signed in user
        // and to use a cookie to temporarily store information about a user logging in with a third party login provider
        // Configure the sign in cookie
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            Provider = new CookieAuthenticationProvider
            {
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                    validateInterval: TimeSpan.FromMinutes(30),
                    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
            }
        });
        // Use a cookie to temporarily store information about a user logging in with a third party login provider
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
        }
like image 176
Wei Avatar answered Oct 27 '22 00:10

Wei