I'm working on a Xamarin.Forms project, and I'm having a really weird issue. This code is actually executing in Xamarin.Droid project.
When I try to do this
var user = await client.LoginAsync(this, MobileServiceAuthenticationProvider.Facebook);
if (user != null)
{
try
{
// executes this line
var userInfo = await client.InvokeApiAsync("/.auth/me");
// down here nothing is executed and userInfo is never set with the data
}
catch (Exception e)
{
// never enter to this block
}
}
The userInfo variable is never set with the data, and no exceptions and nothing rare in the Output.
I already tried client.InvokeApiAsync("/.auth/me", HttpMethod.Get, null) but no works neither.
I know this is quite short information but I haven't anything else, because no exception is raised.
Thanks.
I followed this article to add authentication to my Xamarin Forms app. It worked fine on my side. There are some things you need to check on your project.
Have you published your Azure Mobile Service to Azure and turn on the Authentication & configured Facebook app-id and secret.
Have you connected your mobile service from your mobile client.
I finally figured out what was the problem. The event handler that initiates the logic of authentication, returned void instead of Task, so the async call never continues after await call.
This is something for remind.
Thanks #Amor - MSFT for your answer.
Related
I want to override Azure AD SSO login for a MVC web application. I don't want to log other applications out in the process, but require login for security purposes. I am using OAuth2.0 with OIDC via Owin for authentication.
I am trying to use the prompt=login query parameter, which should theoretically do the trick. I found a Github reference to this being recently made available in Core but cannot trace how to do it in MVC5.2
Is it possible to do it in the Application Builder? I tried adding .WithExtraQueryParameters ("prompt=login") to the ConfidentialClientApplicationBuilder when getting the access code. No luck.
Is there another workaround if the code doesn't come out-of-the-box?
EDIT: PublicClientApplication allows .WithPrompt(Prompt.Login) while ConfidentialClientApplication does not (also does not allow AcquireTokenInteractive) This is a web app so it needs the confidential builder. Tested using the Public builder and it logs in successfully. But I get an ActiveX instantiation error 'not in a single-threaded apartment'(?) Strange, unless that is how the token is being delivered perhaps. I also tested by changing to multitenant in Azure and by toggling Public client on and off.
Any ideas?
You could use ForceLogin to add paramter to ConfidentialClientApplicationBuilder.
ForceLogin: enables the application developer to have the user prompted for credentials by the service even if this would not be needed. This can be useful if Acquiring a token fails, to let the user re-sign-in. This is done by sending prompt=login to the identity provider. Again, we've seen it used in some security focused applications where the organization governance demands that the user re-logs-in each time they access specific parts of an application.
So, use the code as below:
result = await app.AcquireTokenInteractive(scopes)
.WithPrompt(Prompt.ForceLogin)
.ExecuteAsync();
The Modifier .WithExtraQueryParameters will not help you. You need to use .WithPrompt instead.Please refer article.
Example:
await PublicClientApplication
.AcquireTokenInteractive(scopes, null)
.WithAccount(CurrentUser)
.WithPrompt(Prompt.ForceLogin) // use login for your case
.ExecuteAsync();
I eventually resolved this as follows:
Under Notifications in the ConfigureAuth(IAppBuilder app) add a reference to a new task:
RedirectToIdentityProvider = OnRedirectToIdentityProvider,
Then add the task:
private Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification
<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
{
// Forces the user to login.
if (notification.ProtocolMessage.Prompt == null)
{
notification.ProtocolMessage.Prompt = "login";
}
return Task.FromResult(0);
}
Hope that helps the next person with this issue.
I am developing an app that syncs with my google calendar with my database.
I Have everything running, but I have a problem.
Every time I do an action (add, delete, update) on my google calendar I receive multiple push notifications for the same event, and after a few events, I get blocked by Google services (403-user-rate-limit-exceeded).
to every notification i am answering with the proper status code, here is my code:
[HttpPost, Route("notifications")]
public HttpResponseMessage Notifications()
{
try
{
this.googleCalendarService.PerformEventsSync();
var response = this.Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent("200");
return response;
}
catch (Exception e)
{
log.Error(e);
return this.Request.CreateResponse(HttpStatusCode.InternalServerError);
}
}
Ok, so i found what was going on.
Turns out that while I was debugging and deploying my app I was creating multiple watch channels.
What i did:
Created a variable to save my active channel id and it's expiration time
On each received notification I retrieve the header "X-Goog-Channel-ID"
Before preforming my sync I assure that its comming from the correct channel (my app can only have one channel)
When my expiration time is coming to an end I refresh my channel
Thank you
I have an ASP.NET Core application with work & school account authentication as configured by Visual Studio 2015 Update 3. I'm trying to integrate Microsoft.Graph with my application. Specifically, I'm trying to obtain user information (name, department, mail, about me, etc.) from the currently logged in user.
Following the samples for previous versions of ASP.NET MVC, I managed to make the following code work.
var token = await GetAppTokenAsync(authStringMicrosoft, graphResourceId);
var authHelper = new AuthenticationHelper() { AccessToken = token };
var graphClient = new GraphServiceClient(authHelper);
var users1 = await graphClient.Users.Request().GetAsync();
var users2 = await graphClient.Users.Request().Select("mail,givenName,surname").GetAsync();
This code is placed on the OnTokenValidated callback of OpenIdConnectEvents within OpenIdConnectOptions, on my Startup class.
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions {
// ...
Events = new OpenIdConnectEvents {
OnTokenValidated = async ctx => {
// right here
}
}
});
So far, both calls to Users work great, and the code retrieves me a list of users with the specified properties. However, whenever I try to get data from the Me property, I get an error, as described below.
User me = await graphClient.Me.Request().GetAsync();
Error:
Code: Request_ResourceNotFound
Message: Resource '65c4885a-b493-4b8d-861f-79f0b8c23ec4' does not exist
or one of its queried reference-property objects are not present.
Inner error
I don't get why am I getting this error. I have checked the permissions for the application in the Azure Management Portal, both for Windows Azure Active Directory and Microsoft Graph applications. As a test, I checked everything that is to check, and still get this error.
So, my question is: why I get this error? Do I need to add a different permission, do I need to include anything else?
Thank you in advance.
From the sample code, it looks like app token is used here. /me request is not valid in context where app token (obtained by client_credential flow) is used. It is valid only in the context of access token obtained by authorization code flow (also referred to as 3-legged flow). If you can share request-id header from the error response along with timestamp, I can confirm.
I'm trying to test out Xamarin.Auth with Facebook on Xamarin.iOS. I can login via the web view and get redirected but the Completed handler is never called. After some investigation, it looks like a common problem that users have is with this code from WebRedirectAuthenticator.cs
private bool UrlMatchesRedirect (Uri url)
{
return url.Host == redirectUrl.Host && url.LocalPath == redirectUrl.LocalPath;
}
which controls whether the Completed event is raised.
As far as I can tell I have everything set up correctly both in code and in the Facebook developer console.
Redirect URL's in Facebook developer console
URL's
Authenticator
However, the process never continues past this point
When you are testing are you using the same account as the Facebook app / developer account is setup on? If so try testing with a normal account.
I could be wrong but have a vague memory or hitting something similar once
Try removing the s from "https". Your variable declaration should look like this:
FACEBOOK_REDIRECT_URL = "http://www.facebook.com/connect/login_success.html"
I'm trying to send a push notification to my Windows Store App developed in my laptop using VS 2013 Express. It's been few days now but I cannot figure out why I get "The Token obtained from the Token Provider is wrong" error. I use Windows Azure Notification Bus for this purpose. I use VS Server Explorer to send test notifications. I can see my laptop is being registered as a device in the Device Registration tab too. I tried the Azure portal as well, but the same error. However, when I try to connect to Service Bus Explorer 2.4.3.0 providing the connection string it throws below error.
<21:47:14> Exception: The remote server returned an error: (401) Unauthorized. Manage claim is required for this operation..TrackingId:c0c4fea2-08bc-4def-964c-ec6e690b7551_G45,TimeStamp:10/12/2014 4:17:11 PM. Method b__7e: retry 2 of 10.
FYI: I'm following below article step by step.
http://azure.microsoft.com/en-us/documentation/articles/notification-hubs-windows-store-dotnet-get-started/
Please help me. Thank you.
Mahesh
Looks like token is just expired. Make sure you obtain token each time application starts. In terms of the article you refer it means you should call method InitNotificationsAsync() to do it. Here is that method:
private async void InitNotificationsAsync()
{
var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
var hub = new NotificationHub("<hub name>", "<connection string with listen access>");
var result = await hub.RegisterNativeAsync(channel.Uri);
// Displays the registration ID so you know it was successful
if (result.RegistrationId != null)
{
var dialog = new MessageDialog("Registration successful: " + result.RegistrationId);
dialog.Commands.Add(new UICommand("OK"));
await dialog.ShowAsync();
}
}