Ejemplo n.º 1
0
    /// <summary>
    /// An authentication response have been received from the web browser.
    /// Check if it's correct
    /// </summary>
    /// <param name="header">Contents from the Authorization header</param>
    /// <param name="realm">Realm that should be authenticated</param>
    /// <param name="httpVerb">GET/POST/PUT/DELETE etc.</param>
    /// <returns>
    /// Authentication object that is stored for the request. A user class or something like that.
    /// </returns>
    /// <exception cref="ArgumentException">if authenticationHeader is invalid</exception>
    /// <exception cref="ArgumentNullException">If any of the parameters is empty or null.</exception>
    public IAuthenticationUser Authenticate(AuthorizationHeader header, string realm, string httpVerb)
    {
      if (header == null)
        throw new ArgumentNullException("header");

      lock (_nonces)
      {
        if (_timer == null)
          _timer = new Timer(ManageNonces, null, 15000, 15000);
      }

      if (!header.Scheme.Equals("digest", StringComparison.OrdinalIgnoreCase))
        return null;

      var parameters = HeaderParameterCollection.Parse(new StringReader(header.Data), ',');
      if (!IsValidNonce(parameters["nonce"]) && !DisableNonceCheck)
        return null;

      // request authentication information
      string username = parameters["username"];
      var user = _userProvider.Lookup(username, realm);
      if (user == null)
        return null;



      // Encode authentication info
      string HA1 = string.IsNullOrEmpty(user.HA1) ? GetHA1(realm, username, user.Password) : user.HA1;

      // encode challenge info
      string A2 = String.Format("{0}:{1}", httpVerb, parameters["uri"]);
      string HA2 = GetMD5HashBinHex2(A2);
      string hashedDigest = Encrypt(HA1, HA2, parameters["qop"],
                                    parameters["nonce"], parameters["nc"], parameters["cnonce"]);

      //validate
      if (parameters["response"] == hashedDigest)
        return user;

      return null;
    }
Ejemplo n.º 2
0
    /// <summary>
    /// An authentication response have been received from the web browser.
    /// Check if it's correct
    /// </summary>
    /// <param name="header">Authorization header</param>
    /// <param name="realm">Realm that should be authenticated</param>
    /// <param name="httpVerb">GET/POST/PUT/DELETE etc.</param>
    /// <returns>Authentication object that is stored for the request. A user class or something like that.</returns>
    /// <exception cref="ArgumentException">if authenticationHeader is invalid</exception>
    /// <exception cref="ArgumentNullException">If any of the paramters is empty or null.</exception>
    public IAuthenticationUser Authenticate(AuthorizationHeader header, string realm, string httpVerb)
    {
      if (header == null)
        throw new ArgumentNullException("realm");
      if (string.IsNullOrEmpty(realm))
        throw new ArgumentNullException("realm");
      if (string.IsNullOrEmpty(httpVerb))
        throw new ArgumentNullException("httpVerb");

      /*
       * To receive authorization, the client sends the userid and password,
          separated by a single colon (":") character, within a base64 [7]
          encoded string in the credentials.*/
      string decoded = Encoding.UTF8.GetString(Convert.FromBase64String(header.Data));
      int pos = decoded.IndexOf(':');
      if (pos == -1)
        throw new BadRequestException("Invalid basic authentication header, failed to find colon.");

      string password = decoded.Substring(pos + 1, decoded.Length - pos - 1);
      string userName = decoded.Substring(0, pos);

      var user = _userProvider.Lookup(userName, realm);
      if (user == null)
        return null;

      if (user.Password == null)
      {
        var ha1 = DigestAuthentication.GetHA1(realm, userName, password);
        if (ha1 != user.HA1)
          return null;
      }
      else
      {
        if (password != user.Password)
          return null;
      }

      return user;
    }