0

I have a problem in generating token with Owin and Oauth2 (In Mvc Project). Some of my application users have subset users and they want to login to their panel without knowing their password.

Problem:

public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
{
    public ApplicationOAuthProvider2(string publicClientId)
    {
    }

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        //get current user
        var user1 = HttpContext.Current.User;//null
        var user2 = Thread.CurrentPrincipal;//null
        var user3 = context.OwinContext.Authentication.User;//null

    }
}

My OauthOptions:

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

I can not get the current user in OauthProvider. Is there any solution?

4
  • What do you mean by subset users? Commented Jul 3, 2017 at 7:00
  • I mean a user is parent of some other users. Commented Jul 3, 2017 at 7:03
  • But only parent users have a password? Do parent users need to login for the subset users? Commented Jul 3, 2017 at 7:04
  • yes, every user has his own password.but parent user dont know children password. Commented Jul 3, 2017 at 7:06

1 Answer 1

1

It's logical that the current user is null in GrantResourceOwnerCredentials. That's the point where you'll need to validate the credentials, username / password and set the user in the context.

It seems that you want to impersonate the (child)user. This is what you can do. Please note that this is pseudo code. Read the comments:

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
    // assume that context contains username, password and childusername

    var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();            

    //  First validate the credentials of the parent:
    var appUser = await userManager.FindAsync(context.UserName, context.Password);

    // Check if user is valid AND user is parent of childUserName

    // now find the user to impersonate
    appUser = await userManager.FindByNameAsync(context.ChildUserName);

    // If found, appuser is child user:

    // you may add information so you know that the user was impersonated by a parent user.
    var propertyDictionary = new Dictionary<string, string> { { "userName", appUser.UserName }, { "parent", context.UserName } };
    var properties = new AuthenticationProperties(propertyDictionary);

    var oAuthIdentity = await appUser.GenerateUserIdentityAsync(userManager);
    var ticket = new AuthenticationTicket(oAuthIdentity, properties);

    // Token is validated.
    context.Validated(ticket);

    // parent is now child user.
 }

This is just the idea to impersonate the child. You'll need to add the flow for normal login: where child logs in or parent didn't specify a childUserName.

-- update --

Based on your comment I've updated the answer.

The access_token is selfcontained. You cannot change or update it. So you cannot switch the current subset user without having the parent user to login again. Since you cannot get a new or other access_token with the current access_token.

So there are two options: use the flow described above or add claims to the parent user. This will not set the current user, but you can add the current subset user in the url.

You can also add an additional header that contains the subsetUser. In that case you won't need to check the url.

If you want to add claim(s), I suggest you use ApplicationUser like the template:

public class ApplicationUser : IdentityUser
{
    public List<string> SubsetUsers { get; set; }

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);

        // Add custom user claims here
        userIdentity.AddClaim(new Claim("subsetUsers", string.Join(",", SubsetUsers)));

        return userIdentity;
    }
}

Or something like this. I do not know how and where you persist the subset users.

To get the list of available subset users, assuming the subset user is from the url:

user = (System.Security.Claims.ClaimsIdentity)User.Identity;
var subset = user.FindFirstValue("subsetUsers").Split(',');
if(subset.Contains(UserNameFromUrl))
    IsValid = true;

You cannot use the default AuthorizeAttribute to validate this, but you can add your own filter.

Sign up to request clarification or add additional context in comments.

1 Comment

Parent user logged in and has bearer token then he wants to login to children. i should take info from that token

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.