Sunday, February 28, 2016

Properly invoking scheduled WebJobs

Recently we've found the need to start using Scheduled Azure WebJobs. However, the examples out there are all gargbage, even in the case where you can find an actual example using a scheduled WebJob rather than a continuous WebJob. So, for the benefit of anyone interested, including future me, here's the proper way to invoke a Scheduled WebJob in the entry point of the WebJobs assembly:

    /// <summary>
    /// The main entry point to the scheduled webjobs.
    /// </summary>
    public class Program
    {
        /// <summary>
        /// Main entry point for the scheduled webjobs
        /// </summary>
        public static void Main()
        {
            IKernel kernel = new StandardKernel();

            kernel.Load(new ServicesScheduledWebJobsNinjectModule());

            var jobHostConfiguration = new JobHostConfiguration
            {
                JobActivator = new ServicesScheduledWebJobsActivator(kernel),
                DashboardConnectionString = ConfigurationManager.ConnectionStrings["AzureWebJobsDashboard"].ConnectionString,
                StorageConnectionString = ConfigurationManager.ConnectionStrings["AzureWebJobsStorage"].ConnectionString,
            };

            var host = new JobHost(jobHostConfiguration);

            // Must ensure that we call host.Start() to actually start the job host. Must do so in
            // order to ensure that all jobs we manually invoke can actually run.
            host.Start();

            // The following code will invoke all functions that have a 'NoAutomaticTriggerAttribute'
            // to indicate that they are scheduled methods.
            foreach (MethodInfo jobMethod in typeof(Functions).GetMethods().Where(m => m.GetCustomAttributes<NoAutomaticTriggerAttribute>().Any()))
            {
                try
                {
                    host.CallAsync(jobMethod).Wait();
                }
                catch (Exception ex)
                {
                    Console.Error.WriteLine("Failed to execute job method '{0}' with error: {1}", jobMethod.Name, ex);
                }
            }
        }
    }

What the above does is the following:

  • Configures the JobHost to use a dependency injection container via a custom IJobActivator implementation that, in our case, uses the Ninject dependency injection container.
  • Configures the JobHost with a custom configuration so that we can control various items, including the connection strings for the dashboard and jobs storage.
  • Starts the JobHost. This bit is important, because all the other examples out there neglect that this needs to be done.
  • Dynamically resolves all schedulable methods that should be invoked, using the NoAutomaticTriggerAttribute built in to the WebJobs SDK. This attribute is used internally by the SDK to determine which methods need to be invoked manually (i.e. on demand) rather than by a continuous invocation used by Continous WebJobs.

Continuous Delivery of Azure Web Services

See this:

https://azure.microsoft.com/en-us/documentation/articles/cloud-services-dotnet-continuous-delivery/

Sunday, February 21, 2016

Debugging Azure web apps on localhost

To get this working, you need to have an app registered with your localhost app root registered for the redirect URI and login URI. Here's the really important part of you're using AAD authentication:

You need to disable all forms of Authorization in IIS and enable Anonymous authentication for the application in the IIS manager on the web app itself so that Azure AD can take over the authentication!

Using adal.js and getting error AADSTS65001: The user or administrator has not consented to use the application with ID '....'

It turns out that you have to actually go in and give your javascript web client permissions to access the web api application in the Azure Active Directory management portal. Go figure.

Using adal.js and getting error AADSTS70005: response_type="token" not supported

I've recently started using adal.js with OData in an AngularJS 1.5 application and been getting this error with attempting to connect my client-side XHR requests to my Web API application.

Following the advice here, changing the AAD manifest of the AngularJS web client from this:

"oauth2AllowImplicitFlow": false

... to this:

"oauth2AllowImplicitFlow": true

... seems to have solved the problem.

Tuesday, February 16, 2016

Getting CORS requests working in Web API 2

I've just recently started playing with using adal.js to connect to Azure Active Directory for authentication so that I can set up an AngularJS => Web API scenario with OData connections.

I followed the page on asp.net here.

However, I'm still running into the following problem: // TODO

Monday, February 08, 2016

How to move a shelveset from one branch to another in TFS

You're going to have to start by installing the TFS PowerTools for TFS 2013 (or whatever version is appropriate for you). Once you have the powertools installed and the tools added to your PATH (if they're not already added by the installer), run a command similar to the following in the command line:

tfpt unshelve /migrate /source:"$/ProjectName/Branch" /target:"$/ProjectName/Targetbranch" "My Shelveset Name"

This will unshelve your shelveset into your new branch for you.

WARNING: Before you do this, make sure you're unshelving into a clean branch with no Pending Changes, otherwise you could inadvertently overwrite or otherwise lose important changes.

Friday, January 22, 2016

Retrieving the list of Service Principals in your Azure subscription(s)

Recently I found that I needed to grant certain users permissions in my applications, specifically I needed to put Service Principals into groups in order to grant them permissions in my application so that they can access protected data.

I found out that in Azure PowerShell, there's the module 'MSOnline', which contains the following pertinent commands:

Connect-MsolService:

Connects your current session to your MSOnline account

Get-MsolServicePrincipal:

Retrieves a listing of all of the Service Principals in your subscription(s)

Monday, January 18, 2016

Enabling manipulation of Azure Active Directory groups through Web Applications via the Azure Graph SDK

In your application(s) (plural if you're using a web / native application delegating to a Web Services API which is doing the actual work), you'll need to go into their pages in the Azure Active Directory management page. Once there, edit the permissions of the applications to include the following:

Under the delegated-to application:

  • Under "Application Permissions", select:
    • Read and write domains
    • Read and write directory data
    • Read directory data
  • Under "Delegated Permissions", select:
    • Read and write directory data
    • Read and write all groups
    • Read all groups
    • Access the directory as the signed-in user
    • Read directory data
Under the top-level application:

  • Under "Delegated permissions", select:
    • Read and write directory data 
    • Read and write all groups 
    • Read all groups 
    • Access the directory as the signed-in user 
    • Read directory data

Tuesday, December 08, 2015

Getting the SQL Server PowerShell tools

They're apparently not that easy to find. The SQL Server PowerShell Tools come as part of the SQL Server Feature Pack for their respective versions. You can find the SQL Server 2014 Feature Pack (along with the PowerShell Tools) here.

Thursday, October 22, 2015

Querying PowerShell for module and cmdlet information

I've recently realized that it's of incredible benefit to start designing our systems such that they're open and easily queryable by any system, particularly .NET and PowerShell. As a result, I've started designing modules for PowerShell to let my team administrate our systems. This has led me to realize that they need some of the basics of PowerShell to query what's available to them, because none of them have really used PowerShell before. The following commands should be of help to beginners:

Show the currently loaded PowerShell modules: Get-Module

Show the available PowerShell modules: Get-Module -ListAvailable

Show the cmdlets available in a particular module: Get-Command -Module [module name]

* in the case of our custom compiled C# module assembly, this is the name of the assembly (not the name of the assembly file, e.g. MyCompany.MyAssembly, not MyCompany.MyAssembly.dll)


Sunday, October 18, 2015

Accessing TFS via PowerShell

I'm ashamed to admit that only today did I find out that there are PowerShell cmdlets for TFS.

You can load them into a PowerShell session by executing this:

add-pssnapin Microsoft.TeamFoundation.PowerShell

Once that's done, you can get started with the following commands:

Get-Help Get-TfsServer

See this post on Hey Scripting Guy.

Saturday, October 17, 2015

AADSTS90093: User cannot consent to web app requesting user impersonation as an app permission.

According to the Azure Graph API team's blog, they've changed the way permissions are handled in Azure AD-authenticating apps.

This error has been driving me nuts for the past month while I've been able to get into an app we're writing in Azure using AD, but my team hasn't.

Here's how we fixed our issue:
1) I could get into our app (because I setup the permissions with my account in the management portal), but my team couldn't.
2) Had to go talk to one of our DevOps guys who's a Global Administrator in our Azure tenant, got him to remove the permission in the Azure AD Application, then re-add it.

Now my team could get in.

Hope this helps anybody stuck on this

Monday, October 05, 2015

SqlPackage.exe fails to deploy to Azure with error "The database platform service with type Microsoft.Data.Tools.Schema.Sql.SqlAzureV12DatabaseSchemaProvider is not valid."

I've recently started trying to deploy to one of my own databases in Azure using SqlPackage.exe. I've used it numerous times at work without problem, but on my own system at home, I keep running into the following error:

"Internal Error. The database platform service with type Microsoft.Data.Tools.Schema.Sql.SqlAzureV12DatabaseSchemaProvider is not valid. You must make sure the service is loaded, or you must provide the full type name of a valid database platform service."

As it turns out, you need at least SSMS CU#6 to get a version of SqlPackage.exe recent enough to deploy to Azure with SQL Azure v12. The copyright on the SqlPackage.exe executable must be 2015 (or later). Such a version comes with the latest versions of SQL Server Data Tools (SSDT). If you're unable to use the version of SqlPackage.exe that comes with SQL Server 2014 because it's too old ("C:\Program Files (x86)\Microsoft SQL Server\120\DAC\bin\SqlPackage.exe"), you can use the version that comes with SSDT for Visual Studio 2013 ("C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\120\sqlpackage.exe").

Thursday, September 10, 2015

Setting up continuous Webjobs in Azure

First things first: you need to properly setup your dashboard:

This means that in the 'Application settings' area of the panel for your Web app, you need to go into the 'Connection strings' setting and add blob storage connection strings with the names 'AzureWebJobsDashboard' and 'AzureWebJobsStorage', with a type of 'Custom'.

Second: if you have continuous web jobs associated with a Web app, you need to ensure that the Web app setting 'Always On' is toggled *on*.

Thursday, August 27, 2015

Setting up delegated authentication between web apps in Azure Active Directory - quirks

When setting up your Azure App ID for your web apps, it's extremely important that you follow the recommended format of "https://<your tenant name>/<your app name>"

Otherwise, delegated authentication will NOT work!!

Wednesday, August 26, 2015

Using ADAL in Javascript to enable use of Azure Active Directory from an AngularJS SPA

Check this out, apparently it came out last fall in Azure:

http://www.cloudidentity.com/blog/2014/10/28/adal-javascript-and-angularjs-deep-dive/


Enabling group membership claims in delegated tokens in Azure Active Directory

In your application manifest, add the following to the root object:

{
   ....
  "groupMembershipClaims": "All",
   ....
}


Fixing redirect loops in Azure web apps that use Azure Active Directory for authentication

We've recently been using Azure Active Directory to handle authentication for a bunch of our Line-Of-Business applications that we're moving into the cloud. Unfortunately, we've been noticing that in some circumstances, we encounter redirect loops that the browser can't break out of and I've been scratching my head over it. As it turns out, the loops had a common cause: going to a URL in the application that started with http://.

Since we're all good programmers here ;), we always want to be using best practices and enforcing secure connections anyway, but it also turned out to be the fix: adding [RequireHttps] to the top of our filters list in FilterConfig.cs solved the problem and closed a security hole at the same time.

As for the initial cause: why would anybody be using HTTP anyway ? It turns out that HTTP is the default scheme for URLs in the Azure portal when you're viewing the settings for an application and people were clicking on those links to go straight into the app.

Alex