[英]How can I enable NTLM and TLS 1.2 with Xamarin on Android?
I am working with a client app in Xamarin on Android and I need TLS 1.2 and NTLM. 我正在Android的Xamarin中使用客户端应用程序,并且我需要TLS 1.2和NTLM。
So far, I have been using the regular System.Net.HttpClientHandler and it has worked fine - it looks like this: 到目前为止,我一直在使用常规的System.Net.HttpClientHandler,并且运行良好-看起来像这样:
new System.Net.Http.HttpClientHandler()
{
Credentials = credentials
};
But now I have a new customer and I need TLS 1.2. 但是现在我有一个新客户,我需要TLS 1.2。 So I made this code for Android:
因此,我为Android编写了以下代码:
new Xamarin.Android.Net.AndroidClientHandler()
{
Credentials = credentials
};
With the environment variable: 使用环境变量:
XA_HTTP_CLIENT_HANDLER_TYPE=Xamarin.Android.Net.AndroidClientHandler
Now, this AndroidClientHandler works as far as the certificate goes. 现在,这个AndroidClientHandler可以工作到证书为止。 But I also need NTLM to work.
但是我也需要NTLM才能工作。 To me it seems like the AndroidClientHandler only has support for Basic and Digest authentication schemes (see Xamarin.Android.Net.AuthenticationScheme).
在我看来,AndroidClientHandler仅支持基本身份验证和摘要身份验证方案(请参阅Xamarin.Android.Net.AuthenticationScheme)。
I also tried with the ModernHttpClient, but it seems to me that it uses Mono the same way System.Net.Http.HttpClientHandler does, so TLS 1.2 doesn't work there either. 我还尝试了ModernHttpClient,但在我看来它以与System.Net.Http.HttpClientHandler相同的方式使用Mono,因此TLS 1.2也不起作用。
It seems to me that this should be a pretty common case, but I still can't find a relevant example on the web. 在我看来,这应该是很普遍的情况,但是我仍然在网上找不到相关的例子。 I hope I am just missing something obvious.
我希望我只是缺少明显的东西。 How have you guys solved this?
你们如何解决这个问题?
I believe it would be beneficial for you to read through: 我相信这对您阅读有帮助:
https://github.com/xamarin/xamarin-android/blob/0c3597869bc4493895e755bda8a26f778e4fe9e0/src/Mono.Android/Xamarin.Android.Net/AndroidClientHandler.cs#L40-L56 https://github.com/xamarin/xamarin-android/blob/0c3597869bc4493895e755bda8a26f778e4fe9e0/src/Mono.Android/Xamarin.Android.Net/AndroidClientHandler.cs#L40-L56
/// <para>
/// The class supports pre-authentication of requests albeit in a slightly "manual" way. Namely, whenever a request to a server requiring authentication
/// is made and no authentication credentials are provided in the <see cref="PreAuthenticationData"/> property (which is usually the case on the first
/// request), the <see cref="RequestNeedsAuthorization"/> property will return <c>true</c> and the <see cref="RequestedAuthentication"/> property will
/// contain all the authentication information gathered from the server. The application must then fill in the blanks (i.e. the credentials) and re-send
/// the request configured to perform pre-authentication. The reason for this manual process is that the underlying Java HTTP client API supports only a
/// single, VM-wide, authentication handler which cannot be configured to handle credentials for several requests. AndroidClientHandler, therefore, implements
/// the authentication in managed .NET code. Message handler supports both Basic and Digest authentication. If an authentication scheme that's not supported
/// by AndroidClientHandler is requested by the server, the application can provide its own authentication module (<see cref="AuthenticationData"/>,
/// <see cref="PreAuthenticationData"/>) to handle the protocol authorization.</para>
/// <para>AndroidClientHandler also supports requests to servers with "invalid" (e.g. self-signed) SSL certificates. Since this process is a bit convoluted using
/// the Java APIs, AndroidClientHandler defines two ways to handle the situation. First, easier, is to store the necessary certificates (either CA or server certificates)
/// in the <see cref="TrustedCerts"/> collection or, after deriving a custom class from AndroidClientHandler, by overriding one or more methods provided for this purpose
/// (<see cref="ConfigureTrustManagerFactory"/>, <see cref="ConfigureKeyManagerFactory"/> and <see cref="ConfigureKeyStore"/>). The former method should be sufficient
/// for most use cases, the latter allows the application to provide fully customized key store, trust manager and key manager, if needed. Note that the instance of
/// AndroidClientHandler configured to accept an "invalid" certificate from the particular server will most likely fail to validate certificates from other servers (even
/// if they use a certificate with a fully validated trust chain) unless you store the CA certificates from your Android system in <see cref="TrustedCerts"/> along with
/// the self-signed certificate(s).</para>
Basically this says: It supports Basic
and Digest
authentication. 基本上说:支持
Basic
和Digest
身份验证。 If there's an authentication scheme that's not supported in AndroidClientHandler
that is requested by the server, the application can provide it's own authentication module to handle the protocol authorization. 如果服务器请求的
AndroidClientHandler
存在不支持的身份验证方案,则应用程序可以提供其自己的身份验证模块来处理协议授权。
We then can see that the RequestedAuthentication
property will list out the about each scheme supported by the server.: 然后,我们可以看到
RequestedAuthentication
属性将列出服务器支持的每个方案的相关信息::
https://github.com/xamarin/xamarin-android/blob/0c3597869bc4493895e755bda8a26f778e4fe9e0/src/Mono.Android/Xamarin.Android.Net/AndroidClientHandler.cs#L116-L124 https://github.com/xamarin/xamarin-android/blob/0c3597869bc4493895e755bda8a26f778e4fe9e0/src/Mono.Android/Xamarin.Android.Net/AndroidClientHandler.cs#L116-L124
/// <summary>
/// If the website requires authentication, this property will contain data about each scheme supported
/// by the server after the response. Note that unauthorized request will return a valid response - you
/// need to check the status code and and (re)configure AndroidClientHandler instance accordingly by providing
/// both the credentials and the authentication scheme by setting the <see cref="PreAuthenticationData"/>
/// property. If AndroidClientHandler is not able to detect the kind of authentication scheme it will store an
/// instance of <see cref="AuthenticationData"/> with its <see cref="AuthenticationData.Scheme"/> property
/// set to <c>AuthenticationScheme.Unsupported</c> and the application will be responsible for providing an
/// instance of <see cref="IAndroidAuthenticationModule"/> which handles this kind of authorization scheme
/// (<see cref="AuthenticationData.AuthModule"/>
/// </summary>
This tells us that if it returns Unsupported
as our AuthenticationScheme
, then we need to submit our own IAndroidAuthenticationModule
that handles the challenge. 这告诉我们,如果它返回
Unsupported
作为我们的AuthenticationScheme
,那么我们需要提交自己的IAndroidAuthenticationModule
来处理挑战。
Here is an enum of the AuthenticationScheme
: 这是
AuthenticationScheme
的枚举:
https://github.com/xamarin/xamarin-android/blob/24f2aec113857b5c583e14959b9af08ad45b22b1/src/Mono.Android/Xamarin.Android.Net/AuthenticationScheme.cs https://github.com/xamarin/xamarin-android/blob/24f2aec113857b5c583e14959b9af08ad45b22b1/src/Mono.Android/Xamarin.Android.Net/AuthenticationScheme.cs
namespace Xamarin.Android.Net
{
/// <summary>
/// Authentication schemes supported by <see cref="AndroidClientHandler"/>
/// </summary>
public enum AuthenticationScheme
{
/// <summary>
/// Default value used in <see cref="AuthenticationData.Scheme"/>
/// </summary>
None,
/// <summary>
/// <see cref="AndroidClientHandler"/> doesn't support this scheme, the application must provide its own value. See <see cref="AuthenticationData.Scheme"/>
/// </summary>
Unsupported,
/// <summary>
/// The HTTP Basic authentication scheme
/// </summary>
Basic,
/// <summary>
/// The HTTP Digest authentication scheme
/// </summary>
Digest
}
}
Thus we would have to implement a custom IAndroidAuthenticationModule
by extending this interface on your implementation: 因此,我们必须通过在实现上扩展此接口来实现自定义
IAndroidAuthenticationModule
:
https://github.com/xamarin/xamarin-android/blob/24f2aec113857b5c583e14959b9af08ad45b22b1/src/Mono.Android/Xamarin.Android.Net/IAndroidAuthenticationModule.cs https://github.com/xamarin/xamarin-android/blob/24f2aec113857b5c583e14959b9af08ad45b22b1/src/Mono.Android/Xamarin.Android.Net/IAndroidAuthenticationModule.cs
Then you'd pass that implementation into the AuthenticationData.AuthModule
property: 然后,您将该实现传递给
AuthenticationData.AuthModule
属性:
https://github.com/xamarin/xamarin-android/blob/24f2aec113857b5c583e14959b9af08ad45b22b1/src/Mono.Android/Xamarin.Android.Net/AuthenticationData.cs#L37 https://github.com/xamarin/xamarin-android/blob/24f2aec113857b5c583e14959b9af08ad45b22b1/src/Mono.Android/Xamarin.Android.Net/AuthenticationData.cs#L37
You would then pass that into the main client's PreAuthenticationData
property. 然后,您可以将其传递给主客户端的
PreAuthenticationData
属性。
https://github.com/xamarin/xamarin-android/blob/0c3597869bc4493895e755bda8a26f778e4fe9e0/src/Mono.Android/Xamarin.Android.Net/AndroidClientHandler.cs#L113 https://github.com/xamarin/xamarin-android/blob/0c3597869bc4493895e755bda8a26f778e4fe9e0/src/Mono.Android/Xamarin.Android.Net/AndroidClientHandler.cs#L113
I hope this helps! 我希望这有帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.