-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 616b013
Showing
12 changed files
with
362 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/appsettings.Development.json | ||
/.vs/oauthy | ||
/bin/Debug/net5.0 | ||
/obj | ||
/oauthy.csproj.user |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace oauthy | ||
{ | ||
public class AzureAdOptions | ||
{ | ||
public string ClientId { get; set; } | ||
public string ClientSecret { get; set; } | ||
public string Instance { get; set; } | ||
public string TenantId { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
using Microsoft.AspNetCore.Authentication; | ||
using Microsoft.AspNetCore.Authentication.JwtBearer; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.Options; | ||
using oauthy; | ||
using System; | ||
|
||
public static class AzureAdServiceCollectionExtensions | ||
{ | ||
public static AuthenticationBuilder AddAzureAdBearer(this AuthenticationBuilder builder) | ||
=> builder.AddAzureAdBearer(_ => { }); | ||
|
||
public static AuthenticationBuilder AddAzureAdBearer(this AuthenticationBuilder builder, Action<AzureAdOptions> configureOptions) | ||
{ | ||
builder.Services.Configure(configureOptions); | ||
builder.Services.AddSingleton<IConfigureOptions<JwtBearerOptions>, ConfigureAzureOptions>(); | ||
builder.AddJwtBearer(); | ||
return builder; | ||
} | ||
|
||
private class ConfigureAzureOptions : IConfigureNamedOptions<JwtBearerOptions> | ||
{ | ||
private readonly AzureAdOptions _azureOptions; | ||
|
||
public ConfigureAzureOptions(IOptions<AzureAdOptions> azureOptions) | ||
{ | ||
_azureOptions = azureOptions.Value; | ||
} | ||
|
||
public void Configure(string name, JwtBearerOptions options) | ||
{ | ||
options.TokenValidationParameters.ValidAudiences = new string[] { $"api://{_azureOptions.ClientId}", _azureOptions.ClientId }; | ||
options.Authority = $"{_azureOptions.Instance}{_azureOptions.TenantId}"; | ||
options.Events = JwtBearerMiddlewareDiagnostics.Subscribe(options.Events); | ||
} | ||
|
||
public void Configure(JwtBearerOptions options) | ||
{ | ||
Configure(Options.DefaultName, options); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
using Microsoft.AspNetCore.Authorization; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.Extensions.Logging; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
namespace oauthy.Controllers | ||
{ | ||
[ApiController] | ||
[Route("[controller]")] | ||
[Authorize(Roles = "OuathyAppRole")] | ||
public class WeatherForecastController : ControllerBase | ||
{ | ||
private static readonly string[] Summaries = new[] | ||
{ | ||
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" | ||
}; | ||
|
||
private readonly ILogger<WeatherForecastController> _logger; | ||
|
||
public WeatherForecastController(ILogger<WeatherForecastController> logger) | ||
{ | ||
_logger = logger; | ||
} | ||
|
||
[HttpGet] | ||
public IEnumerable<WeatherForecast> Get() | ||
{ | ||
var rng = new Random(); | ||
return Enumerable.Range(1, 5).Select(index => new WeatherForecast | ||
{ | ||
Date = DateTime.Now.AddDays(index), | ||
TemperatureC = rng.Next(-20, 55), | ||
Summary = Summaries[rng.Next(Summaries.Length)] | ||
}) | ||
.ToArray(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
using Microsoft.AspNetCore.Authentication.JwtBearer; | ||
using System; | ||
using System.Diagnostics; | ||
using System.Threading.Tasks; | ||
|
||
namespace oauthy | ||
{ | ||
/// <summary> | ||
/// Diagnostics for the JwtBearer middleware (used in Web APIs) | ||
/// </summary> | ||
public class JwtBearerMiddlewareDiagnostics | ||
{ | ||
/// <summary> | ||
/// Invoked if exceptions are thrown during request processing. The exceptions will be re-thrown after this event unless suppressed. | ||
/// </summary> | ||
static Func<AuthenticationFailedContext, Task> onAuthenticationFailed; | ||
|
||
/// <summary> | ||
/// Invoked when a protocol message is first received. | ||
/// </summary> | ||
static Func<MessageReceivedContext, Task> onMessageReceived; | ||
|
||
/// <summary> | ||
/// Invoked after the security token has passed validation and a ClaimsIdentity has been generated. | ||
/// </summary> | ||
static Func<TokenValidatedContext, Task> onTokenValidated; | ||
|
||
/// <summary> | ||
/// Invoked before a challenge is sent back to the caller. | ||
/// </summary> | ||
static Func<JwtBearerChallengeContext, Task> onChallenge; | ||
|
||
/// <summary> | ||
/// Subscribes to all the JwtBearer events, to help debugging, while | ||
/// preserving the previous handlers (which are called) | ||
/// </summary> | ||
/// <param name="events">Events to subscribe to</param> | ||
public static JwtBearerEvents Subscribe(JwtBearerEvents events) | ||
{ | ||
if (events == null) | ||
{ | ||
events = new JwtBearerEvents(); | ||
} | ||
|
||
onAuthenticationFailed = events.OnAuthenticationFailed; | ||
events.OnAuthenticationFailed = OnAuthenticationFailed; | ||
|
||
onMessageReceived = events.OnMessageReceived; | ||
events.OnMessageReceived = OnMessageReceived; | ||
|
||
onTokenValidated = events.OnTokenValidated; | ||
events.OnTokenValidated = OnTokenValidated; | ||
|
||
onChallenge = events.OnChallenge; | ||
events.OnChallenge = OnChallenge; | ||
|
||
return events; | ||
} | ||
|
||
static async Task OnMessageReceived(MessageReceivedContext context) | ||
{ | ||
Debug.WriteLine($"1. Begin {nameof(OnMessageReceived)}"); | ||
// Place a breakpoint here and examine the bearer token (context.Request.Headers.HeaderAuthorization / context.Request.Headers["Authorization"]) | ||
// Use https://jwt.ms to decode the token and observe claims | ||
await onMessageReceived(context); | ||
Debug.WriteLine($"1. End - {nameof(OnMessageReceived)}"); | ||
} | ||
|
||
static async Task OnAuthenticationFailed(AuthenticationFailedContext context) | ||
{ | ||
Debug.WriteLine($"99. Begin {nameof(OnAuthenticationFailed)}"); | ||
// Place a breakpoint here and examine context.Exception | ||
await onAuthenticationFailed(context); | ||
Debug.WriteLine($"99. End - {nameof(OnAuthenticationFailed)}"); | ||
} | ||
|
||
static async Task OnTokenValidated(TokenValidatedContext context) | ||
{ | ||
Debug.WriteLine($"2. Begin {nameof(OnTokenValidated)}"); | ||
await onTokenValidated(context); | ||
Debug.WriteLine($"2. End - {nameof(OnTokenValidated)}"); | ||
} | ||
|
||
static async Task OnChallenge(JwtBearerChallengeContext context) | ||
{ | ||
Debug.WriteLine($"55. Begin {nameof(OnChallenge)}"); | ||
await onChallenge(context); | ||
Debug.WriteLine($"55. End - {nameof(OnChallenge)}"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Hosting; | ||
using Microsoft.Extensions.Configuration; | ||
using Microsoft.Extensions.Hosting; | ||
using Microsoft.Extensions.Logging; | ||
|
||
namespace oauthy | ||
{ | ||
public class Program | ||
{ | ||
public static void Main(string[] args) | ||
{ | ||
CreateHostBuilder(args).Build().Run(); | ||
} | ||
|
||
public static IHostBuilder CreateHostBuilder(string[] args) => | ||
Host.CreateDefaultBuilder(args) | ||
.ConfigureWebHostDefaults(webBuilder => | ||
{ | ||
webBuilder.UseStartup<Startup>(); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
{ | ||
"$schema": "http://json.schemastore.org/launchsettings.json", | ||
"iisSettings": { | ||
"windowsAuthentication": false, | ||
"anonymousAuthentication": true, | ||
"iisExpress": { | ||
"applicationUrl": "http://localhost:49265", | ||
"sslPort": 44352 | ||
} | ||
}, | ||
"profiles": { | ||
"IIS Express": { | ||
"commandName": "IISExpress", | ||
"launchBrowser": true, | ||
"launchUrl": "swagger", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
} | ||
}, | ||
"oauthy": { | ||
"commandName": "Project", | ||
"dotnetRunMessages": "true", | ||
"launchBrowser": true, | ||
"launchUrl": "swagger", | ||
"applicationUrl": "https://localhost:5001;http://localhost:5000", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
using Microsoft.AspNetCore.Authentication.JwtBearer; | ||
using Microsoft.AspNetCore.Builder; | ||
using Microsoft.AspNetCore.Hosting; | ||
using Microsoft.Extensions.Configuration; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.Hosting; | ||
using Microsoft.OpenApi.Models; | ||
|
||
namespace oauthy | ||
{ | ||
public class Startup | ||
{ | ||
public Startup(IConfiguration configuration) | ||
{ | ||
Configuration = configuration; | ||
} | ||
|
||
public IConfiguration Configuration { get; } | ||
|
||
// This method gets called by the runtime. Use this method to add services to the container. | ||
public void ConfigureServices(IServiceCollection services) | ||
{ | ||
|
||
services.AddControllers(); | ||
services.AddAuthentication(sharedOptions => | ||
{ | ||
sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; | ||
}).AddAzureAdBearer(options => Configuration.Bind("AzureAd", options)); | ||
services.AddSwaggerGen(c => | ||
{ | ||
c.SwaggerDoc("v1", new OpenApiInfo { Title = "oauthy", Version = "v1" }); | ||
}); | ||
} | ||
|
||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | ||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) | ||
{ | ||
if (env.IsDevelopment()) | ||
{ | ||
app.UseDeveloperExceptionPage(); | ||
app.UseSwagger(); | ||
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "oauthy v1")); | ||
} | ||
|
||
app.UseHttpsRedirection(); | ||
app.UseRouting(); | ||
app.UseAuthentication(); | ||
app.UseAuthorization(); | ||
app.UseEndpoints(endpoints => | ||
{ | ||
endpoints.MapControllers(); | ||
}); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using System; | ||
|
||
namespace oauthy | ||
{ | ||
public class WeatherForecast | ||
{ | ||
public DateTime Date { get; set; } | ||
|
||
public int TemperatureC { get; set; } | ||
|
||
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); | ||
|
||
public string Summary { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"Logging": { | ||
"LogLevel": { | ||
"Default": "Information", | ||
"Microsoft": "Warning", | ||
"Microsoft.Hosting.Lifetime": "Information" | ||
} | ||
}, | ||
"AllowedHosts": "*" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net5.0</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.15" /> | ||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 16 | ||
VisualStudioVersion = 16.0.31613.86 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "oauthy", "oauthy.csproj", "{2B831538-6E96-4C11-AF3E-408A13828C33}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{2B831538-6E96-4C11-AF3E-408A13828C33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{2B831538-6E96-4C11-AF3E-408A13828C33}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{2B831538-6E96-4C11-AF3E-408A13828C33}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{2B831538-6E96-4C11-AF3E-408A13828C33}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {7FB810AD-9C28-415F-8931-BCFB5D0D40DA} | ||
EndGlobalSection | ||
EndGlobal |