Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.net Web API. How to retrieve user properties (user Id) from access token? Request handler code based on current user/token

Let's say you have a .net Web API server for a user based application. The user logs into the application with a username and password which is sent to the server and the app is given an access token back.

Now the app wants to show pieces of user information (stored on the server in a DB). So it makes the http request to server and includes the access token in the header.

How do you restrict that the server will only send back to the application the relevent information for that particular user and no one else's information.

Is there a way, when I receive their username and password and am creating a token to send back, to associate their userId with that token? So now when I get a request to something like /GetUserFoodPreferences, I can just get the userId from the token and query my db based on that id.

Is this the correct approach?

like image 591
user3489727 Avatar asked Jan 02 '15 00:01

user3489727


People also ask

Does access token have user info?

An access token is a tiny piece of code that contains a large amount of data. Information about the user, permissions, groups, and timeframes is embedded within one token that passes from a server to a user's device.

How can I get access token authorization code?

To get a new access token, use the refresh token as you would an authorization code, but with a grant_type value of refresh_token and a refresh_token parameter that holds the contents of the refresh token. The type of grant being used. To exchange a refresh token for an access token, use refresh_token .

How do I get authentication token for REST API?

You use the POST operation on the api/get_token element to request your unique token that is required to authenticate the REST API requests. , and click Profile. Then, click Show token.


2 Answers

I have a similar issue which I solve by creating a customized OAuthProvider.

public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
{
    private readonly IYourLoginLogic _loginLogic;

    /// <summary>
    /// Constructor
    /// </summary>
    public ApplicationOAuthProvider(IYourLoginLogic loginLogic)
    {
        _loginLogic = loginLogic;
    }

    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
        return Task.FromResult<object>(null);
    }

    /// <summary>
    /// Login the user with username and password.
    /// </summary>
    /// <param name="context">OAuthGrantResourceOwnerCredentialsContext</param>
    /// <returns>Not used</returns>
    public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        bool loginRst = _loginLogic.Login(context.UserName, context.Password);

        if(!loginRst)
        {
            context.SetError("invalid_grant", "The user name or password is incorrect.");
        }
        else
        {
            var identity = new ClaimsIdentity(context.Options.AuthenticationType);
            identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
            identity.AddClaim(new Claim("role", "user"));
            context.Validated(identity);
        }

        return Task.FromResult<object>(null);
    }

This way, the username will be included in the token returned to client. When the client send the request back with the token, you can get the username from the request's context as below:

public class CustomizedAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(HttpActionContext actionContext)
    {
        base.OnAuthorization(actionContext);

        string username = actionContext.RequestContext.Principal.Identity.Name;
        // do something with the username
    }
}

You will need to use the CustomizedAuthrize attribute for your controllers or actions you want to protect.

In my case, it is like:

[CustomizedAuthorize]
public sealed class MyController : ApiController {......}
like image 182
Yang Zhang Avatar answered Oct 10 '22 15:10

Yang Zhang


Storing the userid, or some other kind of id connected to that user in a cookie would be the most common way. You can then inspect that cookie (Request.Cookies["name"];) for the id to confirm the user.

EDIT: If of course you are using the API Controller and authenticating your user correctly you can use:

HttpContext.Current.User.Identity.GetUserId();

NOTE : don't forget to import Microsoft.AspNet.Identity library.

like image 37
RattyLaa Avatar answered Oct 10 '22 15:10

RattyLaa