Update the OIDC AzureAd sample.

This commit is contained in:
Chris R 2016-05-24 10:34:39 -07:00
parent d6763bd77c
commit 871885259b
5 changed files with 75 additions and 36 deletions

View File

@ -1,5 +1,9 @@
using System;
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Authentication;
using Microsoft.AspNetCore.Http.Features.Authentication;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
namespace OpenIdConnect.AzureAdSample
@ -8,46 +12,85 @@ namespace OpenIdConnect.AzureAdSample
{
private const string TokenCacheKey = ".TokenCache";
private HttpContext _httpContext;
private ClaimsPrincipal _principal;
private AuthenticationProperties _authProperties;
private string _signInScheme;
public bool HasCacheChanged { get; internal set; }
public AuthPropertiesTokenCache(AuthenticationProperties authProperties) : base()
private AuthPropertiesTokenCache(AuthenticationProperties authProperties) : base()
{
_authProperties = authProperties;
BeforeAccess = BeforeAccessNotification;
AfterAccess = AfterAccessNotification;
BeforeAccess = BeforeAccessNotificationWithProperties;
AfterAccess = AfterAccessNotificationWithProperties;
BeforeWrite = BeforeWriteNotification;
}
private AuthPropertiesTokenCache(HttpContext httpContext, string signInScheme) : base()
{
_httpContext = httpContext;
_signInScheme = signInScheme;
BeforeAccess = BeforeAccessNotificationWithContext;
AfterAccess = AfterAccessNotificationWithContext;
BeforeWrite = BeforeWriteNotification;
}
public static TokenCache ForCodeRedemption(AuthenticationProperties authProperties)
{
return new AuthPropertiesTokenCache(authProperties);
}
public static TokenCache ForApiCalls(HttpContext httpContext,
string signInScheme = CookieAuthenticationDefaults.AuthenticationScheme)
{
return new AuthPropertiesTokenCache(httpContext, signInScheme);
}
private void BeforeAccessNotificationWithProperties(TokenCacheNotificationArgs args)
{
string cachedTokensText;
if (authProperties.Items.TryGetValue(TokenCacheKey, out cachedTokensText))
if (_authProperties.Items.TryGetValue(TokenCacheKey, out cachedTokensText))
{
var cachedTokens = Convert.FromBase64String(cachedTokensText);
Deserialize(cachedTokens);
}
}
// Notification raised before ADAL accesses the cache.
// This is your chance to update the in-memory copy from the DB, if the in-memory version is stale
private void BeforeAccessNotification(TokenCacheNotificationArgs args)
private void BeforeAccessNotificationWithContext(TokenCacheNotificationArgs args)
{
// Retrieve the auth session with the cached tokens
var authenticateContext = new AuthenticateContext(_signInScheme);
_httpContext.Authentication.AuthenticateAsync(authenticateContext).Wait();
_authProperties = new AuthenticationProperties(authenticateContext.Properties);
_principal = authenticateContext.Principal;
BeforeAccessNotificationWithProperties(args);
}
// Notification raised after ADAL accessed the cache.
// If the HasStateChanged flag is set, ADAL changed the content of the cache
private void AfterAccessNotification(TokenCacheNotificationArgs args)
private void AfterAccessNotificationWithProperties(TokenCacheNotificationArgs args)
{
// if state changed
if (HasStateChanged)
{
HasCacheChanged = true;
var cachedTokens = Serialize();
var cachedTokensText = Convert.ToBase64String(cachedTokens);
_authProperties.Items[TokenCacheKey] = cachedTokensText;
}
}
private void AfterAccessNotificationWithContext(TokenCacheNotificationArgs args)
{
// if state changed
if (HasStateChanged)
{
AfterAccessNotificationWithProperties(args);
var cachedTokens = Serialize();
var cachedTokensText = Convert.ToBase64String(cachedTokens);
_authProperties.Items[TokenCacheKey] = cachedTokensText;
_httpContext.Authentication.SignInAsync(_signInScheme, _principal, _authProperties).Wait();
}
}
private void BeforeWriteNotification(TokenCacheNotificationArgs args)
{
// if you want to ensure that no concurrent write take place, use this notification to place a lock on the entry

View File

@ -8,11 +8,8 @@ namespace OpenIdConnect.AzureAdSample
{
public static void Main(string[] args)
{
var config = new ConfigurationBuilder().AddEnvironmentVariables("ASPNETCORE_").Build();
var host = new WebHostBuilder()
.UseKestrel()
.UseConfiguration(config)
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()

View File

@ -21,7 +21,7 @@
"launchUrl": "http://localhost:42023",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_SERVER.URLS": "http://localhost:42023"
"ASPNETCORE_URLS": "http://localhost:42023"
}
}
}

View File

@ -89,12 +89,12 @@ namespace OpenIdConnect.AzureAdSample
var request = context.HttpContext.Request;
var currentUri = UriHelper.Encode(request.Scheme, request.Host, request.PathBase, request.Path);
var credential = new ClientCredential(clientId, clientSecret);
var authContext = new AuthenticationContext(authority, new AuthPropertiesTokenCache(context.Properties));
var authContext = new AuthenticationContext(authority, AuthPropertiesTokenCache.ForCodeRedemption(context.Properties));
var result = await authContext.AcquireTokenByAuthorizationCodeAsync(
context.ProtocolMessage.Code, new Uri(currentUri), credential, resource);
context.HandleCodeRedemption(result.AccessToken, result.IdToken);
context.HandleCodeRedemption();
}
}
});
@ -128,23 +128,11 @@ namespace OpenIdConnect.AzureAdSample
await context.Response.WriteAsync("Tokens:<br>" + Environment.NewLine);
try
{
// Retrieve the auth session with the cached tokens
var authenticateContext = new AuthenticateContext(CookieAuthenticationDefaults.AuthenticationScheme);
await context.Authentication.AuthenticateAsync(authenticateContext);
var authProperties = new AuthenticationProperties(authenticateContext.Properties);
var tokenCache = new AuthPropertiesTokenCache(authProperties);
// Use ADAL to get the right token
var authContext = new AuthenticationContext(authority, tokenCache);
var authContext = new AuthenticationContext(authority, AuthPropertiesTokenCache.ForApiCalls(context, CookieAuthenticationDefaults.AuthenticationScheme));
var credential = new ClientCredential(clientId, clientSecret);
string userObjectID = context.User.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
var result = authContext.AcquireTokenSilent(resource, credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));
// Update the cookie with the modified tokens
if (tokenCache.HasCacheChanged)
{
await context.Authentication.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, authenticateContext.Principal, authProperties);
}
var result = await authContext.AcquireTokenSilentAsync(resource, credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));
await context.Response.WriteAsync($"access_token: {result.AccessToken}<br>{Environment.NewLine}");
}

View File

@ -5,13 +5,24 @@
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "1.0.0-*",
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0-*",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0-*",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0-*",
"Microsoft.Extensions.Configuration.UserSecrets": "1.0.0-*",
"Microsoft.Extensions.Logging.Console": "1.0.0-*",
"Microsoft.IdentityModel.Clients.ActiveDirectory": "2.22.302111727",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0-*"
"Microsoft.IdentityModel.Clients.ActiveDirectory": "3.9.302261508-alpha"
},
"frameworks": {
"net451": {}
"net451": { },
"netcoreapp1.0": {
"imports": [
"dnxcore50"
],
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.0-*",
"type": "platform"
}
}
}
},
"buildOptions": {
"emitEntryPoint": true