A Houghton
A Houghton

Reputation: 392

Access username from basic authentication

I have a MVC project with uses Identity. This enables users to sign up to the site and create a profile.

I have a separate WebAPI class to allow Embedded GSM devices to communicate with the server. Users are able to sign up and add many GSM units to their profile. I've had to use a Basic Authentication filter for the embedded GSM devices as it they are unable to cache a token / cookie.

My question is, how do i look up the username of the request within a webAPI controller? i've tried accessing the user with RequestContext.Principal as per suggestions, but it returns null.

Controller:

 [BasicAuthentication]
 public void Post([FromBody]string value)
 {
    // Get username from request for database lookup?
 }

Filter:

public class BasicAuthenticationAttribute : AuthorizationFilterAttribute
{

    public override void OnAuthorization(HttpActionContext actionContext)
    {
        if (actionContext.Request.Headers.Authorization == null)
        {
            actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
        }
        else
        {
            string authenticationToken = actionContext.Request.Headers.Authorization.Parameter;
            string decodedAuthenticationToken = Encoding.UTF8.GetString(Convert.FromBase64String(authenticationToken));
            string[] usernamePasswordArray = decodedAuthenticationToken.Split(':');
            string username = usernamePasswordArray[0];
            string password = usernamePasswordArray[1];

            if (GSMSecurity.Login(username, password))
            {
                Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(username), null);
            }
            else
            {
                actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
            }
        }
    }
}

Edit:

I found the username using :

System.Threading.Thread.CurrentPrincipal;

Upvotes: 1

Views: 2771

Answers (3)

peco
peco

Reputation: 4000

If your controller inherits from System.Web.Http.ApiController you can access the User property:

[BasicAuthentication]
public void Post([FromBody]string value)
{
    var name = User.Identity.Name;
}

In BasicAuthentication, do not forget to set the principal property correctly when signing in:

if (GSMSecurity.Login(username, password))
{
    var currentPrincipal = new GenericPrincipal(new GenericIdentity(username), null);
    actionContext.RequestContext.Principal = currentPrincipal;
    Thread.CurrentPrincipal = currentPrincipal;
    HttpContext.Current.User = currentPrincipal;
}

Upvotes: 1

Nkosi
Nkosi

Reputation: 247451

You should also consider setting the principal on the HttpContext

if (GSMSecurity.Login(username, password)) {
    var principal = new GenericPrincipal(new GenericIdentity(username), null);
    System.Threading.Thread.CurrentPrincipal = principal;
    if (System.Web.HttpContext.Current != null) {
        System.Web.HttpContext.Current.User = principal;
    }
}

And then accessing it via the User property on the ApiController

[BasicAuthentication]
public void Post([FromBody]string value) {
    // Get username from request for database lookup?
    var username = User.Identity.Name;
    //...
}

The framework will extract the user information from the context and associate it with the request context.

Upvotes: 1

Marcus Höglund
Marcus Höglund

Reputation: 16846

You can find the current user in the RequestContext.Principal

Upvotes: 0

Related Questions