簡體   English   中英

“ WebRequest”對象如何確定要使用的“ IAuthenticationModule”實現?

[英]How “WebRequest” object determine the “IAuthenticationModule” implementation to use?

我想使用System.Net的AuthenticationManager類來定義WebRequest的基本或承載授權標頭。

AuthenticationManager提供了Register方法來添加新模塊( IAuthenticationModule的實現)。 這表明可以注冊多個模塊,並且可以選擇其中一個模塊。

而且我認為必須通過提供模塊“ AuthenticationType”屬性中定義的值來完成模塊選擇。 我在傳遞給“ WebRequest”的CredentialCache中定義它。

我嘗試創建並保存2個模塊:

  • 重新定義基本授權(以禁用預身份驗證)的模塊(我使用Microsoft文檔的示例: 此處
  • 授權載體模塊。

然后,使用以下代碼將2個模塊保存在AuthenticationManager中:

// I remove the previous basic module 
AuthenticationManager.Unregister("Basic");

// And i register my 2 modules
AuthenticationManager.Register(customBasicModule);
AuthenticationManager.Register(customBearerModule);

但這似乎總是第一個被調用的記錄模塊。

我的測試代碼:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://example.com");

var cache = new CredentialCache();
cache.Add(new Uri("http://example.com"), "Basic", new NetworkCredential("user", "password"));

request.Method = "GET";    
request.Credentials = cache;

HttpWebResponse response = (HttpWebResponse)request.GetResponse();

我希望調用“ customBasicModule”,因為我在此模塊的屬性“ AuthenticationType”和“ CredentialCache”中都指示了“ Basic”。 但是,如果我先注冊“ customBearerModule”,它將被調用。

模塊:

public class BasicAuthenticationModule : IAuthenticationModule
{
    private const string BASIC_SCHEME = "Basic";

    public bool CanPreAuthenticate => false;

    public string AuthenticationType => BASIC_SCHEME;

    public Authorization Authenticate(string challenge, WebRequest request, ICredentials credentials)
    {
        // Some code to get Basic from ICredentials
    }

    public Authorization PreAuthenticate(WebRequest request, ICredentials credentials)
    {
        return null;
    }
}

public class BearerAuthenticationModule : IAuthenticationModule
{
    private const string BEARER_SCHEME = "Bearer";

    public bool CanPreAuthenticate => false;

    public string AuthenticationType => BEARER_SCHEME;

    public Authorization Authenticate(string challenge, WebRequest request, ICredentials credentials)
    {
        // Some code to get Bearer from ICredentials
    }

    public Authorization PreAuthenticate(WebRequest request, ICredentials credentials)
    {
        return null;
    }
}

AuthenticationManager將始終按照注冊時的順序調用所有IAuthenticationModule,直到一個返回非null授權實例為止。

想法是,每個IAuthenticationModule實現都應根據其能力驗證質詢參數,如果不匹配,則返回null。

所以您的實現應該看起來像

public class BasicAuthenticationModule : IAuthenticationModule
{
    private const string BASIC_SCHEME = "Basic";

    public bool CanPreAuthenticate => false;

    public string AuthenticationType => BASIC_SCHEME;

    public Authorization Authenticate(string challenge, WebRequest request, ICredentials credentials)
    {
        if (!challenge.StartWith(BASIC_SCHEME)) return null;
        // Some code to get Basic from ICredentials
    }

    public Authorization PreAuthenticate(WebRequest request, ICredentials credentials)
    {
        return null;
    }
}

public class BearerAuthenticationModule : IAuthenticationModule
{
    private const string BEARER_SCHEME = "Bearer";

    public bool CanPreAuthenticate => false;

    public string AuthenticationType => BEARER_SCHEME;

    public Authorization Authenticate(string challenge, WebRequest request, ICredentials credentials)
    {
        if (!challenge.StartWith(BEARER_SCHEME)) return null;
        // Some code to get Bearer from ICredentials
    }

    public Authorization PreAuthenticate(WebRequest request, ICredentials credentials)
    {
        return null;
    }
}

還請注意,挑戰是服務器在第一個未經授權的響應(401)之后由服務器發送的WWW-Authenticate標頭的內容,該響應與您在CredentialCache中編寫的“基本”無關

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM