7

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()
             });
        }
G A
  • 67
  • 2
  • 13
anthonyhumphreys
  • 1,051
  • 2
  • 12
  • 25

1 Answers1

5

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.

Adrian Hall
  • 7,990
  • 1
  • 18
  • 26
  • Oh wow the man himself. Thank you so much for your blog - it is a great asset to the community:) I will take a look at what you have said tomorrow. Thank you for you assistance. – anthonyhumphreys Jul 04 '16 at 23:32
  • One further question - What call should I be making from the front end to azure to authorize? – anthonyhumphreys Jul 05 '16 at 22:10
  • 1
    @anthonyhumphreys See [Add authentication to your Apache Cordova app](https://azure.microsoft.com/en-us/documentation/articles/app-service-mobile-cordova-get-started-users/). – lindydonna Jul 05 '16 at 23:43
  • Thanks for the link, I had seen this and followed it to enable FB, Twitter etc...what i am trying to do now is add an *additional* alternative login using auth0. I do the auth0 login and set the token to the azureClient.currentUser.~token object attribute and then call a table method, but i get a 401 back. – anthonyhumphreys Jul 06 '16 at 00:05
  • 1
    I'd recommend that you enable FB, Twitter, etc. in Auth0 instead - this allows you a single authentication provider. – Adrian Hall Jul 06 '16 at 17:23
  • Okay, will follow that pattern :) Cheers – anthonyhumphreys Jul 06 '16 at 19:00
  • This is now working except when I enable [Authorize] on the controllers i get a 401 back. The token side of things appears to be resolved, but they are not being allowed to auth against my controllers – anthonyhumphreys Aug 15 '16 at 12:37
  • 1
    You would need to do a custom authentication to swap the Auth0 token for a ZUMO-AUTH token. See this for the general process: https://adrianhall.github.io/develop-mobile-apps-with-csharp-and-azure/chapter2/custom/#using-third-party-tokens - you will have to translate to the cordova version instead of the .NET version. – Adrian Hall Aug 17 '16 at 22:59
  • Oh I see...I followed your guide here to get to where I am at which you say was intended to avoid the need for swapping tokens? https://shellmonger.com/2016/04/08/30-days-of-zumo-v2-azure-mobile-apps-day-5-custom-authentication/ – anthonyhumphreys Aug 21 '16 at 14:20
  • @AdrianHall any ideas? Desperate here :p – anthonyhumphreys Aug 28 '16 at 11:11
  • @AdrianHall I awarded you the bounty as you're the only one to have responded. I would still appreciate clarification of your blog post though as I followed your steps to the letter but I'm getting 401s - your blog post says you DO NOT need to create a custom auth solution to handle the use case! – anthonyhumphreys Aug 28 '16 at 18:32
  • I've completed the Authentication chapter for the book now - you can read it here: https://adrianhall.github.io/develop-mobile-apps-with-csharp-and-azure/ – Adrian Hall Sep 06 '16 at 17:26
  • Awesome, will take a look, this issue is still driving me crazy :( Thanks for your hard work – anthonyhumphreys Sep 07 '16 at 00:06