Unable to use Xamarin.Forms WebView for Dropbox authentication - ios

I've run into a problem using WebView to access the authorization uri necessary to authorize access by my Xamarin forms (running under iOS) app. I don't believe the problem lies with the WebView and the particular url, and not the Dropbox API itself.
First, I should mention that I am able to use WebView to access arbitrary web sites, so I know I am able to access the web generally from within my app.
In the code below you will see that I have two buttons set up. The first uses a WebView to successfully access the Wikipedia page for Xamarin. The second attempts to contact Dropbox in order to begin the authentication process. However, that request fails with the message:
Error (400) It seems the app you were using submitted a bad request. If you would like to report this error to the app's developer, include the information below. Invalid redirect_uri. Must be an absolute uri.
Initially, I thought that the problem was that the redirection uri wasn't registered correctly, but if I copy the url being passed to the webview (included below as a comment), and paste it directly into safari, the authentication page opens as expected. It is only when using WebView that I receive the error message. That makes me think that it's not the redirect_uri, or the url itself, but something in the way that the WebView is presenting it to dropbox.com.
Can anyone help me out? I've also tried taking a uri that works in Safari / Chrome and passing it directly to the webview (bypassing DropboxOAuth2Helper) without any luck. The uri will work in Safari, but not in the WebView.
public App()
{
Button xamarinBtn = new Button();
xamarinBtn.Text = "Xamarin";
xamarinBtn.Clicked += OnButtonClicked;
xamarinBtn.StyleId = "Xamarin";
Button dropboxBtn = new Button();
dropboxBtn.Text = "Dropbox";
dropboxBtn.Clicked += OnButtonClicked;
dropboxBtn.StyleId = "Dropbox";
StackLayout layout = new StackLayout();
layout.Children.Add(xamarinBtn);
layout.Children.Add(dropboxBtn);
ContentPage page = new ContentPage();
page.Content = layout;
MainPage = new NavigationPage(page);
}
private void OnButtonClicked(object sender, EventArgs e)
{
Button btn = sender as Button;
UrlWebViewSource source = new UrlWebViewSource();
if (btn.StyleId == "Xamarin")
{
source.Url = "https://en.wikipedia.org/wiki/Xamarin";
}
else if (btn.StyleId == "Dropbox")
{
string oauth2State = Guid.NewGuid().ToString("N");
Uri authorizeUri = DropboxOAuth2Helper.GetAuthorizeUri(OAuthResponseType.Token, "d1612up7la63slo", "http://127.0.0.1:52475/authorize", oauth2State);
source.Url = authorizeUri.AbsoluteUri; // https://www.dropbox.com/oauth2/authorize?response_type=token&client_id=d1612up7la63slo&redirect_uri=http%3A%2F%2F127.0.0.1%3A52475%2Fauthorize&state=1062a614aa3d4e2e85cd84de32903987
}
WebView webView = new WebView();
webView.Source = source;
ContentPage page = new ContentPage();
page.Content = webView;
MainPage.Navigation.PushAsync(page);
}

You should add that as a OAuth 2 redirect URI for your app via the App Console:
After doing this, I tried OC code it works properly and can show the authorize view. But Unfortunately, the Dropbox for Xamarin failed. You can try to use another api to show this view:
Uri authorizeUri = DropboxOAuth2Helper.GetAuthorizeUri("d1612up7la63slo");
source.Url = source.Url = authorizeUri.AbsoluteUri;

Related

Xamarin forms: How to check a browser is open successfully in my webview

In my xamarin forms app, using webview I am loading a website with its IP. If the website loading is fail I want to redirect the user back to IP entering page and let him enter the correct IP. So how I can check the website is loading successfully or not?
Thanks in advance
In your shared project, you have the Navigated event from your Webview object:
WebView webView = new WebView ();
webView.Navigated += WebView_Navigated;
private void WebView_Navigated (object sender, WebNavigatedEventArgs e)
{
//your stuff
}

Xamarin.Auth Google Presenter not closing in Android Xamarin.Forms App

I am using Xamarin.Form to write a Android app. I have successfully implemented the OAuth and I can sign in and get the user information using OAuth2Authenticator.
When the user clicks signup/Login I show the OAuthLoginPresenter as follows:
var oAuthLoginPresenter = new Xamarin.Auth.Presenters.OAuthLoginPresenter();
oAuthLoginPresenter.Login(App.OAuth2Authenticator);
This works great and the user sees the login page.
When the user clicks Allow the completed Event on the OAuth2Authenticator instance fires as expected and the user is once again back looking at the app.
However this is where my problem is - I get a notification:
If CustomTabs Login Screen does not close automatically close
CustomTabs by Navigating back to the app.
Thing is though I am back at the app. If I look at all my open apps I can see the login screen is still running in the back ground so that presenter has not closed.
In my intercept Activity which gets the redirect looks like this:
[Activity(Label = "GoogleAuthInterceptor")]
[IntentFilter
(
actions: new[] { Intent.ActionView },
Categories = new[]
{
Intent.CategoryDefault,
Intent.CategoryBrowsable
},
DataSchemes = new[]
{
// First part of the redirect url (Package name)
"com.myapp.platform"
},
DataPaths = new[]
{
// Second part of the redirect url (Path)
"/oauth2redirect"
}
)]
public class GoogleAuthInterceptor: Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your application here
Android.Net.Uri uri_android = Intent.Data;
// Convert Android Url to C#/netxf/BCL System.Uri
Uri uri_netfx = new Uri(uri_android.ToString());
// Send the URI to the Authenticator for continuation
App.OAuth2Authenticator?.OnPageLoading(uri_netfx);
Finish();
}
}
Am I missing a step in here to close that presenter? Any other ideas please?
UPDATE:
I have now found that using Chrome as the default browser works fine and presenter is closed. But if I use a Samsung browser as my default browser - it does not close.
So I need a way to close it manually.
Just set property to null when initializing Xamarin.Auth in your main activity:
//don't show warning message when closing account selection page
CustomTabsConfiguration.CustomTabsClosingMessage = null;

ASP.Net MVC application access to other servers

We have an ASP.Net MVC application (website), just a straight web app. The URL it needs to connect to is an ASP.Net WebAPI2 web service on port 14015. The MVC application is calling the Web service anonymously using a WebClient class; the web service is secured by limiting which IPs can connect to it. There is no authorization mode to access except by IP.
using (WebClient client = new WebClient())
{
//****************************
// We make the web service call like this:
//****************************
string url = #"http://secure.example.com:14015/lms/SSOKey/1158341";
string key = client.DownloadString(url);
//****************************
// Then we append the returned key to build the full URL. This URL is used
// in the View to build a link button.
//****************************
string login_url = #"http://192.168.1.1/tc/login.do?uid=" + key;
login_url = login_url.Replace("\"", string.Empty);
//****************************
// Pass the URL to the view to build the link button
//****************************
ViewBag.LoginURL = login_url;
}
I can access the URL from a browser on the server where the MVC application is published, however, the call is unsuccessful. Any ideas how I may find out why this won't connect??
If you are calling the code inside of a controller and the users have to logon to your web app, than this code should give you what you need:
string currentUser = User.Identity.Name;
If your users use your web app anonymously currentUser will be blank.
Adding this code solved the problem.
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
Since we limit access by IP Addresses, very low security risk.

Facebook OAuth + AppHarbor workaround on random port

I a have a sample app, hosted on AppHarbor and now want to integrate authorization through facebook. So i downloaded nugget Facebook.Web.Mvc package to implement it.
After reading tutorial, in controller i have method:
public ActionResult Login(string returnUrl)
{
var oauthClient = new FacebookOAuthClient(FacebookApplication.Current) { RedirectUri = GetFacebookRedirectUri() };
if (!string.IsNullOrWhiteSpace(returnUrl))
{
returnUrl = Url.Action("Index", "Facebook");
}
dynamic parameters = new ExpandoObject();
parameters.scope = ExtendedPermissions;
var state = new { csrf_token = CalculateMD5Hash(Guid.NewGuid().ToString()), return_url = returnUrl };
parameters.state = Base64UrlEncode(Encoding.UTF8.GetBytes(JsonSerializer.Current.SerializeObject(state)));
SetFacebookCsrfToken(state.csrf_token);
string s = oauthClient.GetLoginUrl(parameters).AbsoluteUri;
ViewBag.FacebookLoginUrl = s;
//new LogEvent(s).Raise();
return View(new AccountModel());
}
View:
<a href="#ViewBag.FacebookLoginUrl" id="lUrl">
<div class="fblogin"></div>
In localhost this works for me.
But when i upload it to appharbor, i see, that generated link indicates to address + port 16013 (as support told always random port). So clicking it shows me facebook login window, than blank page.
I manually configured my app settings in facebook to this port but it did not helped.
Also i tried to access my site through this port - nothing.
Then i changed port number through jquery to 80, its also did not help.
you have had such problems?
I'm not familiar with the Facebook api, but I've had a similar problem.
I suspect that the returnUrl value being passed in is incorrect. It probably contains a port number that AppHarbor uses internally for load balancing.
See this article on how to create a public url for AppHarbor:
http://support.appharbor.com/kb/getting-started/workaround-for-generating-absolute-urls-without-port-number
Then make sure that the value in your returnUrl is publicly available.
You can now set the aspnet:UseHostHeaderForRequestUrl appSetting to true which effectively solves this problem. This can be done by adding a Configuration Variable to your application with the corresponding key and value.
Source on AppHarbor

Embedded browser control does not display

Basically I embedded a browser into my application. However the request I want to view (google) does not show in the application despite my code linking to it. Any ideas?
BrowserFieldConfig myBrowserFieldConfig = new BrowserFieldConfig();
myBrowserFieldConfig.setProperty(BrowserFieldConfig.NAVIGATION_MODE,BrowserFieldConfig.NAVIGATION_MODE_POINTER);
BrowserField browserSession = new BrowserField(myBrowserFieldConfig);
//browserSession.
browserSession.requestContent( "http://www.google.com" );
add(browserSession);**
It need MDS service to be running. Check for MDS. it will work.

Resources