+-
Android Windows身份验证
不推荐使用DefaultHttpHandler,HttpURLConnection不支持NTLM,并且NTLM似乎是ASP.NET MCV网站唯一受到良好支持的协议.那么,还剩下什么呢?

在我们的业务中,我们使用Microsoft.我们使用Microsoft登录,我们的网络邮件由Microsoft完成,我们的平板电脑应用程序是Android …

目前我正在开发一个需要连接到ASP.NET实体框架Web界面的项目.此Web界面托管在IIS上,使用NTLM作为提供程序配置Windows身份验证.

我正在制作的应用程序必须访问此Web界面.所以,我问用户他们的用户名和密码,并希望登录web界面.但是,Android根本不支持NTLM.我一直在四处寻找,但似乎这种组合相当罕见.我想知道,我的选择是什么?

我被允许搞乱任何事情.唯一的要求是用户使用他们的Microsoft帐户登录,我们不希望使用价格过高的Xamarin.你会推荐什么?

最佳答案
好的,我做的第一件事就是导入 JCIFS库.它是从该链接下载的jar.

我需要做的下一件事是将JCIFSEngine类和NTLMSchemeFactory类导入到项目中.

最后这个方法构建你的HTTPClient:

//I know it is deprecated but there is no other way to implement NTLM thus far.
    private static DefaultHttpClient setupHttpClient (String username, String password) {
        DefaultHttpClient httpclient = new DefaultHttpClient();
        // register ntlm auth scheme
        httpclient.getAuthSchemes().register("ntlm", new NTLMSchemeFactory());
        httpclient.getCredentialsProvider().setCredentials(
                // Limit the credentials only to the specified domain and port
                new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),
                // Specify credentials, most of the time only user/pass is needed
                new NTCredentials(username, password, "", "")
        );
        return httpclient;
    }

我的连接是通过Retrofit完成的,所以我只需使用以下行附加此HTTPClient进行改造:

retrofitAdapterBuilder.setClient(new ApacheClient(setupHttpClient(username, password)));

到目前为止,这对我有用 – 尽管Android没有本机支持这一点非常糟糕.

编辑:添加Okhttp实现.这是一个旧类,我们不再使用它,因为我们决定放弃NTLM支持,但它曾经工作过.请记住,我们连接到可以进行基本/ windows / azure身份验证的服务器,因此我们需要进行多次检查,您可能不需要这些检查.

首先创建一个实现okhttp的Authenticator接口的类.然后在authenticate()方法中执行以下操作:

    @Override
public Request authenticate(Route route, okhttp3.Response response) throws IOException {
    if (response == null || response.headers() == null || response.headers().toString().isEmpty()) {
        return null;
    }

    final List<String> authHeaders = response.headers().values("WWW-Authenticate");

    if (authHeaders.contains("NTLM")) {
        return response.request().newBuilder().header("Authorization", "NTLM " + mNtlmInitialChallenge).build();
    } else if (checkIsBasicAuth(authHeaders)) {
        String credentials = mUsername + ":" + mPassword;
        final String basic = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
        return response.request().newBuilder().header("Authorization", basic).build();
    }

    if (mChallengeSent) {
        return null;
    } else {
        mChallengeSent = true;
        String ntlmFinalChallenge = null;
        try {
            ntlmFinalChallenge = mNtlmEngine.generateType3Msg(mUsername, mPassword, mDomain, "android-device", authHeaders.get(0).substring(5));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response.request().newBuilder().header("Authorization", "NTLM " + ntlmFinalChallenge).build();
    }
}

要生成mNtlmInitialChallenge,请创建以下方法:

    private String getInitialNtlmChallenge() {
    String initialChallenge = null;
    try {
        initialChallenge = mNtlmEngine.generateType1Msg(null, null);
    } catch (Exception e) {
        e.printStackTrace();
    }

    return initialChallenge;
}

我手动从JCIFS库复制的mNtlmEngine类,因此我可以删除依赖项.

一些说明:

>代码不是最干净的,因为这是一个POC.
>是的我们使用了可怕的mVariable表示法,我们不再使用它了.
>您将不得不玩这个实现,直到它适合您.
>要将验证器附加到okhttp,只需执行client.authenticator(new NtlmAuthenticator(username,password,“”));
>您可能需要实施一些失败机制.

点击查看更多相关文章

转载注明原文:Android Windows身份验证 - 乐贴网