Domanda

I am using the asp.net Identity provider with the OWIN middleware with OAuth in my WebAPI application. Using the template and the

https://www.nuget.org/packages/Microsoft.AspNet.Identity.Samples

I have working OAuth on my WebAPI endpoints. However, I am failing to see how to extend this architecture to provide different Token lifetimes for different requests.

For example, my REST API will be consumed by a web app, and a mobile app. I want the mobile app to have a much longer token lifetime than the web application.

In my Startup.Auth.cs file I see the following OAuth configuration-

        // Enable the application to use bearer tokens to authenticate users
        app.UseOAuthBearerTokens(new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/Token"),
            Provider = new ApplicationOAuthProvider<ApplicationUserManager, DirectoryUser, Guid>(PublicClientId),
            AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
            AllowInsecureHttp = true
        });

Is there a way to override this behavior per token request? For example I could expose a "/Token" -> 14 days and a "/DeviceToken" -> 60 days. Is this possible?

È stato utile?

Soluzione

I was able to fix this my inserting the following into my OAuth provider (ApplicationOAuthProvider.cs) from the sample-

   public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        var userManager = context.OwinContext.Get<TUserManager>();

        TUser user = await userManager.FindAsync(context.UserName, context.Password);


        if (user == null)
        {
            context.SetError("invalid_grant", "The user name or password is incorrect.");
            return;
        }


        //if user, expire 60. If Admin, 14 days
        if (userManager.IsInRole(user.Id, "Users"))
        {
            context.Options.AccessTokenExpireTimeSpan = TimeSpan.FromDays(60);
        }
        else {
            context.Options.AccessTokenExpireTimeSpan = TimeSpan.FromDays(14);
        }

        ClaimsIdentity oAuthIdentity = await userManager.CreateIdentityAsync(user,
context.Options.AuthenticationType);
        ClaimsIdentity cookiesIdentity = await userManager.CreateIdentityAsync(user,
            CookieAuthenticationDefaults.AuthenticationType);
        AuthenticationProperties properties = CreateProperties(user.UserName);


        AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
        context.Validated(ticket);
        context.Request.Context.Authentication.SignIn(cookiesIdentity);

    }

Altri suggerimenti

Setting context.Options.AccessTokenExpireTimeSpan will actually change the global value, and affect all requests, that won't work for the original requirement.

The right place is the TokenEndpoint method.

public override Task TokenEndpoint(OAuthTokenEndpointContext context)
{
    ...

    if (isRequestFromDevice)
    {
        context.Properties.ExpiresUtc = DateTime.UtcNow.AddDays(60);
    }

    ...
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top