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
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?
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?
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;
}
}
}
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.
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);
}
}