Reputation: 1961
I'm creating a Xamarin.Forms PCL application that uses Azure B2C to authenticate users. I was previously using Microsoft.Identity.Client
version 1.0.304142221-alpha but I just updated to 1.1.0-preview after it came out on NuGet.
I'm also using the Azure MobileServiceClient
to login users so only authenticated users can make calls to my tables.
I am able to successfully authenticate, which I set up like this sample on GitHub.
Using the previous version of Microsoft.Identity.Client
, I was able to login to the MobileServiceClient
like this:
AuthenticationResult ar = await App.AuthenticationClient.AcquireTokenAsync(Config.Scopes,
string.Empty, UiOptions.SelectAccount, string.Empty, null,
Config.Authority, Config.SignUpSignInpolicy);
JObject payload = getPayload(ar.IdToken);
payload["access_token"] = ar.Token;
string objectId = payload["oid"].ToString();
MobileServiceUser u = await App.MobileService.LoginAsync(MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory,
payload);
However, after the update, AuthenticationResult
no longer has a member named Token
. Instead, it has AccessToken
, which for me, is always returning null
.
I have tried logging into the MobileServiceClient
using the IdToken
, but this produces an unauthorized error.
I think this problem could have something to with the scopes I define. Right now I have:
public static string[] Scopes = { "https://<MyTennant>/<MyAPIName>.read"};
Are there any scopes that I'm missing to get the AccessToken
or is the problem somewhere else?
Update: Here are my settings in the Azure Portal
For my API:
In my App, I'm logging in like this:
AuthenticationResult ar = await App.AuthenticationClient.AcquireTokenAsync(Scopes,
GetUserByPolicy(App.AuthenticationClient.Users, PolicySignUpSignIn),
App.UiParent);
payload = getPayload(ar.IdToken);
payload["access_token"] = ar.IdToken;
var mobileService = new Microsoft.WindowsAzure.MobileServices.MobileServiceClient("https://giftthis.azurewebsites.net/.auth/");
MobileServiceUser u = await mobileService.LoginAsync(MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, payload);
LoginAsync
is now executing, but it returns null so I still can't make calls to the tables.
Upvotes: 0
Views: 1546
Reputation: 14649
I am trying to test this issue using the Microsoft.Identity.Client
version 1.1.0-preview, however it works well for me.
The mobile app was protected using Azure AD B2C app with Advanced mode and set the ALLOWED TOKEN AUDIENCES using the app id like figure below:
After that I used the MobileServiceClient
from Azure Mobile Client SDK. And to new the MobileServiceClient
we only need to provide the mobile application URL as code below:
string applicationUrl = "https://mobilefei.azurewebsites.net/";
var mobileClient = new MobileServiceClient(applicationUrl);
However if I used the MobileServiceClient
from Azure Mobile Services SDK
, I can reproduce the same issue with 401 error. In this scenario, when we need append .auth
to initialize the MobileServiceClient
like code below:
string applicationUrl = "https://mobilefei.azurewebsites.net/.auth/";
var mobileClient = new MobileServiceClient(applicationUrl);
string CLIENT_ID = "420a3a24-97cf-46ca-a882-f6c047b0d845";
string[] SCOPES = { "https://xxx.onmicrosoft.com/b2cwebapp/read" };
string Tenant = "xxx.onmicrosoft.com";
string PolicySignUpSignIn = "B2C_1_Sign_In";
string AuthorityBase = $"https://login.microsoftonline.com/tfp/{Tenant}/";
string Authority = $"{AuthorityBase}{PolicySignUpSignIn}";
PublicClientApplication myApp = new PublicClientApplication(CLIENT_ID, Authority);
AuthenticationResult authenticationResult = myApp.AcquireTokenAsync(SCOPES).Result;
Console.WriteLine($"AccessToken:\n{authenticationResult.AccessToken}");
Console.WriteLine($"IdToken:\n{authenticationResult.IdToken}");
//This applicationUrl works for WindowsAzure.MobileServices
//string applicationUrl = "https://mobilefei.azurewebsites.net/.auth/";
//This applicationUrl works for Microsoft.Azure.Mobile.Client
string applicationUrl = "https://mobilefei.azurewebsites.net/";
var mobileClient = new MobileServiceClient(applicationUrl);
JObject token = new JObject();
token.Add("access_token", authenticationResult.IdToken);
var user = mobileClient.LoginAsync(MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, token).Result;
Console.WriteLine($"UserID:\n{user.UserId}");
Console.Read();
Upvotes: 1