We just released many updates to the .NET backend of Azure Mobile Services, including:
- Custom scopes from authentication providers
- Single sign-on support for Windows Store applications
- Updated dependency to Web API 5.2
If you are new to Azure Mobile Services .NET then
check out this great overview and
here is more information about Azure Mobile Services in general.
Getting the updates
As has been the case, you can get the latest updates to your project via the NuGet Package Explorer. Right-click the project node or the references node in your project in the solution explorer, then select the “Manage NuGet Packages” option:

In the NuGet dialog, select the “Updates” option in the left, and type “mobileservices” in the search box. You should see the latest version of the mobile services-related packages, with the latest version (1.0.402). Select the packages and click the “Update” button.

Notice: there are some dependencies which cannot be updated at this moment, so don’t use the “Update All” button. If you update only the mobile service-related packages, it will automatically update any dependencies that it works well with.
Custom Scopes for Social Authentication Providers
This has been a long-standing feature request, which is
present in the node.js backend. When you log in to the .NET backend, you can ask in the server for a token to talk to the authentication providers. By default, the token only grants some basic information about the user. Now, in the .NET backend, you can also request additional login scopes so that the access token which you receive at the server can be used to retrieve more information from the authentication provider. Like in the node.js backend, this feature is available for Facebook, Google and Microsoft accounts. Like in the node.js backend, the login scopes can be defined using app settings, which can be set in the “configure” tab in the portal:
MS_FacebookScope,
MS_GoogleScope and
MS_MicrosoftScope (for Facebook, Google and Microsoft accounts, respectively).
Let’s look at an example of those scopes being used. I’ve
set up a .NET mobile service with authentication with two of the providers mentioned above (Facebook and Microsoft). I’ll also add a controller that talks to the providers to retrieve information about the logged in user:
public class UserInfoController : ApiController
{
public ApiServices Services { get; set; }
[AuthorizeLevel(AuthorizationLevel.User)]
public async Task<JObject> GetUserInfo()
{
ServiceUser user = this.User as ServiceUser;
if (user == null)
{
throw new InvalidOperationException("This can only be called by authenticated clients");
}
var identities = await user.GetIdentitiesAsync();
var result = new JObject();
var fb = identities.OfType<FacebookCredentials>().FirstOrDefault();
if (fb != null)
{
var accessToken = fb.AccessToken;
result.Add("facebook", await GetProviderInfo("https://graph.facebook.com/me?access_token=" + accessToken));
}
var ms = identities.OfType<MicrosoftAccountCredentials>().FirstOrDefault();
if (ms != null)
{
var accessToken = ms.AccessToken;
result.Add("microsoft", await GetProviderInfo("https://apis.live.net/v5.0/me/?method=GET&access_token=" + accessToken));
}
return result;
}
private async Task<JToken> GetProviderInfo(string url)
{
var c = new HttpClient();
var resp = await c.GetAsync(url);
resp.EnsureSuccessStatusCode();
return JToken.Parse(await resp.Content.ReadAsStringAsync());
}
}
Then, we can have an application that authenticates and gets information about its user. For this example, I’ll use a simple app with buttons for each of the authentication providers mentioned above.
public sealed partial class MainPage : Page
{
public static MobileServiceClient MobileService = new MobileServiceClient(
"https://blog20141002.azure-mobile.net/",
"yourapplicationkeyshouldbehere00"
);
public MainPage()
{
this.InitializeComponent();
}
private async void btnFacebook_Click(object sender, RoutedEventArgs e)
{
await LoginAndGetUserInfo(MobileServiceAuthenticationProvider.Facebook);
}
private async void btnMicrosoft_Click(object sender, RoutedEventArgs e)
{
await LoginAndGetUserInfo(MobileServiceAuthenticationProvider.MicrosoftAccount);
}
private async Task LoginAndGetUserInfo(MobileServiceAuthenticationProvider provider)
{
try
{
var user = await MobileService.LoginAsync(provider);
Debug("Logged in as {0}", user.UserId);
var userInfo = await MobileService.InvokeApiAsync("userInfo", HttpMethod.Get, null);
Debug("User info: {0}", userInfo);
MobileService.Logout();
Debug("Logged out");
Debug("");
}
catch (Exception ex)
{
Debug("Error: {0}", ex);
}
}
private void Debug(string text, params object[] args)
{
if (args != null && args.Length > 0) text = string.Format(text, args);
this.txtDebug.Text = this.txtDebug.Text + text + Environment.NewLine;
}
}
If we run the app and login with each of the three providers, we’d get some basic information about the user. For example, this is what I get with my credentials:
Logged in as Facebook:xxxxxxxxxxxxx9805
User info: {
"facebook": {
"id": "xxxxxxxxxxxxx9805",
"first_name": "Carlos",
"gender": "male",
"last_name": "Figueira",
"link": "https://www.facebook.com/app_scoped_user_id/xxxxxxxxxxxxx9805/",
"locale": "en_US",
"name": "Carlos Figueira",
"timezone": -7,
"updated_time": "2013-12-12T04:09:57Z",
"verified": true
}
}
Logged out
Logged in as MicrosoftAccount:xxxxxxxxxxxxd789
User info: {
"microsoft": {
"id": "xxxxxxxxxxxxd789",
"name": "Carlos Figueira",
"first_name": "Carlos",
"last_name": "Figueira",
"link": "https://profile.live.com/",
"gender": null,
"locale": "en_US",
"updated_time": "2014-09-30T09:38:42Z"
}
}
Logged out
That’s some basic information, but if my application also needed the user’s e-mail or some other information, the access token granted by the service login didn’t have access to that. But if we request additional scopes during the login, by setting the
MS_FacebookScope and
MS_MicrosoftScope app settings, we’d get the additional information we need:

And running the client app again we’d get the newly requested information (after the user grants the application access to the additional info).
Logged in as Facebook:xxxxxxxxxxxxx9805
User info: {
"facebook": {
"id": "xxxxxxxxxxxxx9805",
"birthday": "xx/yy/zzzz",
"email": "xxxxxxxxxxxxxxxxxxx@hotmail.com",
"first_name": "Carlos",
"gender": "male",
"last_name": "Figueira",
"link": "https://www.facebook.com/app_scoped_user_id/xxxxxxxxxxxxx9805/",
"locale": "en_US",
"name": "Carlos Figueira",
"timezone": -7,
"updated_time": "2013-12-12T04:09:57Z",
"verified": true
}
}
Logged out
Logged in as MicrosoftAccount:xxxxxxxxxxxxd789
User info: {
"microsoft": {
"id": "xxxxxxxxxxxxd789",
"name": "Carlos Figueira",
"first_name": "Carlos",
"last_name": "Figueira",
"link": "https://profile.live.com/",
"gender": null,
"emails": {
"preferred": "xxxxxxxxxxxxxxxxxxx@hotmail.com",
"account": "xxxxxxxxxxxxxxxxxxx@hotmail.com",
"personal": null,
"business": null
},
"locale": "en_US",
"updated_time": "2014-09-30T09:38:42Z"
}
}
Logged out
One final note about requesting additional scopes: as a good general rule, only request the minimum information you need from the user. Many users don’t like giving out a lot of information to the apps they use, so they may simply give up using your app just because they’re being asked too much when logging in.
Single Sign-On Support for Windows Store Applications
When you use the mobile services SDK in a Windows Store application, every time the app calls the method
LoginAsync
in the
MobileServiceClient
passing the authentication provider the authentication window is show, and the user has to enter their credentials and click the “sign in” button in the authentication page – even if the user selected the “remember me” button in the provider’s login page (Windows may have cached the credentials so that they don’t need to be entered, but the user still needs to click the button to log in). That’s because by default the cookies from an authentication session are not preserved, so that when the provider page is shown again, there will be no cookies from a previous authentication to identify the user. There’s an
overload to LoginAsync which takes an additional flag which indicates that the client should cache the cookies in the authentication sessions, so that the next time
LoginAsync
is called, the authentication dialog will just be shown briefly and then automatically dismissed, making for a better user experience.
In the client shown in the previous section, all we need to do is to use the additional overload and pass
true to the second parameter of
LoginAsync
.
private async Task LoginAndGetUserInfo(MobileServiceAuthenticationProvider provider)
{
try
{
var user = await MobileService.LoginAsync(provider, true);
Debug("Logged in as {0}", user.UserId);
var userInfo = await MobileService.InvokeApiAsync("userInfo", HttpMethod.Get, null);
Debug("User info: {0}", userInfo);
MobileService.Logout();
Debug("Logged out");
Debug("");
}
catch (Exception ex)
{
Debug("Error: {0}", ex);
}
}
There’s one change which needs to be done in the server side as well, if you haven’t yet. To enable this scenario, the application needs to be associated with an app in the Windows Store, since the package SID (one of the app identifiers) for that application needs to be stored in the service. You will get a package SID by creating the app in the
Windows Store Dashboard, and you can see how to find that value in the tutorial to
register the app package for Microsoft authentication. If your app will not use Microsoft authentication (for example, use Facebook or Twitter), you won’t need to copy the client id / secrets, but you’ll still need to copy the package SID in the
microsoft account settings under the
identity tab in the portal.
Support for ASP.NET Web API 2.2
With this update the .NET backend now supports ASP.NET Web API 2.2 (or the version 5.2.x of the
Microsoft.AspNet.WebApi.Owin NuGet package). With that you can now take advantage of all the new features and bug fixes from that release, such as attribute routing improvements and OData v4. The full list of changes can be found in “
What’s New in ASP.NET Web API 2.2”.
Wrapping up
That’s it. We hope that those features will be helpful. As usual, please send us feedback either as comments in this post, via twitter
@AzureMobile or in our
MSDN forums.