@@ -2,7 +2,7 @@ | |||
<PropertyGroup> | |||
<VersionMajor>5</VersionMajor> | |||
<VersionMinor>1</VersionMinor> | |||
<VersionPatch>0</VersionPatch> | |||
<VersionPatch>1</VersionPatch> | |||
<VersionQuality></VersionQuality> | |||
<VersionPrefix>$(VersionMajor).$(VersionMinor).$(VersionPatch)</VersionPrefix> | |||
</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() | |||
.AddAuthentication(options => | |||
{ | |||
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; | |||
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; | |||
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; | |||
}) | |||
.AddCookie() | |||
@@ -36,7 +36,8 @@ namespace Sample.Dashboard.Auth | |||
options.Scope.Clear(); | |||
options.Scope.Add("openid"); | |||
options.Scope.Add("profile"); | |||
}); | |||
}) | |||
.AddScheme<MyDashboardAuthenticationSchemeOptions, MyDashboardAuthenticationHandler>("MyDashboardScheme",null); | |||
services.AddCors(x => | |||
{ | |||
@@ -45,13 +46,15 @@ namespace Sample.Dashboard.Auth | |||
p.WithOrigins("http://localhost:8080").AllowCredentials().AllowAnyHeader().AllowAnyMethod(); | |||
}); | |||
}); | |||
services.AddCap(cap => | |||
{ | |||
cap.UseDashboard(d => | |||
{ | |||
d.UseChallengeOnAuth = true; | |||
d.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; | |||
d.UseAuth = true; | |||
d.DefaultAuthenticationScheme = "MyDashboardScheme"; | |||
}); | |||
cap.UseMySql(_configuration.GetValue<string>("ConnectionString")); | |||
cap.UseRabbitMQ(aa => | |||
@@ -76,16 +79,16 @@ namespace Sample.Dashboard.Auth | |||
public void Configure(IApplicationBuilder app) | |||
{ | |||
app.UseAuthentication(); | |||
app.UseCors(); | |||
app.UseRouting(); | |||
app.UseAuthentication(); | |||
app.UseAuthorization(); | |||
app.UseCookiePolicy(); | |||
app.UseEndpoints(endpoints => | |||
{ | |||
endpoints.MapControllers(); | |||
endpoints.MapControllers(); | |||
}); | |||
} | |||
} | |||
} | |||
} |
@@ -13,16 +13,29 @@ namespace DotNetCore.CAP | |||
} | |||
public string PathMatch { get; set; } | |||
/// <summary> | |||
/// The interval the /stats endpoint should be polled with. | |||
/// </summary> | |||
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; } | |||
/// <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> | |||
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 (_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; | |||
if (isAuthenticated == false && _options.UseChallengeOnAuth) | |||
{ | |||
await httpContext.ChallengeAsync(_options.DefaultChallengeScheme); | |||
return; | |||
} | |||