Skip to content
This repository has been archived by the owner on Dec 13, 2018. It is now read-only.

Iteration 4 - Using Auth 2.0/Options 2.0 packages #1170

Closed
wants to merge 25 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 109 additions & 15 deletions Security.sln

Large diffs are not rendered by default.

10 changes: 4 additions & 6 deletions samples/CookieSample/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Linq;
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
Expand All @@ -13,24 +14,21 @@ public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication();
services.AddCookieAuthentication();
}

public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
{
loggerfactory.AddConsole(LogLevel.Information);

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AutomaticAuthenticate = true
});
app.UseAuthentication();

app.Run(async context =>
{
if (!context.User.Identities.Any(identity => identity.IsAuthenticated))
{
var user = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, "bob") }, CookieAuthenticationDefaults.AuthenticationScheme));
await context.Authentication.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, user);
await context.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, user);

context.Response.ContentType = "text/plain";
await context.Response.WriteAsync("Hello First timer");
Expand Down
11 changes: 4 additions & 7 deletions samples/CookieSessionSample/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
Expand All @@ -14,18 +15,14 @@ public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication();
services.AddCookieAuthentication(o => o.SessionStore = new MemoryCacheTicketStore());
}

public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
{
loggerfactory.AddConsole(LogLevel.Information);

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AutomaticAuthenticate = true,
SessionStore = new MemoryCacheTicketStore()
});
app.UseAuthentication();

app.Run(async context =>
{
Expand All @@ -39,7 +36,7 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
claims.Add(new Claim(ClaimTypes.Role, "SomeRandomGroup" + i, ClaimValueTypes.String, "IssuedByBob", "OriginalIssuerJoe"));
}

await context.Authentication.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
await context.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme)));

context.Response.ContentType = "text/plain";
Expand Down
1 change: 1 addition & 0 deletions samples/JwtBearerSample/JwtBearerSample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="$(AspNetCoreVersion)" />
</ItemGroup>

</Project>
59 changes: 21 additions & 38 deletions samples/JwtBearerSample/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
Expand Down Expand Up @@ -42,39 +43,12 @@ public Startup(IHostingEnvironment env)
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app)
{
// Simple error page to avoid a repo dependency.
app.Use(async (context, next) =>
{
try
{
await next();
}
catch (Exception ex)
{
if (context.Response.HasStarted)
{
throw;
}
context.Response.StatusCode = 500;
await context.Response.WriteAsync(ex.ToString());
}
});

app.UseDefaultFiles();
app.UseStaticFiles();

app.UseJwtBearerAuthentication(new JwtBearerOptions
services.AddJwtBearerAuthentication(o =>
{
// You also need to update /wwwroot/app/scripts/app.js
Authority = Configuration["jwt:authority"],
Audience = Configuration["jwt:audience"],
Events = new JwtBearerEvents()
o.Authority = Configuration["jwt:authority"];
o.Audience = Configuration["jwt:audience"];
o.Events = new JwtBearerEvents()
{
OnAuthenticationFailed = c =>
{
Expand All @@ -89,24 +63,34 @@ public void Configure(IApplicationBuilder app)
}
return c.Response.WriteAsync("An error occurred processing your authentication.");
}
}
};
});
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app)
{
app.UseDeveloperExceptionPage();

app.UseDefaultFiles();
app.UseStaticFiles();

app.UseAuthentication();

// [Authorize] would usually handle this
app.Use(async (context, next) =>
{
// Use this if options.AutomaticAuthenticate = false
// Use this if there are multiple authentication schemes
// var user = await context.Authentication.AuthenticateAsync(JwtBearerDefaults.AuthenticationScheme);

var user = context.User; // We can do this because of options.AutomaticAuthenticate = true;
var user = context.User; // We can do this because of there's only a single authentication scheme
if (user?.Identity?.IsAuthenticated ?? false)
{
await next();
}
else
{
// We can do this because of options.AutomaticChallenge = true;
await context.Authentication.ChallengeAsync();
await context.ChallengeAsync();
}
});

Expand Down Expand Up @@ -135,5 +119,4 @@ public void Configure(IApplicationBuilder app)
});
}
}
}

}
12 changes: 5 additions & 7 deletions samples/OpenIdConnect.AzureAdSample/AuthPropertiesTokenCache.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
using System;
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication;
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
Expand Down Expand Up @@ -58,10 +57,9 @@ private void BeforeAccessNotificationWithProperties(TokenCacheNotificationArgs a
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;
var result = _httpContext.AuthenticateAsync(_signInScheme).Result;
_authProperties = result.Ticket.Properties;
_principal = result.Ticket.Principal;

BeforeAccessNotificationWithProperties(args);
}
Expand All @@ -87,7 +85,7 @@ private void AfterAccessNotificationWithContext(TokenCacheNotificationArgs args)
var cachedTokens = Serialize();
var cachedTokensText = Convert.ToBase64String(cachedTokens);
_authProperties.Items[TokenCacheKey] = cachedTokensText;
_httpContext.Authentication.SignInAsync(_signInScheme, _principal, _authProperties).Wait();
_httpContext.SignInAsync(_signInScheme, _principal, _authProperties).Wait();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="$(IdentityModelActiveDirectoryVersion)" />
<DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="$(AspNetCoreVersion)" />
Expand Down
93 changes: 39 additions & 54 deletions samples/OpenIdConnect.AzureAdSample/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
using System.Linq;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Authentication;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
Expand Down Expand Up @@ -37,68 +37,55 @@ public Startup(IHostingEnvironment env)

public IConfiguration Configuration { get; set; }

private string ClientId => Configuration["oidc:clientid"];
private string ClientSecret => Configuration["oidc:clientsecret"];
private string Authority => Configuration["oidc:authority"];
private string Resource => "https://graph.windows.net";

public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(sharedOptions =>
sharedOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme);
}

public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
{
loggerfactory.AddConsole(Microsoft.Extensions.Logging.LogLevel.Information);

// Simple error page
app.Use(async (context, next) =>
{
try
{
await next();
}
catch (Exception ex)
{
if (!context.Response.HasStarted)
{
context.Response.Clear();
context.Response.StatusCode = 500;
await context.Response.WriteAsync(ex.ToString());
}
else
{
throw;
}
}
sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
});

app.UseCookieAuthentication(new CookieAuthenticationOptions());
services.AddCookieAuthentication();

var clientId = Configuration["oidc:clientid"];
var clientSecret = Configuration["oidc:clientsecret"];
var authority = Configuration["oidc:authority"];
var resource = "https://graph.windows.net";
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
services.AddOpenIdConnectAuthentication(o =>
{
ClientId = clientId,
ClientSecret = clientSecret, // for code flow
Authority = authority,
ResponseType = OpenIdConnectResponseType.CodeIdToken,
PostLogoutRedirectUri = "/signed-out",
o.ClientId = ClientId;
o.ClientSecret = ClientSecret; // for code flow
o.Authority = Authority;
o.ResponseType = OpenIdConnectResponseType.CodeIdToken;
o.PostLogoutRedirectUri = "/signed-out";
// GetClaimsFromUserInfoEndpoint = true,
Events = new OpenIdConnectEvents()
o.Events = new OpenIdConnectEvents()
{
OnAuthorizationCodeReceived = async context =>
{
var request = context.HttpContext.Request;
var currentUri = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path);
var credential = new ClientCredential(clientId, clientSecret);
var authContext = new AuthenticationContext(authority, AuthPropertiesTokenCache.ForCodeRedemption(context.Properties));
var credential = new ClientCredential(ClientId, ClientSecret);
var authContext = new AuthenticationContext(Authority, AuthPropertiesTokenCache.ForCodeRedemption(context.Properties));

var result = await authContext.AcquireTokenByAuthorizationCodeAsync(
context.ProtocolMessage.Code, new Uri(currentUri), credential, resource);
context.ProtocolMessage.Code, new Uri(currentUri), credential, Resource);

context.HandleCodeRedemption(result.AccessToken, result.IdToken);
}
}
};
});
}

public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
{
loggerfactory.AddConsole(Microsoft.Extensions.Logging.LogLevel.Information);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

namespace?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its because Azure also has a log level so this is disambiguiating


app.UseDeveloperExceptionPage();

app.UseAuthentication();

app.Run(async context =>
{
Expand All @@ -111,13 +98,11 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
return;
}

await context.Authentication.ChallengeAsync(
OpenIdConnectDefaults.AuthenticationScheme,
new AuthenticationProperties { RedirectUri = "/" });
await context.ChallengeAsync(new AuthenticationProperties { RedirectUri = "/" });
}
else if (context.Request.Path.Equals("/signout"))
{
await context.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
await WriteHtmlAsync(context.Response,
async response =>
{
Expand All @@ -127,8 +112,8 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
}
else if (context.Request.Path.Equals("/signout-remote"))
{
await context.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
await context.Authentication.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
await context.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
}
else if (context.Request.Path.Equals("/signed-out"))
{
Expand All @@ -141,7 +126,7 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
}
else if (context.Request.Path.Equals("/remote-signedout"))
{
await context.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
await WriteHtmlAsync(context.Response,
async response =>
{
Expand All @@ -153,7 +138,7 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
{
if (!context.User.Identities.Any(identity => identity.IsAuthenticated))
{
await context.Authentication.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties { RedirectUri = "/" });
await context.ChallengeAsync(new AuthenticationProperties { RedirectUri = "/" });
return;
}

Expand All @@ -170,10 +155,10 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
try
{
// Use ADAL to get the right token
var authContext = new AuthenticationContext(authority, AuthPropertiesTokenCache.ForApiCalls(context, CookieAuthenticationDefaults.AuthenticationScheme));
var credential = new ClientCredential(clientId, clientSecret);
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 = await authContext.AcquireTokenSilentAsync(resource, credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));
var result = await authContext.AcquireTokenSilentAsync(Resource, credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));

await response.WriteAsync($"<h3>access_token</h3><code>{HtmlEncode(result.AccessToken)}</code><br>");
}
Expand Down
Loading