[英]How “WebRequest” object determine the “IAuthenticationModule” implementation to use?
我想使用System.Net的AuthenticationManager类来定义WebRequest的基本或承载授权标头。
AuthenticationManager提供了Register方法来添加新模块( IAuthenticationModule的实现)。 这表明可以注册多个模块,并且可以选择其中一个模块。
而且我认为必须通过提供模块“ AuthenticationType”属性中定义的值来完成模块选择。 我在传递给“ WebRequest”的CredentialCache中定义它。
我尝试创建并保存2个模块:
然后,使用以下代码将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.