何处挂钩到WCF管道以从传入的HTTP请求标头中提取UserNamePasswordValidator的凭据

时间:2011-08-12 19:31:52

标签: wcf

有人可以指向一个合适的WCF扩展点,用于挂钩到WCF管道,从传入的HTTP REST请求的标头中提取UserNamePasswordValidator的凭据吗?

是的我知道所有使用Http Handlers等的时髦特技你可以以某种方式获得Basic / Digest Auth工作但是因为我正在研究的客户端将严格基于Javascript我选择了一个简单的模型凭据通过SSL管道使用两个自定义标头传递。

1 个答案:

答案 0 :(得分:4)

更新:我已经通过使用here所述的方法改进了这一点。虽然这不能解决我的问题中描述的问题,但它无需在授权策略中进行身份验证,因为身份验证现在由自定义AuthenticationManager处理,完全绕过UsernamePasswordValidator。

目前我通过在自定义授权策略中组合身份验证和授权来解决问题。我仍然宁愿找到一种方法来挂钩普通的UserNamePasswordValidator身份验证方案,因为授权策略应该授权而不是身份验证。

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);

        ...