Upload file to Secured FTP in ASP.NET - asp.net

I want to upload files to FTPS and SFTP. My code is currently using FtpWebRequest object to upload to FTP. What changes or class should I use to upload to FTP, FTPS and SFTP servers?

SFTP is not a built-in protocol for .NET, you'll have to use a third-party library, like SharpSSH; however, FTP and FTPS are. There are a number of third-party libraries both commercial and OpenSource (SSH Factory for .NET , Rebex SFTP for .NET/.NET CF, SharpSSH - A Secure Shell (SSH) library for .NET, Compare SFTP (SSH File Transfer Protocol) components for .NET (C#, VB.NET) - SecureBlackbox®) and you'll need to do some research to determine which one will best suit your needs.
Here's a sample console app I wrote that does FTP and FTPS using the .NET Framework's FtpWebRequest:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
namespace FtpSslTest
{
class Program
{
static void Main(string[] args)
{
string server = null;
do
{
Console.Write("Enter the server to connect to: ");
server = Console.ReadLine();
} while (IsServerValid(server) == false);
UriBuilder ftpUrl = new UriBuilder("ftp", server);
bool useSsl = GetYesNo("Use SSL?");
bool allowInvalidCertificate = false;
if (useSsl)
{
allowInvalidCertificate = GetYesNo("Allow invalid SSL certificate?");
}
bool useActiveFtp = GetYesNo("Use Active FTP?");
string path = null;
do
{
Console.Write("Enter the path: ");
path = Console.ReadLine();
} while (IsValidPath(path) == false);
ftpUrl.Path = path;
Console.Write("Enter the user name: ");
string userName = Console.ReadLine();
string password = GetPasswordFromUser();
Console.WriteLine();
Console.WriteLine();
List<string> directoryContents = null;
try
{
directoryContents = DisplayDirectoryContents(ftpUrl.ToString(), userName, password, useSsl, allowInvalidCertificate, useActiveFtp, false);
}
catch (WebException ex)
{
Console.WriteLine("The request failed with status {0}. {1}", ex.Status, ex.Message);
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.ToString());
}
if (directoryContents != null && directoryContents.Count == 1)
{
bool saveFile = GetYesNo(string.Format("Download the file {0} from {1}? ", directoryContents[0], server));
if (saveFile)
{
string savePath = null;
do
{
Console.Write("Enter a local path to save the file: ");
savePath = Console.ReadLine();
} while (!IsValidPath(savePath));
try
{
DownloadFileFromServer(ftpUrl.ToString(), userName, password, useSsl, allowInvalidCertificate, useActiveFtp, savePath);
}
catch (WebException ex)
{
Console.WriteLine("The request failed with status {0}. {1}", ex.Status, ex.Message);
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.ToString());
}
}
}
}
private static bool GetYesNo(string message)
{
Console.Write("{0} (Y/N) ", message);
string input = null;
do
{
input = new string(Console.ReadKey(true).KeyChar, 1);
} while (!input.Equals("Y", StringComparison.CurrentCultureIgnoreCase) && !input.Equals("N", StringComparison.CurrentCultureIgnoreCase));
Console.WriteLine(input);
return input.Equals("Y", StringComparison.CurrentCultureIgnoreCase);
}
private static bool IsValidPath(string path)
{
bool validPath = false;
validPath = path != null && path.IndexOfAny(Path.GetInvalidPathChars()) < 0;
if (validPath == false)
{
Console.WriteLine("You must enter a valid path.");
}
return validPath;
}
private static bool IsServerValid(string server)
{
bool serverValid = false;
if (!string.IsNullOrEmpty(server))
{
try
{
IPAddress[] addresses = Dns.GetHostAddresses(server);
serverValid = (addresses != null && addresses.Length > 0);
}
catch (SocketException ex)
{
Console.WriteLine(ex.Message);
}
}
else
{
Console.WriteLine("You must provide a valid host name or IP address.");
}
return serverValid;
}
private static string GetPasswordFromUser()
{
Console.Write("Enter the password: ");
StringBuilder password = new StringBuilder();
char readChar = '\x00';
while (readChar != '\r')
{
readChar = Console.ReadKey(true).KeyChar;
if (readChar == '\b')
{
if (password.Length > 0)
{
password.Length--;
Console.Write("\b \b");
}
}
else if (readChar != '\r')
{
Console.Write('*');
password.Append(readChar);
}
}
return password.ToString();
}
public static bool ServicePointManager_ServerCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
bool allowCertificate = true;
if (sslPolicyErrors != SslPolicyErrors.None)
{
Console.WriteLine("Accepting the certificate with errors:");
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) == SslPolicyErrors.RemoteCertificateNameMismatch)
{
Console.WriteLine("\tThe certificate subject {0} does not match.", certificate.Subject);
}
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) == SslPolicyErrors.RemoteCertificateChainErrors)
{
Console.WriteLine("\tThe certificate chain has the following errors:");
foreach (X509ChainStatus chainStatus in chain.ChainStatus)
{
Console.WriteLine("\t\t{0}", chainStatus.StatusInformation);
if (chainStatus.Status == X509ChainStatusFlags.Revoked)
{
allowCertificate = false;
}
}
}
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) == SslPolicyErrors.RemoteCertificateNotAvailable)
{
Console.WriteLine("No certificate available.");
allowCertificate = false;
}
Console.WriteLine();
}
return allowCertificate;
}
private static FtpWebRequest CreateFtpWebRequest(string ftpUrl, string userName, string password, bool useSsl, bool allowInvalidCertificate, bool useActiveFtp)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpUrl);
request.Credentials = new NetworkCredential(userName, password);
if (useSsl)
{
request.EnableSsl = true;
if (allowInvalidCertificate)
{
ServicePointManager.ServerCertificateValidationCallback = ServicePointManager_ServerCertificateValidationCallback;
}
else
{
ServicePointManager.ServerCertificateValidationCallback = null;
}
}
request.UsePassive = !useActiveFtp;
return request;
}
private static List<string> DisplayDirectoryContents(string ftpUrl, string userName, string password, bool useSsl, bool allowInvalidCertificate, bool useActiveFtp, bool detailed)
{
List<string> directoryContents = new List<string>();
FtpWebRequest request = CreateFtpWebRequest(ftpUrl, userName, password, useSsl, allowInvalidCertificate, useActiveFtp);
if (detailed)
{
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
}
else
{
request.Method = WebRequestMethods.Ftp.ListDirectory;
}
Stopwatch stopwatch = new Stopwatch();
long bytesReceived = 0;
stopwatch.Start();
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
Console.WriteLine(response.BannerMessage);
Console.WriteLine(response.WelcomeMessage);
Console.WriteLine(response.StatusDescription);
using (Stream responseStream = response.GetResponseStream())
using (StreamReader responseStreamReader = new StreamReader(responseStream))
{
while (!responseStreamReader.EndOfStream)
{
string directoryEntry = responseStreamReader.ReadLine();
Console.WriteLine(directoryEntry);
directoryContents.Add(directoryEntry);
}
}
Console.WriteLine(response.ExitMessage);
}
stopwatch.Stop();
Console.WriteLine();
Console.WriteLine("{0} bytes received in {1} seconds.", bytesReceived, stopwatch.ElapsedMilliseconds / 1000.0);
return directoryContents;
}
private static List<string> ListDirectoryContents(string ftpUrl, string userName, string password, bool useSsl, bool allowInvalidCertificate, bool useActiveFtp, bool detailed)
{
List<string> directoryContents = new List<string>();
FtpWebRequest request = CreateFtpWebRequest(ftpUrl, userName, password, useSsl, allowInvalidCertificate, useActiveFtp);
if (detailed)
{
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
}
else
{
request.Method = WebRequestMethods.Ftp.ListDirectory;
}
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
using (StreamReader responseStreamReader = new StreamReader(responseStream))
{
while (!responseStreamReader.EndOfStream)
{
string directoryEntry = responseStreamReader.ReadLine();
directoryContents.Add(directoryEntry);
}
}
}
return directoryContents;
}
private static void DownloadFileFromServer(string ftpUrl, string userName, string password, bool useSsl, bool allowInvalidCertificate, bool useActiveFtp, string savePath)
{
FtpWebRequest request = CreateFtpWebRequest(ftpUrl, userName, password, useSsl, allowInvalidCertificate, useActiveFtp);
request.Method = WebRequestMethods.Ftp.DownloadFile;
Stopwatch stopwatch = new Stopwatch();
long bytesReceived = 0;
stopwatch.Start();
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
Console.WriteLine(response.BannerMessage);
Console.WriteLine(response.WelcomeMessage);
Console.WriteLine(response.StatusDescription);
using (Stream responseStream = response.GetResponseStream())
using (FileStream saveFileStream = File.OpenWrite(savePath))
{
// Note that this method call requires .NET 4.0 or higher. If using an earlier version it will need to be replaced.
responseStream.CopyTo(saveFileStream);
}
bytesReceived = response.ContentLength;
Console.WriteLine(response.ExitMessage);
}
stopwatch.Stop();
Console.WriteLine();
Console.WriteLine("{0} bytes received in {1} seconds.", bytesReceived, stopwatch.ElapsedMilliseconds / 1000.0);
}
private static void UploadFileToServer(string ftpUrl, string userName, string password, bool useSsl, bool allowInvalidCertificate, bool useActiveFtp, string filePath)
{
FtpWebRequest request = CreateFtpWebRequest(ftpUrl, userName, password, useSsl, allowInvalidCertificate, useActiveFtp);
request.Method = WebRequestMethods.Ftp.UploadFile;
Stopwatch stopwatch = new Stopwatch();
long bytesReceived = 0;
stopwatch.Start();
long bytesSent = 0;
using (Stream requestStream = request.GetRequestStream())
using (FileStream uploadFileStream = File.OpenRead(filePath))
{
// Note that this method call requires .NET 4.0 or higher. If using an earlier version it will need to be replaced.
uploadFileStream.CopyTo(requestStream);
bytesSent = uploadFileStream.Position;
}
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
Console.WriteLine(response.BannerMessage);
Console.WriteLine(response.WelcomeMessage);
Console.WriteLine(response.StatusDescription);
bytesReceived = response.ContentLength;
Console.WriteLine(response.ExitMessage);
}
stopwatch.Stop();
Console.WriteLine();
Console.WriteLine("{0} bytes sent in {1} seconds.", bytesSent, stopwatch.ElapsedMilliseconds / 1000.0);
}
}
}
You can also get detailed tracing for debugging purposes by using the following config file with the sample application:
<?xml version="1.0"?>
<configuration>
<system.diagnostics>
<sources>
<source name="System.Net">
<listeners>
<add name="TraceFile"/>
</listeners>
</source>
<source name="System.Net.Sockets" maxdatasize="1024">
<listeners>
<add name="TraceFile"/>
</listeners>
</source>
</sources>
<sharedListeners>
<add name="TraceFile" type="System.Diagnostics.TextWriterTraceListener" initializeData="System.Net.trace.log" traceOutputOptions="DateTime"/>
</sharedListeners>
<switches>
<add name="System.Net" value="Verbose"/>
<!--<add name="System.Net.Sockets" value="Verbose"/>-->
</switches>
<trace autoflush="true" />
</system.diagnostics>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>

I use this library to download and upload files over sftp. Should be samples of how to use the library if you download the source. http://sshnet.codeplex.com

Related

Problem to execute https connection from a servlet: http 404 error occours

From my Tomcat's servlet I execute an https connection to an external servlet.
This is the code:
HttpsURLConnection hpcon = null;
try {
URL url = new URL(surl);
hpcon = (HttpsURLConnection) url.openConnection();
hpcon.setRequestMethod("POST");
hpcon.setDoInput(true);
hpcon.setDoOutput(true);
hpcon.setUseCaches(false);
hpcon.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
OutputStreamWriter wr = new OutputStreamWriter(hpcon.getOutputStream());
String params = "user=" + URLEncoder.encode(user, "UTF-8");
params += "&psswd=" + URLEncoder.encode(pssw, "UTF-8");
params += "&metodo=" + URLEncoder.encode(metodo, "UTF-8");
wr.write(params);
wr.flush();
wr.close();
hpcon.connect();
int respCode = hpcon.getResponseCode();
if (respCode == 200) {
BufferedReader br = new BufferedReader(new InputStreamReader(hpcon.getInputStream()));
String response = "";
String output;
while ((output = br.readLine()) != null) {
response += output;
}
if (response.indexOf("-") > 0) {
response = "-12";
System.out.println("ret = -12 - response = " + response);
}
br.close();
} else {
ret = "-11";
System.out.println("ret = -11 - respCode = " + respCode);
}
} catch (Exception e) {
e.printStackTrace();
ret = "-10";
System.out.println("ret = -10");
} finally {
if (hpcon != null) {
hpcon.disconnect();
}
}
Where surl is the full url of a servlet present in a different domain and the three parameters are read from a db table (the third really is fixed and is the operation that is make by the external servlet).
The result is:
ret = -11 - respCode = 404
Before make the connection I turn off the certificate's verify using the above code:
try {
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
} catch (Exception e) {
e.printStackTrace();
}
If I execute the same servlet manually from a browser with parameters in get mode all run correctly.
I tried to execute it on my code using the get mode and passing the three parameters in query string, but the result is the same.
How can I do to resolve the problem?

HttpModule Web Api

I'm trying to get an auth basic on my web api. I've written a simple HttpModule to check it
public class BasicAuth : IHttpModule
{
SqlConnection con = new SqlConnection(WebConfigurationManager.ConnectionStrings["Connection"].ConnectionString);
private const string Realm = "MyRealm";
public void Init(HttpApplication context)
{
// Register event handlers
context.AuthorizeRequest += new EventHandler(OnApplicationAuthenticateRequest);
context.EndRequest += new EventHandler(OnApplicationEndRequest);
}
private static void SetPrincipal(IPrincipal principal)
{
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
}
private bool CheckPassword(string username, string password)
{
var parameters = new DynamicParameters();
parameters.Add("#UserName", username);
parameters.Add("#Password", password);
con.Open();
try
{
var query = //query to db to check username and password
return query.Count() == 1 ? true : false;
}
catch
{
return false;
}
finally
{
con.Close();
}
}
private bool AuthenticateUser(string credentials)
{
try
{
var encoding = Encoding.GetEncoding("iso-8859-1");
credentials = encoding.GetString(Convert.FromBase64String(credentials));
int separator = credentials.IndexOf(':');
string name = credentials.Substring(0, separator);
string password = credentials.Substring(separator + 1);
if (CheckPassword(name, password))
{
var identity = new GenericIdentity(name);
SetPrincipal(new GenericPrincipal(identity, null));
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
}
private void OnApplicationAuthenticateRequest(object sender, EventArgs e)
{
var authHeader = request.Headers["Authorization"];
if (authHeader != null)
{
var authHeaderVal = AuthenticationHeaderValue.Parse(authHeader);
// RFC 2617 sec 1.2, "scheme" name is case-insensitive
if (authHeaderVal.Scheme.Equals("basic",
StringComparison.OrdinalIgnoreCase) &&
authHeaderVal.Parameter != null)
{
if (AuthenticateUser(authHeaderVal.Parameter))
{
//user is authenticated
}
else
{
HttpContext.Current.Response.StatusCode = 401;
}
}
else
{
HttpContext.Current.Response.StatusCode = 401;
}
}
catch
{
HttpContext.Current.Response.StatusCode = 401;
}
}
private static void OnApplicationEndRequest(object sender, EventArgs e)
{
var response = HttpContext.Current.Response;
if (response.StatusCode == 401)
{
response.Headers.Add("WWW-Authenticate",
string.Format("Basic realm=\"{0}\"", Realm));
}
}
public void Dispose()
{
}
}
well, this code works pretty well, except the fact it asks for basic auth even on controller I don't put the [Authorize] tag on. And when it occurs, it gives the right data back.
Let me explain:
My HistoryController has [Authorize] attribute, to make a POST request I have to send Header auth to get data, if I don't do it, I receive 401 status code and a custom error.
My HomeController doesn't have [Authorize] attribute, if i make a get request on my homepage, the browser popups the authentication request, but if I hit Cancel it shows my home page. (The page is sent back with 401 error, checked with fiddler).
What am I doing wrong?

Windows Phone 8 http post file upload timeout

I am developing a Windows phone 8 app that needs to upload photos to amazon s3 storage. However, I find that this is impossible since the HttpClient time out after about 60 seconds regardless of what timeout setting I use.
Is there really no way to upload large files from Windows Phone?
BackgroundTransferRequest is useless since it cannot send the neccessary metadata with file uploads.
I use this code (which times out):
using (var httpClient = new HttpClient())
{
httpClient.Timeout = TimeSpan.FromMinutes(30);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, m_uploadUrl);
httpContent.Headers.Add("Keep-Alive", "true");
request.Content = httpContent; // 3-5 Mb file
response = await httpClient.SendAsync(request);
statusCode = response.StatusCode;
}
I also tried PostAsync(), but same result. After about 60 sec the call completes with a status code 400 or 404. This is not a server timeout. IPhone and Android apps use the same service. No problems there.
Any ideas on how to upload files that takes more than 60 seconds to send?
I too faced similar things. The timeout glitch.
Check if you could use another class instead of HttpClient.
WebClient may be.
Check if this helps you:
http://blog.anthonybaker.me/2013/06/how-to-upload-file-from-windows-phone.html
and even this:
http://chriskoenig.net/2011/08/19/upload-files-from-windows-phone/
I got things working for me with those.
I've used several days now to implement a new uploader and get all the details working. I used HttpWebRequest with the async methods and split the file into chuncks. Finally I got it working and it uploads without the timeout. Here is the complete code:
using System;
using Models;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Services
{
public class UploadData
{
public Stream PostStream { get; set; }
public Stream FileStream { get; set; }
public byte[] HeaderBytes {get; set;}
public byte[] FooterBytes {get; set;}
public byte[] Buffer { get; set; }
public Photo Upload { get; set; }
public int BytesWritten { get; set; }
}
public class UploadEventArgs : EventArgs
{
public Photo Upload { get; set; }
public int Progress { get; set; }
}
public class UploadService
{
public delegate void CompletedEventHandler(object sender, UploadEventArgs e);
public event CompletedEventHandler UploadCompleted;
public delegate void ProgressEventHandler(object sender, UploadEventArgs e);
public event ProgressEventHandler ProgressChanged;
private static string contentType = "multipart/form-data; boundary={0}";
private static string headerString = "Content-Disposition: form-data; name=\"file\"; filename=\"{0}\"\r\nContent-Type: Content-Type: application/octet-stream\r\n\r\n";
private HttpWebRequest m_request;
private static string boundarystr;
private UploadData m_uploadData;
private bool m_isStopped;
public async Task StartUpload(Photo upload, Uri uri, Dictionary<string, string> parameters)
{
try
{
m_isStopped = false;
var fileStream = (await upload.File.OpenReadAsync()).AsStreamForRead();
var uploadData = new UploadData();
boundarystr = "---------------------------" + DateTime.Now.Ticks.ToString("x");
string para = GetParamsString(parameters);
string headAndParams = para + String.Format(headerString, HttpUtility.UrlEncode(upload.File.Name));
var headerBytes = System.Text.Encoding.UTF8.GetBytes(headAndParams);
var footerBytes = Encoding.UTF8.GetBytes("\r\n--" + boundarystr + "--\r\n");
uploadData.Upload = upload;
uploadData.FileStream = fileStream;
uploadData.FooterBytes = footerBytes;
uploadData.HeaderBytes = headerBytes;
uploadData.BytesWritten = 0;
m_uploadData = uploadData;
m_request = (HttpWebRequest)WebRequest.Create(uri);
m_request.Method = "POST";
m_request.AllowWriteStreamBuffering = false;
m_request.ContentType = string.Format(contentType, boundarystr);
m_request.ContentLength = fileStream.Length + headerBytes.Length + footerBytes.Length;
var asyncResult = m_request.BeginGetRequestStream((ar) => { GetRequestStreamCallback(ar, uploadData); }, m_request);
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Start upload failed: " + ex.Message);
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
m_uploadData.FileStream.Close();
m_uploadData.PostStream.Close();
OnUploadComplete(argsStopped);
}
}
private void GetRequestStreamCallback(IAsyncResult asynchronousResult, UploadData uploadData)
{
try
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
Stream postStream = request.EndGetRequestStream(asynchronousResult);
postStream.Write(uploadData.HeaderBytes, 0, uploadData.HeaderBytes.Length);
var args = new UploadEventArgs();
args.Upload = uploadData.Upload;
args.Progress = 1;
OnProgressChanged(args);
uploadData.PostStream = postStream;
WriteNextChunck(uploadData);
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Header write failed: " + ex.Message);
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
m_uploadData.FileStream.Close();
m_uploadData.PostStream.Close();
OnUploadComplete(argsStopped);
}
}
private void WriteNextChunck(UploadData upload)
{
try
{
if ((upload.FileStream.Length - upload.BytesWritten) >= 16 * 1024)
{
upload.Buffer = new byte[16 * 1024];
}
else
{
// Last part
upload.Buffer = new byte[upload.FileStream.Length - upload.BytesWritten];
}
upload.FileStream.Read(upload.Buffer, 0, (int)upload.Buffer.Length);
upload.PostStream.BeginWrite(upload.Buffer, 0, upload.Buffer.Length, BeginWriteCallback, upload);
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Buffer write failed: " + ex.Message);
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
upload.FileStream.Close();
upload.PostStream.Close();
OnUploadComplete(argsStopped);
}
}
private void BeginWriteCallback(IAsyncResult ar)
{
try
{
var upload = ar.AsyncState as UploadData;
upload.PostStream.EndWrite(ar);
upload.BytesWritten += upload.Buffer.Length;
var args = new UploadEventArgs();
args.Upload = upload.Upload;
args.Progress = (int)(((decimal)upload.BytesWritten / (decimal)upload.FileStream.Length) * 100);
OnProgressChanged(args);
if (m_isStopped)
{
upload.FileStream.Close();
upload.PostStream.Close();
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Upload stopped");
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
OnUploadComplete(argsStopped);
return;
}
// write next chunck
if (upload.BytesWritten < upload.FileStream.Length)
{
WriteNextChunck(upload);
}
if (upload.BytesWritten >= upload.FileStream.Length)
{
WriteFooter(upload);
}
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Upload write failed: " + ex.Message);
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
OnUploadComplete(argsStopped);
}
}
private void WriteFooter(UploadData upload)
{
try
{
upload.PostStream.Write(upload.FooterBytes, 0, upload.FooterBytes.Length);
upload.PostStream.Close();
var asyncResult = m_request.BeginGetResponse(new AsyncCallback(GetResponseCallback), m_request);
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Footer write failed: " + ex.Message);
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
OnUploadComplete(argsStopped);
}
}
private void GetResponseCallback(IAsyncResult asynchronousResult)
{
try
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
string responseString = streamRead.ReadToEnd();
streamResponse.Close();
streamRead.Close();
response.Close();
m_uploadData.FileStream.Close();
m_uploadData.Upload.UploadInfo.StatusCode = response.StatusCode;
if (response.StatusCode == HttpStatusCode.NoContent)
{
m_uploadData.Upload.UploadInfo.Exception = null;
}
else
{
m_uploadData.Upload.UploadInfo.Exception = new Exception(responseString);
}
var args = new UploadEventArgs();
args.Upload = m_uploadData.Upload;
args.Progress = 100;
OnUploadComplete(args);
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = ex;
var args = new UploadEventArgs();
args.Upload = m_uploadData.Upload;
OnUploadComplete(args);
}
}
private string GetParamsString(Dictionary<string, string> parameters)
{
bool needsCLRF = false;
string result = "";
foreach (var param in parameters)
{
// Thanks to feedback from commenters, add a CRLF to allow multiple parameters to be added.
// Skip it on the first parameter, add it to subsequent parameters.
if (needsCLRF)
result += "\r\n";
needsCLRF = true;
string prm = string.Format("--{0}\r\nContent-Type: text/plain; charset=utf-8\r\nContent-Disposition: form-data; name={1}\r\n\r\n{2}",
boundarystr,
param.Key,
param.Value);
result += prm;
}
// Add the end of the request. Start with a newline
string footer = "\r\n--" + boundarystr + "\r\n";
result += footer;
return result;
}
protected virtual void OnUploadComplete(UploadEventArgs e)
{
if (UploadCompleted != null)
UploadCompleted(this, e);
}
protected virtual void OnProgressChanged(UploadEventArgs e)
{
if (ProgressChanged != null)
ProgressChanged(this, e);
}
public void Stop()
{
m_isStopped = true;
}
}
}

Windows Phone 8 Basic Authentication

I have hosted a Windows Web API using a basic authentication header with username and password.
I'm trying to create a login form that takes a username and password and sends back a token.
so i have the following code.
I'm using a Attributed method
public class BasicAuthenticationAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
private IPromiseRepository promiseRepository;
public BasicAuthenticationAttribute()
{
this.promiseRepository = new EFPromiseRepository(new PropellorContext());
//repository = promiseRepository;
}
public BasicAuthenticationAttribute(IPromiseRepository promiseRepository, INewsFeedRepository newsfeedRepository)
{
this.promiseRepository = promiseRepository;
}
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
if (actionContext.Request.Headers.Authorization == null)
{
actionContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
}
else
{
string authToken = actionContext.Request.Headers.Authorization.Parameter;
string decodedToken = authToken;
// Encoding.UTF8.GetString(Convert.FromBase64String(authToken));
string username = decodedToken.Substring(0, decodedToken.IndexOf(":"));
string password = decodedToken.Substring(decodedToken.IndexOf("^")+1);
string APIToken = decodedToken.Substring(decodedToken.IndexOf("="));
APIToken = APIToken.Replace("=", string.Empty);
password = password.Replace("=", string.Empty);
if (!string.IsNullOrEmpty(APIToken))
{
password = password.Replace(APIToken, string.Empty);
}
if (username != null && password != null)
{
try
{
var user = promiseRepository.GetUserByName(username);
var salt = user.PasswordSalt;
System.Security.Cryptography.SHA512Managed HashTool = new System.Security.Cryptography.SHA512Managed();
Byte[] PasswordAsByte = System.Text.Encoding.UTF8.GetBytes(string.Concat(password, salt));
Byte[] EncryptedBytes = HashTool.ComputeHash(PasswordAsByte);
HashTool.Clear();
var hashedpass = Convert.ToBase64String(EncryptedBytes);
if (hashedpass == user.Password)
{
if (string.IsNullOrEmpty(user.APIToken))
{
String guid = System.Guid.NewGuid().ToString();
user.APIToken = guid;
promiseRepository.UpdateUser(user);
promiseRepository.Save();
}
if (user != null)
{
user = promiseRepository.GetUserByUserID(user.UserID);
HttpContext.Current.User = new GenericPrincipal(new ApiIdentity(user), new string[] { });
base.OnActionExecuting(actionContext);
}
}
if (APIToken != null)
{
if (user.APIToken == APIToken)
{
var userbytoken = promiseRepository.GetUserByAPIToken(APIToken);
HttpContext.Current.User = new GenericPrincipal(new ApiIdentity(userbytoken), new string[] { });
base.OnActionExecuting(actionContext);
}
}
}
catch (Exception)
{
{
actionContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
base.OnActionExecuting(actionContext);
}
throw;
}
}
}
}
}
This works with Fiddler when the correct credentials are passed
I'm attempting to produce the same authentication in my windows phone application.
Passes a username and password into the basic authentication http header.
However I'm not sure how to do this after a large amount of diggging on the internet alot of the exmaples are windows phone 7 and certain methods don't exist anymore.
This is the code i have arrived at.
private void Login1_Click(object sender, RoutedEventArgs e)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:5650/api/start");
NetworkCredential credentials = new NetworkCredential(userName.Text + ":^",password.Text + "=");
request.Credentials = credentials;
request.BeginGetResponse(new AsyncCallback(GetSomeResponse), request);
Hopefully someone can guide me into the right direction.
it should be simple in principle :(
Here is a sample using HttpClient:
public static async Task<String> Login(string username, string password)
{
HttpClient Client = new HttpClient();
Client.DefaultRequestHeaders.Add("Authorization", "Basic " + Convert.ToBase64String(StringToAscii(string.Format("{0}:{1}", username, password))));
var response = await Client.GetAsync(new Uri(new Uri("http://yourdomain.com"), "/login"));
var status= await response.Content.ReadAsAsync<String>();
return status;
}
And of course you can find the ToBase64String function on the internet. The tricky part here is the Authorization header.

Gmail User/Password Authentication in Google Drive API for DotNet

Iam using GoogleDriveAPI to upload Documents to Drive from Asp.net.It is working fine but i need to use ClientID and ClientSecret for Authentication. Not the gmail userName/Password.After Authentication for Authorization it is redirected to gmail for login after login it is asking for AccessPermission for Drive.So how can i pass the GmailUserID and Password for Authentication not the ClientID and ClientSecret . and after that can i restrict again from Login for Authorization .
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using DotNetOpenAuth.OAuth2;
using Google.Apis.Authentication.OAuth2;
using Google.Apis.Authentication.OAuth2.DotNetOpenAuth;
using Google.Apis.Drive.v2;
using Google.Apis.Drive.v2.Data;
using Google.Apis.Util;
using System.Diagnostics;
using DotNetOpenAuth.Messaging;
using System.Text;
using System.IO;
public partial class _Default : System.Web.UI.Page
{
private static DriveService driveService;
private static OAuth2Authenticator<WebServerClient> authenticator;
private static IAuthorizationState _state;
String CLIENT_ID = "90994017777728.apps.googleusercontent.com";
String CLIENT_SECRET = "IR777777773Nf3vnLT0v";
private static readonly string[] SCOPES = new[] { DriveService.Scopes.Drive.GetStringValue() };
protected void Page_Load(object sender, EventArgs e)
{
Login();
}
private IAuthorizationState AuthState {
get {
return _state ?? HttpContext.Current.Session["GoogleAuthState"] as IAuthorizationState;
}
}
private OAuth2Authenticator<WebServerClient> CreateAuthenticator() {
var provider = new WebServerClient(GoogleAuthenticationServer.Description,CLIENT_ID,CLIENT_SECRET);
var authenticator = new OAuth2Authenticator<WebServerClient>(provider,GetAuthorization);
return authenticator;
}
private IAuthorizationState GetAuthorization(WebServerClient client) {
IAuthorizationState state = AuthState;
if (state != null) {
if (state.AccessTokenExpirationUtc.Value.CompareTo(DateTime.Now.ToUniversalTime()) > 0)
return state;
else
state = null;
}
state = client.ProcessUserAuthorization(new HttpRequestInfo(HttpContext.Current.Request));
if (state != null && (!string.IsNullOrEmpty(state.AccessToken) || !string.IsNullOrEmpty(state.RefreshToken))) {
if (state.RefreshToken == null)
state.RefreshToken = "";
HttpContext.Current.Session["GoogleAuthState"] = _state = state;
return state;
}
client.RequestUserAuthorization(SCOPES,"",HttpContext.Current.Request.Url); // Redirecting to Gmail LoginPage
return null;
}
private string GetContentType(string fileExtension) {
if (string.IsNullOrEmpty(fileExtension))
return string.Empty;
string contentType = string.Empty;
switch (fileExtension) {
case "htm":
case "html":
contentType = "text/HTML";
break;
case "txt":
contentType = "text/plain";
break;
case "doc":
case "rtf":
case "docx":
contentType = "Application/msword";
break;
case "xls":
case "xlsx":
contentType = "Application/x-msexcel";
break;
case "jpg":
case "jpeg":
contentType = "image/jpeg";
break;
case "png":
contentType = "image/png";
break;
case "bmp":
contentType = "image/bmp";
break;
case "gif":
contentType = "image/GIF";
break;
case "pdf":
contentType = "application/pdf";
break;
}
return contentType;
}
public void Login() {
if (authenticator == null)
authenticator = CreateAuthenticator();
if (driveService == null) {
driveService = new DriveService(authenticator);
}
}
protected void Button1_Click(object sender,EventArgs e) {
string[] stringParts = FileUpload1.FileName.Split(new char[] { '/' });
string str = stringParts[stringParts.Length - 1].ToString();
string[] strType = str.Split(new char[] { '.' });
string type = GetContentType(strType[1]);
Google.Apis.Drive.v2.Data.File newFile = new Google.Apis.Drive.v2.Data.File { Title = FileUpload1.FileName,MimeType = type };
byte[] byteArray = FileUpload1.FileBytes;
MemoryStream stream = new MemoryStream(byteArray);
FilesResource.InsertMediaUpload request = driveService.Files.Insert(newFile,stream,newFile.MimeType);
request.Convert = true;
request.Upload();
Google.Apis.Drive.v2.Data.File file = request.ResponseBody;
InsertPermission(driveService,file);
HttpContext.Current.Session["GoogleAuthState"] = null;
Response.Write(file.AlternateLink);
}
public void InsertPermission(DriveService service,Google.Apis.Drive.v2.Data.File file) {
Permission newPermission = new Permission();
newPermission.Value = TextBox1.Text;
newPermission.Type = "user";
newPermission.Role = "reader";
try {
Permission per = service.Permissions.Insert(newPermission,file.Id).Fetch();
}
catch (Exception e) {
Console.WriteLine("An error occurred: " + e.Message);
}
}

Resources