简体   繁体   English

如何在Android上使用Xamarin启用NTLM和TLS 1.2?

[英]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. 基本上说:支持BasicDigest身份验证。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM