Download a file through http basic authentication with Xamarin Android - c#

I am accessing to an Enterprise Intranet using a WebView, in a Xamarin Android app. I can see and navigate correctly through the intranet but I am not able to download the files available there. This is my code :
private void MWebview_Download(object sender, DownloadEventArgs e)
{
var url = e.Url;
// var s = url.Replace(" ", "%20");
DownloadManager.Request request = new DownloadManager.Request(Android.Net.Uri.Parse(url));
string credentials = "cristina.casas:Tst.30"; //just for try
// pasar las credenciales a base64
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(credentials);
var encodedCredentials = System.Convert.ToBase64String(plainTextBytes);
request.AddRequestHeader("Authorization", "Basic " + encodedCredentials);
request.SetTitle("descarga.pdf");
request.SetNotificationVisibility(DownloadVisibility.VisibleNotifyCompleted);
request.AllowScanningByMediaScanner();
request.SetMimeType("application/pdf");
request.SetDestinationInExternalPublicDir(Android.OS.Environment.DirectoryDownloads, "descarga.pdf");
DownloadManager dm = (DownloadManager)Application.Context.GetSystemService(Context.DownloadService);
dm.Enqueue(request);
Toast.MakeText(Application.Context, "Downloading File", ToastLength.Long).Show();//To notify the Client that the file is being downloaded
}
It doesn't work. I get the error "download failed". I am stucked at this point for days...

Your code looks correct. Try the following as this works as a basic authentication test using HttpWatch's website. If it works for you, substitute your intranet's uri, user and password.
DownloadCompleteReceiver receiver;
var user = "httpwatch";
var password = new Random().Next(int.MinValue, int.MaxValue).ToString();
var uriString = "https://www.httpwatch.com/httpgallery/authentication/authenticatedimage/default.aspx?0.05205263447822417";
using (var uri = Android.Net.Uri.Parse(uriString))
using (var request = new DownloadManager.Request(uri))
{
var basicAuthentication = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{user}:{password}"));
request.AddRequestHeader("Authorization", $"Basic {basicAuthentication}");
request.SetNotificationVisibility(DownloadVisibility.VisibleNotifyCompleted);
request.SetDestinationInExternalPublicDir(Android.OS.Environment.DirectoryDownloads, "someImage.gif");
using (var downloadManager = (DownloadManager)GetSystemService(DownloadService))
{
var id = downloadManager.Enqueue(request);
receiver = new DownloadCompleteReceiver(id, (sender, e) =>
{
Toast.MakeText(Application.Context, $"Download Complete {id}", ToastLength.Long).Show();
if (sender is DownloadCompleteReceiver rec)
{
UnregisterReceiver(rec);
rec.Dispose();
}
});
RegisterReceiver(receiver, new IntentFilter(DownloadManager.ActionDownloadComplete));
Toast.MakeText(Application.Context, $"Downloading File: {id}", ToastLength.Short).Show();
}
}
The DownloadCompleteReceiver implementation is:
public class DownloadCompleteReceiver : BroadcastReceiver
{
long id;
EventHandler handler;
public DownloadCompleteReceiver(long id, EventHandler handler)
{
this.id = id;
this.handler = handler;
}
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action == DownloadManager.ActionDownloadComplete &&
id == intent.GetLongExtra(DownloadManager.ExtraDownloadId, 0))
{
handler.Invoke(this, EventArgs.Empty);
}
}
}

Related

How to open PDF file in iOS?

i try to open a existing PDF file on a iOS device.
This file have to be open with the default PDF reader.
In this moment i use the "dependency service" to run native code.
public void Save(string filename, byte[] byPDF)
{
string strPfad = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), filename);
if(File.Exists(strPfad))
{
File.Delete(strPfad);
File.WriteAllBytes(strPfad, byPDF);
}
else
File.WriteAllBytes(strPfad, byPDF);
var viewer = UIDocumentInteractionController.FromUrl(NSUrl.FromFilename(strPfad));
var controller = GetVisibleViewController();
viewer.PresentOpenInMenu(controller.View.Frame, controller.View, true);
}
private UIViewController GetVisibleViewController(UIViewController controller = null)
{
controller = controller ?? UIApplication.SharedApplication.KeyWindow.RootViewController;
if (controller.PresentedViewController == null)
return controller;
if (controller.PresentedViewController is UINavigationController)
{
return ((UINavigationController)controller.PresentedViewController).VisibleViewController;
}
if (controller.PresentedViewController is UITabBarController)
{
return ((UITabBarController)controller.PresentedViewController).SelectedViewController;
}
return GetVisibleViewController(controller.PresentedViewController);
}
If I run this code is nothing happend (only the file becomes written).
I just used a standard UIViewController and passed the path (where the pdf is saved on the device) to the controller and loaded it up in a UIWebview.
public class PdfController : UIViewController
{
public PdfController(string pdfPath)
{
NavigationItem.LeftBarButtonItem = new NavBarButton("Back", (sender, args) =>
{
NavigationController.PopViewController(true);
});
var webView = new UIWebView(View.Bounds);
View.AddSubview(webView);
webView.LoadRequest(new NSUrlRequest(new NSUrl(pdfPath, false)));
webView.ScalesPageToFit = true;
}
}
But you will need to download it first and pass it to this controller
This snippit will allow you download the pdf and save it.
Public void DownloadPDF()
{
Utility.AddNetworkConnection();
var webClient = new WebClient();
loadingView = new LoadingView();
loadingView.Show("Downloading PDF");
webClient.DownloadDataCompleted += (s, e) =>
{
Utility.RemoveNetworkConnection();
File.WriteAllBytes(_pdfPathLocation, e.Result); // writes to local storage
InvokeOnMainThread(() =>
{
loadingView.Hide();
_pdfImageElement.SetValueAndUpdate("Open PDF");
var a = new UIAlertView("Done", "File downloaded and saved", null, "OK", "Open PDF");
a.Show();
a.Clicked += OpenPdf;
});
};
var url = new Uri(_wreck.PdfURL);
webClient.Encoding = Encoding.UTF8;
webClient.DownloadDataAsync(url);
}

Remembering log in credentials/permissions UWP/C# (Microsoft Cloud API)

I'm creating an app that access the Microsoft Cloud API to get health data. It uses OAuth to log in when you hit the Sign In Button
private void signinButton_Click(object sender, RoutedEventArgs e)
{
UriBuilder uri = new UriBuilder("https://login.live.com/oauth20_authorize.srf");
var query = new StringBuilder();
query.AppendFormat("redirect_uri={0}", Uri.EscapeDataString(RedirectUri));
query.AppendFormat("&client_id={0}", Uri.EscapeDataString(ClientId));
query.AppendFormat("&scope={0}", Uri.EscapeDataString(Scopes));
query.Append("&response_type=code");
uri.Query = query.ToString();
this.webView.Visibility = Visibility.Visible;
this.webView.Navigate(uri.Uri);
}
This brings up a webView with the page to log in using Microsoft credentials. Once completed, it leads to this:
private async void WebView_NavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
{
//
// When the web view navigates to our redirect URI, extract the authorization code from
// the URI and use it to fetch our access token. If no authorization code is present,
// we're completing a sign-out flow.
//
if (args.Uri.LocalPath.StartsWith("/oauth20_desktop.srf", StringComparison.OrdinalIgnoreCase))
{
WwwFormUrlDecoder decoder = new WwwFormUrlDecoder(args.Uri.Query);
var code = decoder.FirstOrDefault((entry) => entry.Name.Equals("code", StringComparison.OrdinalIgnoreCase));
var error = decoder.FirstOrDefault((entry) => entry.Name.Equals("error", StringComparison.OrdinalIgnoreCase));
var errorDesc = decoder.FirstOrDefault((entry) => entry.Name.Equals("error_description", StringComparison.OrdinalIgnoreCase));
// Check the code to see if this is sign-in or sign-out
if (code != null)
{
// Hide the browser again, no matter what happened...
sender.Visibility = Visibility.Collapsed;
if (error != null)
{
this.responseText.Text = string.Format("{0}\r\n{1}", error.Value, errorDesc.Value);
return;
}
var tokenError = await this.GetToken(code.Value, false);
if (string.IsNullOrEmpty(tokenError))
{
this.responseText.Text = "Successful sign-in!";
this.signoutButton.IsEnabled = true;
this.signinButton.IsEnabled = false;
this.getProfileButton.IsEnabled = true;
this.getDevicesButton.IsEnabled = true;
this.getActivitiesButton.IsEnabled = true;
this.getDailySummaryButton.IsEnabled = true;
this.getHourlySummaryButton.IsEnabled = true;
}
else
{
this.responseText.Text = tokenError;
}
}
else
{
this.responseText.Text = "Successful sign-out!";
this.signoutButton.IsEnabled = false;
this.signinButton.IsEnabled = true;
this.getProfileButton.IsEnabled = false;
this.getDevicesButton.IsEnabled = false;
this.getActivitiesButton.IsEnabled = false;
this.getDailySummaryButton.IsEnabled = true;
this.getHourlySummaryButton.IsEnabled = false;
}
}
}
private async Task<string> GetToken(string code, bool isRefresh)
{
UriBuilder uri = new UriBuilder("https://login.live.com/oauth20_token.srf");
var query = new StringBuilder();
query.AppendFormat("redirect_uri={0}", Uri.EscapeDataString(RedirectUri));
query.AppendFormat("&client_id={0}", Uri.EscapeDataString(ClientId));
query.AppendFormat("&client_secret={0}", Uri.EscapeDataString(ClientSecret));
if (isRefresh)
{
query.AppendFormat("&refresh_token={0}", Uri.EscapeDataString(code));
query.Append("&grant_type=refresh_token");
}
else
{
query.AppendFormat("&code={0}", Uri.EscapeDataString(code));
query.Append("&grant_type=authorization_code");
}
uri.Query = query.ToString();
var request = WebRequest.Create(uri.Uri);
try
{
using (var response = await request.GetResponseAsync())
{
using (var stream = response.GetResponseStream())
{
using (var streamReader = new StreamReader(stream))
{
var responseString = streamReader.ReadToEnd();
var jsonResponse = JObject.Parse(responseString);
this.creds.AccessToken = (string)jsonResponse["access_token"];
this.creds.ExpiresIn = (long)jsonResponse["expires_in"];
this.creds.RefreshToken = (string)jsonResponse["refresh_token"];
string error = (string)jsonResponse["error"];
return error;
}
}
}
}
catch (Exception ex)
{
return ex.Message;
}
}
I don't want users to have to accept the permissions every time the app is launched. Is there a way to save credentials locally so that it automatically authenticates on launch? Thanks!
You can use
Windows.Storage.ApplicationData.Current.LocalSettings
This process good described by this answer Best Way to keep Settings for a WinRT App?
The code in link identity to UWP
Store the needed oauth parts in the credential locker API. Never store these kind of information in the normal settings API.
On start read the oauth information and use the refreshtoken to get a new access token.
More Information here.
https://msdn.microsoft.com/en-us/library/windows/apps/mt270189.aspx

Google integation in windows phone 8.1[RT] application

I am working with windows phone 8.1 application and I want to login with Google Plus , for that I have create Client id and Client secret from Google
string uri = string.Format("{0}?response_type=code&client_id={1}&redirect_uri={2}&scope={3}&approval_prompt=force",
authEndpoint,
clientId,
"urn:ietf:wg:oauth:2.0:oob",
scope);
webBrowser.Navigate(new Uri(uri, UriKind.Absolute));
and I Got string something like 4/BGIl1Na3TQJlAD8SQ7blvHyONJ_Jyav8COHa7tIrAdo
I want User Email and Name from account for signup or login
Please help me for that.
Thank you
Implement the interafce IWebAuthenticationContinuable to your class and then under ContinueWebAuthentication() Method use this code :
var authData = GetGoogleSuccessCode(args.WebAuthenticationResult.ResponseData);
var userData = await GetTokenAndUserInfo(authData);
private string GetGoogleSuccessCode(string data)
{
if (string.IsNullOrEmpty(data)) return null;
var parts = data.Split('&')[0].Split('=');
for (int i = 0; i < parts.Length; ++i)
{
if (parts[i] == "Success code")
{
return parts[i + 1];
}
}
return null;
}
public async Task<string> GetTokenAndUserInfo(string code)
{
var client = new HttpClient();
var auth = await client.PostAsync("https://accounts.google.com/o/oauth2/token", new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("code", code),
new KeyValuePair<string, string>("client_id",Constants.GoogleAppId),
new KeyValuePair<string, string>("client_secret",Constants.GoogleAppSecret),
new KeyValuePair<string, string>("grant_type","authorization_code"),
new KeyValuePair<string, string>("redirect_uri","urn:ietf:wg:oauth:2.0:oob"),
}));
var data = await auth.Content.ReadAsStringAsync();
var j = JToken.Parse(data);
var token = j.SelectToken("access_token");
var searchUrl = "https://www.googleapis.com/oauth2/v2/userinfo";
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token.ToString());
HttpResponseMessage res = await client.GetAsync(searchUrl);
string content = await res.Content.ReadAsStringAsync();
return content;
}
And add following code in App.xaml.cs file:
public static ContinuationManager ContinuationManager { get; private set; }
public App()
{
ContinuationManager = new ContinuationManager();
}
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
#if WINDOWS_PHONE_APP
ContinuationManager.MarkAsStale();
#endif
// TODO: Save application state and stop any background activity
deferral.Complete();
}
protected override void OnActivated(IActivatedEventArgs args)
{
#if WINDOWS_PHONE_APP
if (args.Kind == ActivationKind.WebAuthenticationBrokerContinuation)
{
var continuationEventArgs = args as IContinuationActivatedEventArgs;
if (continuationEventArgs != null)
{
ContinuationManager.Continue(continuationEventArgs);
ContinuationManager.MarkAsStale();
}
}
#endif
}
Don't forget to include Continuation Manager class file in your project.
You will get the user info.
I'm not an expert.
It looks like you need to request the email scope:
https://developers.google.com/+/web/api/rest/oauth#login-scopes
as well as (probably) the profile scope (same page).
If this isn't helpful, please edit your question and show more of your code (obscuring your secret API key, etc.).
I have also searched for sign in using facebook and google in WIN RT Apps and finally found solution from this link :
Web authentication broker sample
Maybe it will help you also.

Bloomberg BLPAPI how get DV01 of a bond?

I'm pretty new to the BBG API and its lack of documentation. I've been trying to figure out how to get the DV01 or PV01 of a bond, but I always get an error on the fields I try. Am I missing something? Sample code below that I modified from blapi C# samples.
private void run(string[] args)
{
string serverHost = "localhost";
int serverPort = 8194;
SessionOptions sessionOptions = new SessionOptions();
sessionOptions.ServerHost = serverHost;
sessionOptions.ServerPort = serverPort;
System.Console.WriteLine("Connecting to " + serverHost + ":" + serverPort);
Session session = new Session(sessionOptions);
bool sessionStarted = session.Start();
if (!sessionStarted)
{
System.Console.WriteLine("Failed to start session.");
return;
}
if (!session.OpenService("//blp/refdata"))
{
System.Console.Error.WriteLine("Failed to open //blp/refdata");
return;
}
Service refDataService = session.GetService("//blp/refdata");
Request request = refDataService.CreateRequest("ReferenceDataRequest");
Element securities = request.GetElement("securities");
//IBM Bond BBG004J4QNM9
securities.AppendValue("BBG004J4QNM9");
Element fields = request.GetElement("fields");
fields.AppendValue("DS002");
fields.AppendValue("MARKET_SECTOR_DES");
fields.AppendValue("SECURITY_TYP2");
fields.AppendValue("SECURITY_TYP");
fields.AppendValue("ID_EXCH_SYMBOL");
fields.AppendValue("PX_LAST");
//None of these are returned
fields.AppendValue("PV01_BID_CURRENCY_1");
fields.AppendValue("PV01_MID_CURRENCY_1");
fields.AppendValue("DV01");
fields.AppendValue("HEDGE_RATIO_10Y_TSY");
Console.WriteLine("Sending Request: " + request);
session.SendRequest(request, null);
while (true)
{
Event eventObj = session.NextEvent();
foreach (Message msg in eventObj.GetMessages())
{
Console.WriteLine(msg.AsElement);
}
if (eventObj.Type == Event.EventType.RESPONSE)
{
break;
}
}
}

How to make an "apprequest" with c# Facebook SDK?

I would like to make an apprequest from my application using the c# facebook sdk.
After some investigation I found some examples that are using the app access token which has the following format : access_token = YOUR_APP_ID|YOU_APP_SECRET
Now I have tried the following using the appAccessToken:
string appAccessToken = String.Format("{0}|{1}",Constants.FacebookAppId,Constants.FacebookAppSecret);
FacebookClient fb = new FacebookClient(appAccessToken);
fb.PostCompleted += (o, args) =>
{
if (args.Error != null)
{
Dispatcher.BeginInvoke(() => MessageBox.Show(args.Error.Message));
return;
}
};
dynamic parameters = new ExpandoObject();
parameters.message = "Test: Action is required";
parameters.data = "Custom Data Here";
fb.PostTaskAsync(String.Format("{0}/apprequests", Constants.FacebookAppId), parameters);
But it doesn't work... Is it possible to make an apprequest using the c# Facebook skd?
I hope anybody can help me.
Have a nice day!
With best regards, Matthias
To get access token of App.
Just use this link and you will get it
https://developers.facebook.com/tools/access_token/
Please check this out : http://facebooksdk.net/docs/phone/tutorial.
To get user access token
Add this to App.xaml.cs
internal static string AccessToken = String.Empty;
internal static string FacebookId = String.Empty;
public static bool IsAuthenticated = false;
public static FacebookSessionClient FacebookSessionClient = new FacebookSessionClient(Constants.FacebookAppId);
Create a method to get Access token
private async Task Authenticate()
{
try
{
_session = await App.FacebookSessionClient.LoginAsync("user_about_me,read_stream");
App.AccessToken = _session.AccessToken;
App.FacebookId = _session.FacebookId;
}
catch (InvalidOperationException e)
{
var messageBox = new OneButtonCustomMessageBox
{
TbMessageTitle = { Text = "Facebook Login Error" },
TbMessageContent = {Text = e.Message}
};
messageBox.Show();
}
}
After you have Access Token you will use a method like this to call GraphAPI from FB to get user information
private async void LoadUserInfo()
{
var fb = new FacebookClient(App.AccessToken);
fb.GetCompleted += (o, e) =>
{
if (e.Error != null)
{
Dispatcher.BeginInvoke(() => MessageBox.Show(e.Error.Message));
return;
}
var result = (IDictionary<string, object>)e.GetResultData();
Dispatcher.BeginInvoke(async () =>
{
var profilePictureUrl = string.Format("https://graph.facebook.com/{0}/picture?type={1}&access_token={2}", App.FacebookId, "normal", App.AccessToken);
this.ImgAvatar.Source = new BitmapImage(new Uri(profilePictureUrl));
this.TxtName.Text = String.Format("{0}", (string)result["name"]);
});
};
await fb.GetTaskAsync("me");
}

Categories

Resources