Search code examples
asp.net-mvcopenidazure-active-directoryazure-webjobsbearer-token

Azure Active Directory Authentication - Using both OpenId Connect and Bearer Authentication in MVC


I have created an MVC app that uses Azure Active Directory Authentication with OpenId. This works great for end users, but I would like to add a webjob to the site that will call its own endpoint (the same http post method that users will use). I found this example https://github.com/AzureADSamples/Daemon-DotNet that allows a server app to call a webapi endpoint.

My authorization configuration class looks like this:

public class StartAuth
{
    private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
    private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
    private static string tenant = ConfigurationManager.AppSettings["ida:Tenant"];
    private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];
    private static string audience = ConfigurationManager.AppSettings["ida:Audience"];

    string authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant);

    public void Configuration(IAppBuilder app)
    {
        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

        app.UseCookieAuthentication(new CookieAuthenticationOptions());

        app.UseOpenIdConnectAuthentication(
            new OpenIdConnectAuthenticationOptions
            {
                ClientId = clientId,
                Authority = authority,
                PostLogoutRedirectUri = postLogoutRedirectUri,
            });

        app.UseWindowsAzureActiveDirectoryBearerAuthentication(
            new WindowsAzureActiveDirectoryBearerAuthenticationOptions
            {
                Tenant = tenant,
                TokenValidationParameters = new TokenValidationParameters
                {
                    ValidAudience = audience
                }
            });
    }
}

The request from my web job console app looks like this (I've replaced the bearer key and the host):

POST      
https://some-random-host/myendpoint     
HTTP/1.1
Authorization: Bearer key
Host: some-random-host
Content-Length: 0

and the response from the server looks like this (replaced the host, key, tenant id, and truncated the location value):

HTTP/1.1 302 Found
Cache-Control: private
Content-Length: 0
Location: https://login.windows.net/tenant-id/oauth2/authorize....
Server: Microsoft-IIS/8.0
Set-Cookie: OpenIdConnect.nonce.u%noncekey; path=/; secure; HttpOnly
WWW-Authenticate: Bearer
X-AspNetMvc-Version: 5.2
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Set-Cookie: ARRAffinity=key;Path=/;Domain=some-random-host
Date: Thu, 19 Mar 2015 11:44:11 GMT

Any ideas why the server is responding with the login location? This obviously works great when users try to hit an authenticated endpoint, but not for my console app.

Thanks for your help in advance. Please let me know if any other information would be useful.


Solution

  • Since Azure WebJobs are not tied to a specific user when authenticating with a key, you cannot have an authorize attribute on the method/controller with users specified. This makes total sense, but was something I overlooked until Omer reminded me to check the attributes.

    In fact, the user is actually null.

    So rather than have: [Authorize(Users="user@contoso.com"] I needed to have just: [Authorize]

    I am not sure if there is a way to specify that just the WebJob has permissions however.