Menu

Setting up Azure Active Directory Single Sign On on a ASP.NET (.NET 4.5) web app using OpenIdConnect (Cookies based)

Install following NuGet packages on your project.


Install-Package Owin
Install-Package Microsoft.Owin
Install-Package Microsoft.Owin.Host.SystemWeb
Install-Package Microsoft.Owin.Security
Install-Package Microsoft.Owin.Security.Cookies
Install-Package Microsoft.Owin.Security.OpenIdConnect

Create a Startup.cs in your root of your web application.

public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
}
}

Create a Startup.Auth.cs in your App_Start folder. and this is how it looks like.

public partial class Startup
{
private static readonly string ClientId = ConfigurationManager.AppSettings["ClientId"];
private static readonly string AadInstance = ConfigurationManager.AppSettings["AADInstance"];
private static readonly string TenantId = ConfigurationManager.AppSettings["TenantId"];
private static readonly string PostLogoutRedirectUri = ConfigurationManager.AppSettings["PostLogoutRedirectUri"];
private static readonly string Authority = AadInstance + TenantId;

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

app.UseCookieAuthentication(new CookieAuthenticationOptions());

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = ClientId,
Authority = Authority,
PostLogoutRedirectUri = PostLogoutRedirectUri,
TokenValidationParameters =
{
NameClaimType = CustomClaimTypes.UserName,
},
Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = SecurityTokenValidated,
AuthenticationFailed = AuthenticationFailed
}
});
}

private Task SecurityTokenValidated(SecurityTokenValidatedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context)
{
ValidateTenant(context);
var user = ValidateUserAndUpdateClaims(context);

return Task.FromResult(0);
}

private static UserInfo ValidateUserAndUpdateClaims(SecurityTokenValidatedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context)
{
var claimsIdentity = context.AuthenticationTicket.Identity;
var email = claimsIdentity.FindFirst(System.Security.Claims.ClaimTypes.Name).Value;

var user = GetUserAndRoles(email);
if (user != null && user.UserRoles.Count > 0)
{

UpdateClaims(claimsIdentity, user, email);
}
else
throw new SecurityTokenValidationException(“Please check if your login is configured in configuration to access this website.”);

return user;
}

private static void UpdateClaims(ClaimsIdentity claimsIdentity, UserInfo user, string email)
{
claimsIdentity.AddClaim(new Claim(“https://www.inoaspect.com.au/claims/UserName”, user.UserName));
claimsIdentity.AddClaim(new Claim(“https://www.inoaspect.com.au/claims/DisplayName”, user.DisplayName));
claimsIdentity.AddClaim(new Claim(System.IdentityModel.Claims.ClaimTypes.Email, email));

foreach (var role in user.UserRoles)
{
claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, role.Role.Name));
}
}

private static void ValidateTenant(SecurityTokenValidatedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context)
{
var tenant = context.AuthenticationTicket.Identity.Claims.FirstOrDefault(o => o.Type == “”http://schemas.microsoft.com/identity/claims/tenantid””);
if (tenant == null)
throw new SecurityTokenValidationException(“Active directory tenant not found.”);

var tenantId = tenant.Value;
IEnumerable approvedTenantIds = new List
{
TenantId
};

if (!approvedTenantIds.Contains(tenantId))
throw new SecurityTokenValidationException(“Active directory tenant is not configured to access this web site.”);
}


private Task AuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context)
{
context.OwinContext.Response.Redirect("/Home/Error?message=" + context.Exception.Message);
context.HandleResponse();
return Task.FromResult(0);
}
}

No in order to protect your controllers you simply add [Authorize] attribute. Like below

[Authorize]
public class HomeController : Controller
{
// Your Controller code
}

Leave a comment