7
votes

I currently have a backend solution for my app using Azure Mobile Apps. I have enabled facebook, twitter, google and Microsoft logins. I am attempting to add a custom login flow in addition to this. I have setup an Auth0 account and application and I am able to get a token and profile back from auth0 when I make the request in-app using auth0 lock widget.

I followed this guide: https://shellmonger.com/2016/04/08/30-days-of-zumo-v2-azure-mobile-apps-day-5-custom-authentication/ and got to the stage 'Custom JWT Verification in the Server' but this is where I am stuck...my backend is in C# not node.js so how do I do the equivalent to this tutorial and validate the JWT token and subsequently access the table controllers from my front end application using azureClient.login/azureClient.table?

EDIT: Okay so as you will see in the comment thread below with @AdrianHall I have been successful in generating a token from within my cordova app but my stumbling block is now getting the service to accept it without having to exchange tokens. This is possible according to the guide posted.

This is my client-side code which currently makes the auth call to auth0 and does some client side set up to get a userID and generate the 'currentUser' object containing the new token.

 auth0.lock.show(auth0.options, function(err, profile, token) {
    if (err) {
     console.error('Error authenticating with Auth0: ', err);
     alert(err);
    } else {
     debugger;
     var userID;
     if (profile.user_id.indexOf("auth0") > -1) {
      userID = profile.user_id.replace("auth0|", "");
     } else if (profile.user_id.indexOf("facebook") > -1) {
      userID = profile.user_id.replace("facebook|", "");
     } else if (profile.user_id.indexOf("twitter") > -1) {
      userID = profile.user_id.replace("twitter|", "");
     } else if (profile.user_id.indexOf("microsoft") > -1) {
      userID = profile.user_id.replace("microsoft|", "");
     } else if (profile.user_id.indexOf("google-oauth2") > -1) {
      userID = profile.user_id.replace("google-oauth2|", "");
     }
     window.azureClient.currentUser = {
      userId: userID,
      profile: profile,
      mobileServiceAuthenticationToken: token
     };

     //A client session has now been created which contains attributes relevant to the currently logged in user.

     console.log("window.azureClient.currentUser", window.azureClient.currentUser);
     window.localStorage.setItem("currentUser", JSON.stringify(window.azureClient.currentUser));
     //Call the get profile function which will call our API to get the user's activities and bio etc.
     getProfile();
    }

Backend code MobileAppSettingsDictionary

settings = config.GetMobileAppSettingsProvider().GetMobileAppSettings();

        if (string.IsNullOrEmpty(settings.HostName))
        {
            //This middleware is intended to be used locally for debugging.By default, HostName will

            //only have a value when running in an App Service application.
            app.UseAppServiceAuthentication(new AppServiceAuthenticationOptions
            {
                SigningKey = ConfigurationManager.AppSettings[""],
                ValidAudiences = new[] { ConfigurationManager.AppSettings[""] },
                ValidIssuers = new[] { ConfigurationManager.AppSettings["https://domain.eu.auth0.com/"] },
                TokenHandler = config.GetAppServiceTokenHandler()
             });
        }
1
Thanks for the edit. Shame you couldn't contribute an answer for the bounty.anthonyhumphreys

1 Answers

5
votes

In the Azure Mobile Apps C# backend, there is an App_Start\Startup.Mobile.cs file with the following code:

    MobileAppSettingsDictionary settings = config.GetMobileAppSettingsProvider().GetMobileAppSettings();

    if (string.IsNullOrEmpty(settings.HostName))
    {
        // This middleware is intended to be used locally for debugging. By default, HostName will
        // only have a value when running in an App Service application.
        app.UseAppServiceAuthentication(new AppServiceAuthenticationOptions
        {
            SigningKey = ConfigurationManager.AppSettings["SigningKey"],
            ValidAudiences = new[] { ConfigurationManager.AppSettings["ValidAudience"] },
            ValidIssuers = new[] { ConfigurationManager.AppSettings["ValidIssuer"] },
            TokenHandler = config.GetAppServiceTokenHandler()
        });
    }

The app.UseAppServiceAuthentication call sets up the configuration needed for decoding your JWT. You just need to understand what your Audience (the aud field in the JWT) and Issuer (the iss field in the JWT). In the auth0 case, Audience is your ClientId and Issuer is "https://your-domain-value" - the Client Secret is the signing key

You can verify an example JWT by cut-and-paste at https://jwt.io - this will show explicitly what the values should be and allow you to verify the signature.