NTLM身份验证在多线程应用程序中失败

戴维斯·布罗达(Davis Broda)

我一直在尝试整理一些代码,这些代码将除其他外将文件上传到使用NTLM身份验证的Sharepoint站点。早期版本的代码是单线程的,并且运行良好。他们完全按预期上传了文件,没有丝毫问题。但是,我最终尝试对该应用程序进行多线程处理,以便它可以一次上传许多文件,而同时又负责其余的业务。

但是,当我尝试对代码进行多线程处理时,它每次都会失败,并抛出IndexOutOfBoundsException。这对我诊断问题的真正原因毫无帮助。

如果你想知道,如果我改变了CachedThreadExecutor一个SingleThreadExecutor-迫使代码晒到单个线程的状态-它再次工作正常。

创建执行程序和连接管理器,并构建线程:

class OrderProcessor implements Runnable {

    //Other variables for object

    private final ExecutorService executorService = Executors
            .newCachedThreadPool();
    //      .newSingleThreadExecutor();

    private HttpClientConnectionManager conManager;

    private void setup() {
        //always called before execution of anything else in object
        conManager = new PoolingHttpClientConnectionManager();
    }
    //lots of other code
}

提交线程的实际代码很复杂,因此此版本有所简化,但很重要。

for(Request request : requests){
    //Do other stuff
    simpleSubmitFile(request);
    //Do other stuff
}

这是简化的文件提交方法

public Future<Boolean> simpleSubmitFile(Request request){

        transferer = new SharePointTransferer(extractionRequest, conManager);

    Future<Boolean> future = executorService.submit(transferer);
    return future;
}

SharePointTransferer代码

//actual values scrubbed
private final String USERNAME = "";
private final String PASSWORD = "";
private final String DOMAIN = "";

private final File sourceFile;
private final String destinationAddress;
private final CloseableHttpClient client;


public SharePointTransferer(final Request extractionRequest, HttpClientConnectionManager conManager) {
    super(extractionRequest);
    this.sourceFile = this.extractionRequest.getFile();
    this.destinationAddress = this.extractionRequest.getDestinationAddress();
    this.client = HttpClients.custom()
            .setConnectionManager(conManager).build();
}

public Boolean call() throws Exception {

    String httpAddress = correctSharePointAddress(destinationAddress);
    HttpPut put = new HttpPut(httpAddress + sourceFile.getName());

    // construct basic request
    put.setEntity(new FileEntity(sourceFile));
    HttpClientContext context = HttpClientContext.create();

    // set credentials for the SharePoint login
    CredentialsProvider credProvider = new BasicCredentialsProvider();
    credProvider.setCredentials(AuthScope.ANY, new NTCredentials(USERNAME,
            PASSWORD, "", DOMAIN));
    context.setCredentialsProvider(credProvider); 
    // execute request
    try {
        HttpResponse response = client.execute(put, context);
        logger.info("response code was: "
                + response.getStatusLine().getStatusCode());
        if (response.getStatusLine().getStatusCode() != 201) {
            throw new FileTransferException(
                    "Could not upload file. Http response code 201 expected."
                            + "\nActual status code: "
                            + response.getStatusLine().getStatusCode());
        }
    } catch (ClientProtocolException e) {
        throw new FileTransferException(
                "Exception Occurred while Transferring file "
                        + sourceFile.getName(), e);
    } catch (IOException e) {
        throw new FileTransferException(
                "Exception Occurred while Transferring file "
                        + sourceFile.getName(), e);
    }finally{
        logger.info("deleting source file: " + sourceFile.getName());
        sourceFile.delete();
        client.close();
    }

    logger.info("successfully transfered file: "+sourceFile.getName());
    return true;
}

如果我提交多个文件,则对所有文件都会引发完全相同的异常。跟踪在异常堆栈跟踪下面

2015-04-16 11:49:26 ERROR OrderProcessor:224 - error processing file: FILE_NAME_SCRUBBED
PACKAGE_SCRUBBED.FileProcessingException: Could not process file: FILE_NAME_SCRUBBED
        at PACKAGE_SCRUBBED.OrderProcessor.finishProcessingOrder(OrderProcessor.java:223)
        at PACKAGE_SCRUBBED.OrderProcessor.run(OrderProcessor.java:124)
        at PACKAGE_SCRUBBED.FileTransferDaemon.process(FileTransferDaemon.java:48)
        at PACKAGE_SCRUBBED.FileTransferDaemon.start(FileTransferDaemon.java:83)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.commons.daemon.support.DaemonLoader.start(DaemonLoader.java:243)
Caused by: java.util.concurrent.ExecutionException: java.lang.ArrayIndexOutOfBoundsException: 41
        at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222)
        at java.util.concurrent.FutureTask.get(FutureTask.java:83)
        at PACKAGE_SCRUBBED.OrderProcessor.finishProcessingOrder(OrderProcessor.java:208)
        ... 8 more
Caused by: java.lang.ArrayIndexOutOfBoundsException: 41
        at org.apache.http.impl.auth.NTLMEngineImpl$NTLMMessage.addByte(NTLMEngineImpl.java:924)
        at org.apache.http.impl.auth.NTLMEngineImpl$NTLMMessage.addUShort(NTLMEngineImpl.java:946)
        at org.apache.http.impl.auth.NTLMEngineImpl$Type1Message.getResponse(NTLMEngineImpl.java:1052)
        at org.apache.http.impl.auth.NTLMEngineImpl.getType1Message(NTLMEngineImpl.java:148)
        at org.apache.http.impl.auth.NTLMEngineImpl.generateType1Msg(NTLMEngineImpl.java:1641)
        at org.apache.http.impl.auth.NTLMScheme.authenticate(NTLMScheme.java:139)
        at org.apache.http.impl.auth.AuthSchemeBase.authenticate(AuthSchemeBase.java:138)
        at org.apache.http.impl.auth.HttpAuthenticator.doAuth(HttpAuthenticator.java:239)
        at org.apache.http.impl.auth.HttpAuthenticator.generateAuthResponse(HttpAuthenticator.java:202)
        at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:262)
        at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
        at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
        at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
        at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
        at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
        at PACKAGE_SCRUBBED.SharePointTransferer.call(SharePointTransferer.java:74)
        at PACKAGE_SCRUBBED.SharePointTransferer.call(SharePointTransferer.java:1)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:138)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:662)

如果有人能找出导致此问题的原因,我将不胜感激。

编辑:我设法找到一种解决方法,可以为我解决此问题,但仍然希望您能确切了解正在发生的情况。

德里克·冲

这是一个错误,已在httpclient版本4.5.2中解决

http://www.apache.org/dist/httpcomponents/httpclient/RELEASE_NOTES-4.5.x.txt

版本4.5.2

变更日志:

  • [HTTPCLIENT-1715] NTLMEngineImpl#Type1Message不是线程安全的,但声明为常量。由Olivier Lafontaine和Gary Gregory贡献

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

weblogic中的Web应用程序部署失败:代理身份验证失败

来自分类Dev

Django应用程序的DB用户在AWS中身份验证失败

来自分类Dev

属性更新后,在露营Web应用程序中身份验证失败

来自分类Dev

银光应用程序中的Pentaho身份验证方法。

来自分类Dev

EJB中的应用程序与容器身份验证

来自分类Dev

Golang WebSocket应用程序中的身份验证

来自分类Dev

UWP应用程序中的身份验证

来自分类Dev

Cordova / AngularJS应用程序中的Facebook身份验证

来自分类Dev

EJB中的应用程序与容器身份验证

来自分类Dev

$ injector:modulerr:AngularJS应用程序中的身份验证

来自分类Dev

Django 在“身份验证”应用程序中缺少迁移

来自分类Dev

应用程序的身份验证概念

来自分类Dev

Alfresco NTLM 身份验证失败

来自分类Dev

为什么Google身份验证令牌刷新最近在Android的Azure移动应用程序SDK中仍然失败

来自分类Dev

由于逻辑应用程序中的交叉API连接,导致Office365 API连接身份验证/授权失败

来自分类Dev

多线程应用程序中的QTimer

来自分类Dev

ncurses在多线程应用程序中

来自分类Dev

Azure移动应用程序中的应用程序身份验证。如何?

来自分类Dev

Windows Phone 8应用程序上的Live Connect SDK是否“身份验证失败”?

来自分类Dev

Bluemix样本应用程序失败,并显示“无法针对MCA进行身份验证”

来自分类Dev

从应用程序服务到Azure Key Vault的身份验证失败

来自分类Dev

启用身份验证后,Flask-restful应用程序失败

来自分类Dev

在同一MVC应用程序中同时使用OWIN Cookie身份验证和Windows身份验证

来自分类Dev

如何在多线程应用程序中存储线程

来自分类Dev

在flutter应用程序中的Firebase身份验证中合并两个uid

来自分类Dev

对单个操作而非整个应用程序使用Windows身份验证进行身份验证

来自分类Dev

Tomcat身份验证和特定的Web应用程序身份验证

来自分类Dev

托管WCF应用程序IIS身份验证

来自分类Dev

Azure本机应用程序通用身份验证

Related 相关文章

  1. 1

    weblogic中的Web应用程序部署失败:代理身份验证失败

  2. 2

    Django应用程序的DB用户在AWS中身份验证失败

  3. 3

    属性更新后,在露营Web应用程序中身份验证失败

  4. 4

    银光应用程序中的Pentaho身份验证方法。

  5. 5

    EJB中的应用程序与容器身份验证

  6. 6

    Golang WebSocket应用程序中的身份验证

  7. 7

    UWP应用程序中的身份验证

  8. 8

    Cordova / AngularJS应用程序中的Facebook身份验证

  9. 9

    EJB中的应用程序与容器身份验证

  10. 10

    $ injector:modulerr:AngularJS应用程序中的身份验证

  11. 11

    Django 在“身份验证”应用程序中缺少迁移

  12. 12

    应用程序的身份验证概念

  13. 13

    Alfresco NTLM 身份验证失败

  14. 14

    为什么Google身份验证令牌刷新最近在Android的Azure移动应用程序SDK中仍然失败

  15. 15

    由于逻辑应用程序中的交叉API连接,导致Office365 API连接身份验证/授权失败

  16. 16

    多线程应用程序中的QTimer

  17. 17

    ncurses在多线程应用程序中

  18. 18

    Azure移动应用程序中的应用程序身份验证。如何?

  19. 19

    Windows Phone 8应用程序上的Live Connect SDK是否“身份验证失败”?

  20. 20

    Bluemix样本应用程序失败,并显示“无法针对MCA进行身份验证”

  21. 21

    从应用程序服务到Azure Key Vault的身份验证失败

  22. 22

    启用身份验证后,Flask-restful应用程序失败

  23. 23

    在同一MVC应用程序中同时使用OWIN Cookie身份验证和Windows身份验证

  24. 24

    如何在多线程应用程序中存储线程

  25. 25

    在flutter应用程序中的Firebase身份验证中合并两个uid

  26. 26

    对单个操作而非整个应用程序使用Windows身份验证进行身份验证

  27. 27

    Tomcat身份验证和特定的Web应用程序身份验证

  28. 28

    托管WCF应用程序IIS身份验证

  29. 29

    Azure本机应用程序通用身份验证

热门标签

归档