Search code examples
c#oauth-2.0authorizationasp.net-web-api2owin

Is it possible to access the clientId from an authToken (RequestContext) in WebAPI 2


I have implemented Oauth with my WebAPI 2 application and there are several applications access the API. Once authenticated, after making a request whilst sending across the auth token, I can access the user as follows:

var currentUser = RequestContext.Principal;

When logging in, the clientId was set as follows:

context.OwinContext.Set<AppClient>("oauth:client", client);

Is there a way to access that client Id? I want to restrict certain actions / controllers to certain clients. Is there a way to do this?

I have tried getting the client as follows:

var client = Request.GetOwinContext().Get<string>("oauth:client");

but this is not working.


Solution

  • When logging in you can set a claim on the identity in the GrantResourceOwnerCredentials

    identity.AddClaim(new Claim("oauth:client", client));
    

    That way it is available once the User Principal's Identity has be set.

    You can create an extension method to extract it conveniently

    public static class GenericIdentityExtensions {
        const string ClientIdentifier = "oauth:client";
    
        /// <summary>
        /// Set the client id claim
        /// </summary>
        /// <param name="identity"></param>
        /// <returns></returns>
        public static bool SetClientId(this IIdentity identity, string clientId) {
            if (identity != null) {
                var claimsIdentity = identity as ClaimsIdentity;
                if (claimsIdentity != null) {
                    claimsIdentity.AddClaim(new Claim(ClientIdentifier, clientId));
                    return true;
                }
            }
            return false;
        }        
    
        /// <summary>
        /// Return the client id claim
        /// </summary>
        /// <param name="identity"></param>
        /// <returns></returns>
        public static string GetClientId(this IIdentity identity) {
            if (identity != null) {
                var claimsIdentity = identity as ClaimsIdentity;
                if (claimsIdentity != null) {
                    return claimsIdentity.FindFirstOrEmpty(ClientIdentifier);
                }
            }
            return string.Empty;
        }
        /// <summary>
        /// Retrieves the first claim that is matched by the specified type if it exists, String.Empty otherwise.
        /// </summary>
        public static string FindFirstOrEmpty(this ClaimsIdentity identity, string claimType) {
            var claim = identity.FindFirst(claimType);
            return claim == null ? string.Empty : claim.Value;
        }
    }
    

    So now once you have the the user principal you can extract the client id from the claims.

    var currentUser = RequestContext.Principal;
    var client = currentUser.Identity.GetClientId();