@@ -2,7 +2,7 @@ | |||||
<PropertyGroup> | <PropertyGroup> | ||||
<VersionMajor>5</VersionMajor> | <VersionMajor>5</VersionMajor> | ||||
<VersionMinor>1</VersionMinor> | <VersionMinor>1</VersionMinor> | ||||
<VersionPatch>0</VersionPatch> | |||||
<VersionPatch>1</VersionPatch> | |||||
<VersionQuality></VersionQuality> | <VersionQuality></VersionQuality> | ||||
<VersionPrefix>$(VersionMajor).$(VersionMinor).$(VersionPatch)</VersionPrefix> | <VersionPrefix>$(VersionMajor).$(VersionMinor).$(VersionPatch)</VersionPrefix> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
@@ -0,0 +1,50 @@ | |||||
using System.Linq; | |||||
using System.Security.Claims; | |||||
using System.Text.Encodings.Web; | |||||
using System.Threading.Tasks; | |||||
using Microsoft.AspNetCore.Authentication; | |||||
using Microsoft.Extensions.Logging; | |||||
using Microsoft.Extensions.Options; | |||||
namespace Sample.Dashboard.Auth | |||||
{ | |||||
public class MyDashboardAuthenticationSchemeOptions : AuthenticationSchemeOptions | |||||
{ | |||||
} | |||||
public class MyDashboardAuthenticationHandler : AuthenticationHandler<MyDashboardAuthenticationSchemeOptions> | |||||
{ | |||||
public MyDashboardAuthenticationHandler(IOptionsMonitor<MyDashboardAuthenticationSchemeOptions> options, | |||||
ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock) | |||||
{ | |||||
options.CurrentValue.ForwardChallenge = ""; | |||||
} | |||||
protected override Task<AuthenticateResult> HandleAuthenticateAsync() | |||||
{ | |||||
var testAuthHeaderPresent = Request.Headers["X-Base-Token"].Contains("xxx"); | |||||
var authResult = testAuthHeaderPresent ? AuthenticatedTestUser() : AuthenticateResult.NoResult(); | |||||
return Task.FromResult(authResult); | |||||
} | |||||
protected override Task HandleChallengeAsync(AuthenticationProperties properties) | |||||
{ | |||||
Response.Headers["WWW-Authenticate"] = "MyDashboardScheme"; | |||||
return base.HandleChallengeAsync(properties); | |||||
} | |||||
private AuthenticateResult AuthenticatedTestUser() | |||||
{ | |||||
var claims = new[] { new Claim(ClaimTypes.Name, "My Dashboard user") }; | |||||
var identity = new ClaimsIdentity(claims, "MyDashboardScheme"); | |||||
var principal = new ClaimsPrincipal(identity); | |||||
var ticket = new AuthenticationTicket(principal, "MyDashboardScheme"); | |||||
return AuthenticateResult.Success(ticket); | |||||
} | |||||
} | |||||
} |
@@ -21,7 +21,7 @@ namespace Sample.Dashboard.Auth | |||||
.AddAuthorization() | .AddAuthorization() | ||||
.AddAuthentication(options => | .AddAuthentication(options => | ||||
{ | { | ||||
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; | |||||
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; | |||||
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; | options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; | ||||
}) | }) | ||||
.AddCookie() | .AddCookie() | ||||
@@ -36,7 +36,8 @@ namespace Sample.Dashboard.Auth | |||||
options.Scope.Clear(); | options.Scope.Clear(); | ||||
options.Scope.Add("openid"); | options.Scope.Add("openid"); | ||||
options.Scope.Add("profile"); | options.Scope.Add("profile"); | ||||
}); | |||||
}) | |||||
.AddScheme<MyDashboardAuthenticationSchemeOptions, MyDashboardAuthenticationHandler>("MyDashboardScheme",null); | |||||
services.AddCors(x => | services.AddCors(x => | ||||
{ | { | ||||
@@ -45,13 +46,15 @@ namespace Sample.Dashboard.Auth | |||||
p.WithOrigins("http://localhost:8080").AllowCredentials().AllowAnyHeader().AllowAnyMethod(); | p.WithOrigins("http://localhost:8080").AllowCredentials().AllowAnyHeader().AllowAnyMethod(); | ||||
}); | }); | ||||
}); | }); | ||||
services.AddCap(cap => | services.AddCap(cap => | ||||
{ | { | ||||
cap.UseDashboard(d => | cap.UseDashboard(d => | ||||
{ | { | ||||
d.UseChallengeOnAuth = true; | d.UseChallengeOnAuth = true; | ||||
d.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; | d.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; | ||||
d.UseAuth = true; | |||||
d.DefaultAuthenticationScheme = "MyDashboardScheme"; | |||||
}); | }); | ||||
cap.UseMySql(_configuration.GetValue<string>("ConnectionString")); | cap.UseMySql(_configuration.GetValue<string>("ConnectionString")); | ||||
cap.UseRabbitMQ(aa => | cap.UseRabbitMQ(aa => | ||||
@@ -76,16 +79,16 @@ namespace Sample.Dashboard.Auth | |||||
public void Configure(IApplicationBuilder app) | public void Configure(IApplicationBuilder app) | ||||
{ | { | ||||
app.UseAuthentication(); | |||||
app.UseCors(); | app.UseCors(); | ||||
app.UseRouting(); | app.UseRouting(); | ||||
app.UseAuthentication(); | |||||
app.UseAuthorization(); | app.UseAuthorization(); | ||||
app.UseCookiePolicy(); | app.UseCookiePolicy(); | ||||
app.UseEndpoints(endpoints => | app.UseEndpoints(endpoints => | ||||
{ | { | ||||
endpoints.MapControllers(); | |||||
endpoints.MapControllers(); | |||||
}); | }); | ||||
} | } | ||||
} | |||||
} | |||||
} | } |
@@ -13,16 +13,29 @@ namespace DotNetCore.CAP | |||||
} | } | ||||
public string PathMatch { get; set; } | public string PathMatch { get; set; } | ||||
/// <summary> | /// <summary> | ||||
/// The interval the /stats endpoint should be polled with. | /// The interval the /stats endpoint should be polled with. | ||||
/// </summary> | /// </summary> | ||||
public int StatsPollingInterval { get; set; } | public int StatsPollingInterval { get; set; } | ||||
/// <summary> | |||||
/// Enable authentication on dashboard request. | |||||
/// </summary> | |||||
public bool UseAuth { get; set; } | |||||
/// <summary> | |||||
/// Default scheme used for authentication. If no scheme is set, the DefaultScheme set up in AddAuthentication will be used. | |||||
/// </summary> | |||||
public string DefaultAuthenticationScheme { get; set; } | |||||
/// <summary> | |||||
/// Enable authentication challenge on dashboard request. | |||||
/// </summary> | |||||
public bool UseChallengeOnAuth { get; set; } | public bool UseChallengeOnAuth { get; set; } | ||||
/// <summary> | /// <summary> | ||||
/// Default ChallengeScheme used for Dashboard authentication. If no scheme is set, the DefaultScheme set up in AddAuthentication will be used. | |||||
/// Default scheme used for authentication challenge. If no scheme is set, the DefaultChallengeScheme set up in AddAuthentication will be used. | |||||
/// </summary> | /// </summary> | ||||
public string DefaultChallengeScheme { get; set; } | public string DefaultChallengeScheme { get; set; } | ||||
} | } |
@@ -47,11 +47,22 @@ namespace DotNetCore.CAP.Dashboard | |||||
if (httpMethod == "GET" && Regex.IsMatch(path, $"^/?{Regex.Escape(_options.PathMatch)}/?index.html$", RegexOptions.IgnoreCase)) | if (httpMethod == "GET" && Regex.IsMatch(path, $"^/?{Regex.Escape(_options.PathMatch)}/?index.html$", RegexOptions.IgnoreCase)) | ||||
{ | { | ||||
if (_options.UseAuth) | |||||
{ | |||||
var result = await httpContext.AuthenticateAsync(_options.DefaultAuthenticationScheme); | |||||
if (result.Succeeded && result.Principal != null) | |||||
{ | |||||
httpContext.User = result.Principal; | |||||
} | |||||
} | |||||
var isAuthenticated = httpContext.User?.Identity?.IsAuthenticated; | var isAuthenticated = httpContext.User?.Identity?.IsAuthenticated; | ||||
if (isAuthenticated == false && _options.UseChallengeOnAuth) | if (isAuthenticated == false && _options.UseChallengeOnAuth) | ||||
{ | { | ||||
await httpContext.ChallengeAsync(_options.DefaultChallengeScheme); | await httpContext.ChallengeAsync(_options.DefaultChallengeScheme); | ||||
return; | return; | ||||
} | } | ||||