web-dev-qa-db-ja.com

ヘッダーから基本認証資格情報を取得するにはどうすればよいですか?

基本認証を使用するユーザー認証メカニズムの簡単なテストを作成しようとしています。ヘッダーから資格情報を取得するにはどうすればよいですか?

string authorizationHeader = this.HttpContext.Request.Headers["Authorization"];

ここからどこに行きますか?いくつかのチュートリアルがありますが、私は.NETと認証を初めて使用します。回答の中で、何をして何をしているのかを段階的に正確に説明してください。

45
user4041873

私のブログから:

これは、これがどのように機能するかを詳細に説明します:

手順1-基本認証について

基本認証を使用すると、ヘッダーがHTTPリクエストに追加され、次のようになります。

許可:基本QWxhZGRpbjpvcGVuIHNlc2FtZQ ==

ソース: http://en.wikipedia.org/wiki/Basic_access_authentication

「QWxhZGRpbjpvcGVuIHNlc2FtZQ ==」は、Base64でエンコードされた「username:password」にすぎません( http://en.wikipedia.org/wiki/Base64 )。 .NET(C#)のヘッダーおよびその他のHTTPプロパティにアクセスするには、現在のHttpコンテキストにアクセスする必要があります。

HttpContext httpContext = HttpContext.Current;

これはSystem.Web名前空間で見つけることができます。

ステップ2-ヘッダーの取得

HttpContextにあるのは承認ヘッダーだけではありません。ヘッダーにアクセスするには、リクエストから取得する必要があります。

string authHeader = this.httpContext.Request.Headers["Authorization"];

コードをデバッグすると、そのヘッダーの内容は次のようになります。

基本QWxhZGRpbjpvcGVuIHNlc2FtZQ ==

ステップ3-ヘッダーの確認

ヘッダーを既に抽出しました。実行する必要があることがいくつかあります。

  1. ヘッダーがnullでないことを確認してください
  2. 認証/認証メカニズムが実際に「基本」であることを確認してください

そのようです:

if (authHeader != null && authHeader.StartsWith("Basic")) {
    //Extract credentials
} else {
    //Handle what happens if that isn't the case
    throw new Exception("The authorization header is either empty or isn't Basic.");
}

これで、データを抽出するものがあることを確認できました。

ステップ4-資格情報の抽出

「Basic」サブストリングの削除

これで、ユーザー名とパスワードの値の取得を試みることができます。まず、「Basic」サブストリングを取り除く必要があります。次のようにできます:

string encodedUsernamePassword = authHeader.Substring("Basic ".Length).Trim();

詳細については、次のリンクを参照してください。

  1. http://msdn.Microsoft.com/en-us/library/system.string.substring(v = vs.110).aspx
  2. http://msdn.Microsoft.com/en-us/library/t97s7bs3(v = vs.110).aspx

Base64のデコード

次に、Base64から文字列にデコードする必要があります。

//the coding should be iso or you could use ASCII and UTF-8 decoder
Encoding encoding = Encoding.GetEncoding("iso-8859-1");
string usernamePassword = encoding.GetString(Convert.FromBase64String(encodedUsernamePassword));

これで、ユーザー名とパスワードは次の形式になります。

username:password

ユーザー名の分割:パスワード

ユーザー名とパスワードを取得するには、「:」のインデックスを取得するだけです。

int seperatorIndex = usernamePassword.IndexOf(':');

username = usernamePassword.Substring(0, seperatorIndex);
password = usernamePassword.Substring(seperatorIndex + 1);

これで、これらのデータをテストに使用できます。幸運を!

PS:最終的なコードは次のようになります。

HttpContext httpContext = HttpContext.Current;

string authHeader = this.httpContext.Request.Headers["Authorization"];

if (authHeader != null && authHeader.StartsWith("Basic")) {
    string encodedUsernamePassword = authHeader.Substring("Basic ".Length).Trim();
    Encoding encoding = Encoding.GetEncoding("iso-8859-1");
    string usernamePassword = encoding.GetString(Convert.FromBase64String(encodedUsernamePassword));

    int seperatorIndex = usernamePassword.IndexOf(':');

    var username = usernamePassword.Substring(0, seperatorIndex);
    var password = usernamePassword.Substring(seperatorIndex + 1);
} else {
    //Handle what happens if that isn't the case
    throw new Exception("The authorization header is either empty or isn't Basic.");
}
170
Dawid O

@DawidOからの素晴らしい回答。

HttpContextがある場合、基本的な認証資格情報を抽出し、.NETマジックに依存するだけの場合、これも機能します。

  public static void StartListener() {
    using (var hl = new HttpListener()) {
      hl.Prefixes.Add("http://+:8008/");
      hl.AuthenticationSchemes = AuthenticationSchemes.Basic;
      hl.Start();
      Console.WriteLine("Listening...");
      while (true) {
        var hlc = hl.GetContext();

        var hlbi = (HttpListenerBasicIdentity)hlc.User.Identity;
        Console.WriteLine(hlbi.Name);
        Console.WriteLine(hlbi.Password);

        //TODO: validater user
        //TODO: take action
      }
    }
  }
4
sobelito

文字列を使用すると、安全性が低下する可能性があります。 GCによって選択されるまで、メモリに残ります。

1
Anup Thakare