Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to hook into WCF Pipeline to extract credentials for UserNamePasswordValidator from incoming HTTP Request Headers

Tags:

wcf

Can anyone point me to a suitable WCF Extension Point for hooking into the WCF Pipeline to extract credentials for UserNamePasswordValidator from the headers of an incoming HTTP REST Request?

Yes I know about all the funky stunts with Http Handlers etc. you can pull to somehow get Basic/Digest Auth working but since the client I'm working on will be strictly Javascript based I've opted for a simple model where the credentials are passed using two custom headers over an SSL pipe.

like image 383
Oliver Weichhold Avatar asked Aug 12 '11 19:08

Oliver Weichhold


1 Answers

Update: I've managed to improve on this by using the approach described here. While this does not solves the problem described in my question, it gets rid of having to authenticate in a authorization policy since authentication is now handled by a custom AuthenticationManager, bypassing the UsernamePasswordValidator alltogether.

For the time being I've solved the problem by combining Authentication and Authorization in a custom Authorization Policy. I'd still rather find a way to hook into the normal UserNamePasswordValidator authentication scheme because an Authorization Policy is supposed to to Authorization not Authentication.

internal class RESTAuthorizationPolicy : IAuthorizationPolicy
{
  public RESTAuthorizationPolicy()
  {
    Id = Guid.NewGuid().ToString();
    Issuer = ClaimSet.System;
  }

  public bool Evaluate(EvaluationContext evaluationContext, ref object state)
  {
    const String HttpRequestKey = "httpRequest";
    const String UsernameHeaderKey = "x-ms-credentials-username";
    const String PasswordHeaderKey = "x-ms-credentials-password";
    const String IdentitiesKey = "Identities";
    const String PrincipalKey = "Principal";

    // Check if the properties of the context has the identities list 
    if (evaluationContext.Properties.Count > 0 ||
      evaluationContext.Properties.ContainsKey(IdentitiesKey) ||
      !OperationContext.Current.IncomingMessageProperties.ContainsKey(HttpRequestKey))
      return false;

    // get http request
    var httpRequest = (HttpRequestMessageProperty)OperationContext.Current.IncomingMessageProperties[HttpRequestKey];

    // extract credentials
    var username = httpRequest.Headers[UsernameHeaderKey];
    var password = httpRequest.Headers[PasswordHeaderKey];

    // verify credentials complete
    if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
      return false;

    // Get or create the identities list 
    if (!evaluationContext.Properties.ContainsKey(IdentitiesKey))
      evaluationContext.Properties[IdentitiesKey] = new List<IIdentity>();
    var identities = (List<IIdentity>) evaluationContext.Properties[IdentitiesKey];

    // lookup user
    using (var con = ServiceLocator.Current.GetInstance<IDbConnection>())
    {
      using (var userDao = ServiceLocator.Current.GetDao<IUserDao>(con))
      {
        var user = userDao.GetUserByUsernamePassword(username, password);

        ...
like image 60
Oliver Weichhold Avatar answered Nov 09 '22 14:11

Oliver Weichhold