Tag: Azure

Configuring Azure AD B2C & ASP.NET 5.0 MVC Web Applications

There are a number of solutions available these days for identity management. One easy & cheap solution for small ASP.NET applications is Azure AD. With Azure AD B2C you get your first 50,000 MAUs (Monthly Active Users) free. It can however be a little daunting to figure out exactly how to get things set up.. This post is intended as a quick guide to getting up and running with Azure AD B2C and ASP.NET Core 5.0.

To start off with you will need to set up your directory in the Azure Portal.

Step 1: Create Your Azure AD B2C Directory

To get started log into your Microsoft Azure Portal and navigate to “Home”. Once on the home page click the “Create a resource icon near the top of the page.

In the search box type in “b2c” and select “Azure Active Directory B2C” from the list. This will navigate you to the Azure Active Directory B2C Page.

Next click the “Create” button near the top of the page. This will take you to “Create new B2C Tenant or Link to existing Tenant”.

Click “Create a new Azure AD B2C Tenant”.

On the “Create a tenant” page you will need to provide a name for your tenant (Organization name), a domain name, choose your country, a subscription and resource group. (Additionally, if you choose to create a new resource group, you will need to select a region.)

Now click “Review + Create” and then if everything looks correct, click “Create”.

It will take a few minutes to create your new directory. Once it completes the page will update with a link to your new tenant.

Follow the link to your new tenant.

Step 2: Configure User Flows

Now that we have our directory created it’s time to start configuring things for our application. To start off we’ll set up our user flows. The configuration of the user flows in your Azure B2C Directory determines what happens when one of the flows is triggered. The most common flow is “Sign up and Sign in”. This flow is how users actually sign into Azure AD B2C or sign up for an account in your directory so they can use your application. (You can also split these into 2 separate flows if you wish.) To get started click on the “User Flows” item under “Policies” in the left navigation bar.

You should now see the list of flows that have been configured for your directory, but the list is empty. Let’s start by adding a “Sign Up and Sign In” flow. To do that click the “New user flow” button near the top of the page.

Next select the “Sign up and sign in” button under “Select a user flow” then select “Recommended” (If you still have the option!) and finally the “Create” button.

On the “Create” page there are 5 distinct, numbered sections to complete.

Name
You can choose any unique name you would like here, but I prefer to keep it simple and just go with SignUpIn. (The whole name will be B2C_1_SignUpIn.)

Identity Providers
Since we just set up our directory, we will only have one option here which is “Email signup”. Later on you can enable third party login providers, but setting that up is probably another post unto itself. Just select the radio button and move on to the next step.

Multifactor Authentication
Under the multifactor authentication heading there are 2 groups of options. The first group allows you to select what form of multifactor authentication to choose (Email, SMS or Phone Call, SMS Only, or Phone call only).

The second set of options is for enforcement of MFA. The options are Off, Always on, and Conditional. With conditional set you are delegating the decision to require MFA to Azure B2C’s Conditional Access Policies that will determine at runtime the risk level associated with the login and automatically require it if needed based on the policies rules.

Since we are doing a demo here, and there is a charge associated with MFA usage I will, choose Email & Off for our configuration.

Conditional Access
Under this heading there is a single checkbox to enable the aforementioned Conditional Access policies. For now I will also leave this off (Unchecked)

User Attributes and Token Claims
The last section is where we can select which user attributes are collected when a user signs up and which attributes are returned in your token responses when a user is authenticated. At the bottom of the list on the page is a link that opens up the full list you have to choose from. I’m going to select the following options from the fly-out for the demo.

Finally, click the “Create” button at the bottom of the page to create your new flow.

Additional Flows

I am also going to set up two additional flows for profile editing and password reset named “B2C_1_EditProfile” & ” B2C_1_ PasswordReset” so we can demo triggering those flows from our application as well. Setting these up is the same as setting up the Sign up and sign in policy we set up previously. Just choose the correct flow for each and set the options the same way we set them in the previous step.

Step 3: Setup Your B2C Application

To get started setting up our application in Azure B2C, click “App registrations” in the left navigation bar ad then click the “New registration” button near the top of the page.

To complete app registration you will need to fill in a “Name” and a “Redirect URI”. I’ll name mine “NinjaAdDemo” and set the redirect URI to “https://localhost:5001/signin-oidc”.
The rest of the options on the page can be left at their default values. Just click the “Register” button to proceed.

We need to enable implicit flow for our application. You can do that from your application page by clicking on “Authentication” in the left navigation bar and the scrolling down to the bottom of the page and checking both “Access tokens (used for implicit flows)” and “ID tokens (used for implicit and hybrid flows)” and clicking the save button at the top of the page.

Now that your application is set up, it’s to to write some code!

Step 4: Configure Middleware In Your Application

For our demo I’ve created an MVC Web application running on .NET 5.0 using the command:

dotnet new mvc -n DotNetNinja.Samples.AzureAD

The first this we will need to do is add a couple of NuGet packages. (You’ll want to run these commands from inside your project directory, or you can add them using the Package Manager inside Visual Studio if you prefer.)

dotnet add package Microsoft.Identity.Web 
dotnet add package Microsoft.Identity.Web.UI

Next, in your editor of choice (I’ll assume Visual Studio), we’ll need to add open up your StartUp.cs file and add a few lines inside the ConfigureServices method so it looks like this:

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMicrosoftIdentityWebAppAuthentication(Configuration, "AzureAdB2C");

            services.AddControllersWithViews().AddMicrosoftIdentityUI();

            services.AddRazorPages();
        }

And we’ll need to add a few lines into our Configure method as well (specifically we are adding the app.UseAuthentication() & endpoints.MapRazorPages() lines):

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
                endpoints.MapRazorPages();
            });
        }

Step 5: Add Configuration

Now to configure our application. When using the Microsoft.Identity.Web middleware it will assume it can find the configuration in your application settings. If you notice above when we specified a config section named ” AzureAdB2C ” as the second parameter to the AddMicrosoftIdentityWebAppAuthentication method. Let’s add that section now:

{
  "AzureAdB2C": {
    "Instance": "https://<YOUR-DIRECTORY-NAME>.b2clogin.com",
    "Domain": "<YOUR-DIRECTORY-NAME>.onmicrosoft.com",
    "TenantId": "<YOUR-TENANT-ID>",
    "ClientId": "<YOUR-CLIENT-ID>",
    "SignUpSignInPolicyId": "B2C_1_SignUpIn",
    "ResetPasswordPolicyId": "B2C_1_PasswordReset",
    "EditProfilePolicyId": "B2C_1_EditProfile",
    "CallbackPath": "/signin-oidc",
    "SignedOutCallbackPath ": "/signout-callback-oidc"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

The actual values for this configuration come from your app configuration in the AzureAD B2C Portal.

Your directory name can be found one the directory overview page.

Step 6: Add A Protected Page

So that we can see things actually working we are going to add a few UI elements. Let’s start by adding a Secure() method to our HomeController.cs that returns the User as a model to the view and mark it with the Authorize attribute.

[Authorize]
public IActionResult Secure()
{
    return View(User);
}

The we’ll add a razor view ~/Views/Home/Secure.cshtml.

@model System.Security.Claims.ClaimsPrincipal
<div class="row">
    <h1>@Model.Identity.Name</h1>
    <table class="table table-striped">
        <thead>
            <tr>
                <th>Claim</th>
                <th>Value</th>
            </tr>
        </thead>
        <tbody>
            @foreach(var claim in Model.Claims.OrderBy(c=>c.Type))
            {
                <tr>
                    <td>@claim.Type</td>
                    <td>@claim.Value</td>
                </tr>
            }
        </tbody>
    </table>
</div>

Lastly, let’s add some navigation to our menu so we can get to our secure page and some links to sign in, sign out, edit profile & reset password. Replace the navigation in your ~/Views/Shared/_Layout.cshtml file, everything after the closing </button> tag to the </nav> tag, with the following.

<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
    <ul class="navbar-nav flex-grow-1">
        <li class="nav-item">
            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
        </li>
        <li class="nav-item">
            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
        </li>
        <li class="nav-item">
            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Secure">Secure</a>
        </li>
    </ul>
    @if (User?.Identity?.IsAuthenticated??false)
    {
        <ul class="navbar-nav float-lg-right">
            <li class="nav-item dropdown">
                <a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" 
                   role="button" aria-haspopup="true" aria-expanded="false">@User.Identity.Name</a>
                <div class="dropdown-menu">
                    <a class="dropdown-item" asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="EditProfile">
                        Edit Profile
                    </a>
                    <a class="dropdown-item" asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="ResetPassword">
                        Reset Password
                    </a>
                    <div class="dropdown-divider"></div>
                    <a class="dropdown-item" asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="SignOut">
                        Sign Out
                    </a>
                </div>
            </li>
        </ul>
    }
    else
    {
        <ul class="navbar-nav float-lg-right">
            <li class="nav-item">
                <a class="nav-link text-dark" asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="SignIn">Sign In</a>
            </li>
        </ul>
    }
</div>

Note all the links for anything related to our user flows (sign in, sign out, edit profile, and reset password) are all going to endpoints in the MVC area “MicrosoftIdentity”. These are endpoints provided by the Microsoft.Identity.Web.UI assembly that we referenced and configured earlier, and they handle all the details of making the properly formatted request to Azure AD B2C. All you need to do is link to them, or redirect to them to handle any interaction with your B2C directory.

Step 7: Try it out!

Now for the fun part! Let’s run our application and give it a try.

Try clicking on the “Secure” menu item. You should be redirected to Azure B2C to sign in. (First time through you can click the link to sign up on the bottom of the login form.)

Once you are signed in you should redirect back the the secure page.

Checkout the other flows using the links under your display name as well once you are logged in.

Final Thoughts

While there are a lot of steps involved in setting this up, once you get used to working with Azure B2C it’s actually pretty quick to set up a new directory and get things up and running. You can also customize the login experience. (Maybe we’ll look at that in a future post, stay tuned!)

Resources

Source Code

DotNet-Ninja/DotNetNinja.Samples.AzureAD: Sample ASP.NET MVC application integration with Azure AD (github.com)

Continuous Integration/Deployment Using GitHub, AppVeyor & Microsoft Azure Websites

There are plenty of tools available these days that a developer or development team can use to set up continuous integration/deployment.  AppVeyor is one such tool that I first heard about last spring (May 2014) when reading a post by Scott Hanselman entitled “AppVeyor – A good continuous integration system is a joy to behold“.   I thought it sounded pretty interesting and so I gave it a try.  It was so easy and simple to set up that I had builds up and running in 15 minutes and I had it deploying to my Azure Websites account in under 30 minutes!

Getting up and running is straight forward assuming you already have GitHub and Azure accounts. These aren’t hard to set up either, but for the purpose of this demo I’ll be assuming you already have one of each.  (Everyone does right?)  To demonstrate how to get things set up I have created a little demo site and checked it into GitHub.  It’s a very simple project which is basically the default ASP.NET MVC template.  I’ve stripped out a few of the endpoints, changed the text on the one remaining page and added in some unit tests that can be run as part of our build.  I’ll probably add onto this site later for other demos or just for fun, but for now this will be adequate for us to take a look at the build and deployment process using GitHub, AppVeyor and Microsoft Azure Websites.

Getting Set Up On AppVeyor

Now that we have an ASP.NET project on GitHub we can get started setting up AppVeyor to build our project.  The first step is to set up our account.  At the time of this writing there is a big green button labeled “SIGN UP FOR FREE” right on the home page.  Click that button, select a plan (I’m choosing the “Free – for open-source projects” option), and choose log in with GitHub.  You can also select BitBucket or Visual Studio Online if you would like to use one of those services instead.  I have not tried them, but I would assume they work exactly the same.

AppVeyor Sign Up Screen

Once you log into GitHub you will be presented with an authorization screen from GitHub.com asking you to confirm that you would like to authorize AppVeyor to access your account.  Click “Authorize application” to authorize AppVeyor and continue with set up.

GitHub Authorization ScreenNext you’ll see the project screen which will be empty at this time except for large item that says “+ NEW PROJECT”.  Click this link to add a new project to your account.   This will take you to a page to select the source control repository you would like to pull from.  The page will default to GitHub and after a few seconds your GitHub Repositories will appear.  If you now hover over the repository you would like to add a button will appear to the right so that you can add the repository.  Click the add button.

Select Repository GitHub - Add

Your First Build

At this point you should have things configured enough to build your repository.  Simply click the “New Build” button on the right to start a build!

Build QueuedNotice that the build is now queued up, the site has pulled in the commit message, time and author and it has automatically incremented our version number to version 1.0.1.  We can manipulate these version numbers in the settings if we wish as well allowing us to make it version 2.0, 2.1, etc.  The server will simply keep incrementing the build number.

Once the build actually begins we will be able to view the console output.

Build Console Output

And once it completes we will get a success or failure message.

Build Success

Notice the green “Build Success” message.  We now have everything configured and any time we commit on the master branch a build will be triggered.  We can customize the branches that build etc. in the settings which I will dig into in a later post.

Also note here that the server has automatically detected and run our unit tests!  Had any of our tests failed the server would have failed the build as well.

Setting Up Azure Websites

The first thing we will need to do in order to deploy our site to Azure is create the site in Azure.  If you already have done this or your site is already live on Azure go ahead and skip ahead to the next step – Configuring Deployment.

Start off by going to the Microsoft Azure Portal (https://manage.windowsazure.com/) and once you are logged in click the “WEBSITES” link on the left side bar and then click the New button in the lower left corner.

Portal Websites

A panel will appear at the bottom of the screen.  Select “COMPUTE”, “WEBSITE” & “CUSTOM CREATE”.

New Compute Website Custom Create

Enter a URL for your website and click the check mark button.

Custom Create Dialog

After a little churning your site will be created.  While we are here there is a little piece of information we will need later, so let’s get that now.  Click on your new site in the websites list to view the details.

Website details

Now click the “Download the publish profile” link on the right side of the page and save it off to your local disc for later use.

Configuring Deployment

To configure your deployment go back to AppVeyor, select your project, click settings and then when the settings page loads go to the build section (third item down the left side).  You’ll need to be sure the option “Package Web Application for Web Deploy” is checked and then save your changes.

Build Settings - Package for MS Deploy

Next go down to the Deployment section (three more items down).  First click “Add Deployment” to add your first deployment and get started configuring it.  You’ll need to select the “Web Deploy” deployment provider.  This is where we need the info in the publish settings file we saved earlier.  Specifically we need the settings publishUrl,  msdeploysite, username, and userPWD.  These values go into the fields in the deployment section as follows:

Server = https: //[publishUrl]/msdeploy.axd?site=[msdeploySite]
Website Name = [msdeploySite]
Username = [username]
Password = [userPWD]

You will also want to turn off NTLM.

Deployment Settings

Click the “Save” button and we should be ready to give it a try.  To start a new build click “LATEST BUILD” and then “NEW BUILD”.  Assuming we’ve done everything correctly a build of your project will queue up and if it is successful it should deploy to you site on Microsoft Azure.

The site is at: http://dependencyinjector.azurewebsites.net/
The GitHub Repository is at: https://github.com/dependencyinjector/dependencyinjector
The AppVeyor Build Information is at: https://ci.appveyor.com/project/lahouse/dependencyinjector

Resources

Documentation:
http://www.appveyor.com/docs/deployment/web-deploy#provider-settings

Scott Hanselman’s Blog Post: http://www.hanselman.com/blog/AppVeyorAGoodContinuousIntegrationSystemIsAJoyToBehold.aspx

The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.

Today was the first time I have worked on our Azure application in quite a while, so I was unpleasantly surprised when I got the latest version of the code, clicked run and was greeted with :

The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.

CommunicationObjectFaultedException

After a lot of poking around and reinstalling the SDK I finally found the solution.  Apparently when running an application under Azure SDK version 1.3 the development environment needs to modify the web config in some way.  However, since I am using TFS for source control, the file was marked readonly and could not be edited.

The work around seemed pretty simple, just remove the readonly flag and off we go.  The next problem is that every time you get latest from source control the file gets marked readonly again and now it won’t run. 🙁  To get around this just add a post-build command to your project to automatically remove the readonly flag when you run your project.   To do this right-click on your project in the Solution Explorer and select properties.  Go to the Build Events tab and enter the command : attrib -r “$(ProjectDir)Web.Config” .

attrib -r "$(ProjectDir)Web.Config"

Deploying ASP.Net MVC3 to Windows Azure

So the first question is can I run an ASP.Net MVC3 WebRole on Windows Azure?   The short answer is yes.  The long answer is, well long.  First off the tooling in Visual Studio 2010  does not directly support creating an ASP.Net MVC3 Webrole (pre SP1 at least, I haven’t beenable to install the SP yet so I can’t comment on the support with that installed, but I hear it will get better), so you have to do it manually.
To get things set up was pretty straight forward, just create your new ASP.Net MVC3 web application,
New ASP.Net MVC3 Application
and then add a new Windows Azure Project to the solution.
New Windows Azure Project
Now you will have to wire up the web role in your Azure Project.  To do this right-click on the Roles folder under your Azure Project and select Add | Web Role Project In Solution and select your project.
Assuming that you have done some work in your ASP.Net MVC3 Project and it is working and ready to deploy there is one more item you’ll need to address.   The Window Azure Hosted Services will not by default have all the assemblies you need to run your site.  To get around this you have a couple of options.  The way I did it was to make sure I had references to these assemblies (you may not since MVC apparently dynamically loads some of them at run time), and then for each one I went to properties and set CopyLocal to True.
Here is the list of assemblies I had to add.
  • System.Web.Mvc
  • Microsoft.Web.Infrastructure
  • System.Web.Razor
  • System.Web.WebPages
  • System.Web.WebPages.Razor
  • System.Web.Helpers
  • System.Web.WebPages.Deployment

Your list may be slightly different.  If you miss one you will get a “Yellow Screen of Death” .

Error Sample

Just add that assembly to your list and try again…

Good Luck!