All*_*ice 6 java cookies asp.net-mvc android forms-authentication
我们有一个.net表单启用auth启用的站点,用户通过我们的Android应用程序中的WebViewClient访问.该站点的一个功能是能够登录和下载某些PDF文件,但是您需要登录才能下载PDF.
我们正在实施shouldOverrideUrlLoading并在满足正确条件时通过以下代码下载pdf.
URL u = new URL(url);
URLConnection conn = u.openConnection();
int contentLength = conn.getContentLength();
DataInputStream stream = new DataInputStream(u.openStream());
byte[] buffer = new byte[contentLength];
stream.readFully(buffer);
stream.close();
DataOutputStream fos = new DataOutputStream(new FileOutputStream("/sdcard/download/file.pdf"));
fos.write(buffer);
fos.flush();
fos.close();
Run Code Online (Sandbox Code Playgroud)
从IIS日志中可以看出,IIS不会考虑将此请求登录并将其重定向到登录页面.
我们需要的是一种下载文件的方法,文件下载请求中保留了auth cookie,但我们不知道如何保留cookie.
对我们来说另一个可行的解决方案是在WebViewClient和Android浏览器之间保留auth cookie.如果我们可以这样做,我们只需通过浏览器中的默认操作打开PDF文件.
编辑:看起来我可以手动设置auth cookie
conn.setRequestProperty("Cookie", "");
Run Code Online (Sandbox Code Playgroud)
现在我只需要弄清楚如何从WebViewClient中读取auth cookie
由于您使用的是ASP.NET Forms身份验证,因此您需要将表单auth cookie从中复制WebView到URLConnection.幸运的是,这很简单.此代码存在于一个实现中shouldOverrideUrlLoading
string url = "http://site/generatePdfBehindFormsAuth";
// get an instance of a cookie manager since it has access to our auth cookie
CookieManager cookieManager = CookieManager.getInstance();
// get the cookie string for the site. This looks something like ".ASPXAUTH=data"
String auth = cookieManager.getCookie(url).toString();
URLConnection conn = (URLConnection)new URL(url).openConnection();
// Set the cookie string to be sent for download. In our case we're just copying the
// entire cookie string from the previous connection, so all values stored in
// cookies are persisted to this new connection. This includes the aspx auth
// cookie, otherwise it would not be authenticated
// when downloading the file.
conn.setRequestProperty("Cookie", auth);
conn.setDoOutput(true);
conn.connect();
// get the filename from the servers response, its typical value is something like:
// attachment; filename="GeneratedPDFFilename.pdf"
String filename = conn.getHeaderField("Content-Disposition").split("\"")[1];
// by default, we'll store the pdf in the external storage directory
String fileRoot = "/sdcard/";
// Complete the download
FileOutputStream f = new FileOutputStream(new File(fileRoot, filename));
InputStream in = conn.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ( (len1 = in.read(buffer)) > 0 )
{
f.write(buffer,0, len1);
}
f.close();
in.close();
Run Code Online (Sandbox Code Playgroud)
注意:有一点要注意的是,你应该不拨打电话给getContentLength您URLConnection.经过4个小时的调试,wireshark最终表明,如果你打电话getContentLength,cookie将被发送给获取内容长度的请求,但是不会为后续请求发送cookie,即使在同一个URLConnection实例上也是如此.也许我天真,这是设计的(文档并没有表明它是按设计),但我无法通过调用setRequestProperty后调用手动设置后续文件请求的cookie getContentLength.如果我试图这样做,我会接近一个力量.
| 归档时间: |
|
| 查看次数: |
3819 次 |
| 最近记录: |