Sfoglia il codice sorgente

Fix/dashboard auth (#793)

* Moved app.UseCapDashboard() later in the pipeline and added new parameter to ChallengeAsync with built-in Authorization and Authentication

* Added a sample for using Authenticated dashboards with OpenId
master
Mateus Viegas 3 anni fa
committed by GitHub
parent
commit
8056d49643
Non sono state trovate chiavi note per questa firma nel database ID Chiave GPG: 4AEE18F83AFDEB23
9 ha cambiato i file con 226 aggiunte e 2 eliminazioni
  1. +7
    -0
      CAP.sln
  2. +52
    -0
      samples/Sample.RabbitMQ.Postgres.DashboardAuth/Controllers/ValuesController.cs
  3. +21
    -0
      samples/Sample.RabbitMQ.Postgres.DashboardAuth/HttpContextDashboardFilter.cs
  4. +17
    -0
      samples/Sample.RabbitMQ.Postgres.DashboardAuth/Program.cs
  5. +17
    -0
      samples/Sample.RabbitMQ.Postgres.DashboardAuth/Sample.RabbitMQ.Postgres.DashboardAuth.csproj
  6. +84
    -0
      samples/Sample.RabbitMQ.Postgres.DashboardAuth/Startup.cs
  7. +13
    -0
      samples/Sample.RabbitMQ.Postgres.DashboardAuth/appsettings.json
  8. +9
    -2
      src/DotNetCore.CAP.Dashboard/CAP.DashboardMiddleware.cs
  9. +6
    -0
      src/DotNetCore.CAP.Dashboard/CAP.DashboardOptions.cs

+ 7
- 0
CAP.sln Vedi File

@@ -69,6 +69,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.AmazonSQS.InMemory",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.CAP.NATS", "src\DotNetCore.CAP.NATS\DotNetCore.CAP.NATS.csproj", "{8B2FD3EA-E72B-4A82-B182-B87EC0C15D07}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.RabbitMQ.Postgres.DashboardAuth", "samples\Sample.RabbitMQ.Postgres.DashboardAuth\Sample.RabbitMQ.Postgres.DashboardAuth.csproj", "{54F6C206-2A23-4971-AE5A-FC47EB772452}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -159,6 +161,10 @@ Global
{8B2FD3EA-E72B-4A82-B182-B87EC0C15D07}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8B2FD3EA-E72B-4A82-B182-B87EC0C15D07}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8B2FD3EA-E72B-4A82-B182-B87EC0C15D07}.Release|Any CPU.Build.0 = Release|Any CPU
{54F6C206-2A23-4971-AE5A-FC47EB772452}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{54F6C206-2A23-4971-AE5A-FC47EB772452}.Debug|Any CPU.Build.0 = Debug|Any CPU
{54F6C206-2A23-4971-AE5A-FC47EB772452}.Release|Any CPU.ActiveCfg = Release|Any CPU
{54F6C206-2A23-4971-AE5A-FC47EB772452}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -185,6 +191,7 @@ Global
{43475E00-51B7-443D-BC2D-FC21F9D8A0B4} = {9B2AE124-6636-4DE9-83A3-70360DABD0C4}
{B187DD15-092D-4B72-9807-50856607D237} = {3A6B6931-A123-477A-9469-8B468B5385AF}
{8B2FD3EA-E72B-4A82-B182-B87EC0C15D07} = {9B2AE124-6636-4DE9-83A3-70360DABD0C4}
{54F6C206-2A23-4971-AE5A-FC47EB772452} = {3A6B6931-A123-477A-9469-8B468B5385AF}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2E70565D-94CF-40B4-BFE1-AC18D5F736AB}


+ 52
- 0
samples/Sample.RabbitMQ.Postgres.DashboardAuth/Controllers/ValuesController.cs Vedi File

@@ -0,0 +1,52 @@
using System;
using System.Threading.Tasks;
using DotNetCore.CAP;
using DotNetCore.CAP.Messages;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace Sample.RabbitMQ.Postgres.DashboardAuth.Controllers
{
[Authorize]
[Route("api/[controller]")]
public class ValuesController : Controller
{
private readonly ICapPublisher _capBus;
private readonly ILogger<ValuesController> _logger;
private const string CapGroup = "sample.rabbitmq.postgres.dashboard";

public ValuesController(ICapPublisher capPublisher, ILogger<ValuesController> logger)
{
_capBus = capPublisher;
_logger = logger;
}

[Route("publish")]
public async Task<IActionResult> Publish()
{
await _capBus.PublishAsync(CapGroup, new Person()
{
Id = 123,
Name = "Bar"
});

return Ok();
}

[NonAction]
[CapSubscribe(CapGroup)]
public void Subscribe(Person p, [FromCap] CapHeader header)
{
var id = header[Headers.MessageId];

_logger.LogInformation($@"{DateTime.Now} Subscriber invoked for message {id}, Info: {p}");
}

public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
}
}

+ 21
- 0
samples/Sample.RabbitMQ.Postgres.DashboardAuth/HttpContextDashboardFilter.cs Vedi File

@@ -0,0 +1,21 @@
using System;
using System.Threading.Tasks;
using DotNetCore.CAP.Dashboard;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

namespace Sample.RabbitMQ.Postgres.DashboardAuth
{
public class HttpContextDashboardFilter : IDashboardAuthorizationFilter
{
public async Task<bool> AuthorizeAsync(DashboardContext context)
{
var httpContextAccessor = context.RequestServices.GetRequiredService<IHttpContextAccessor>();

if (httpContextAccessor is null)
throw new ArgumentException("Configure IHttpContextAccessor as a service on Startup");

return httpContextAccessor.HttpContext?.User?.Identity?.IsAuthenticated == true;
}
}
}

+ 17
- 0
samples/Sample.RabbitMQ.Postgres.DashboardAuth/Program.cs Vedi File

@@ -0,0 +1,17 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace Sample.RabbitMQ.Postgres.DashboardAuth
{
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>(); });
}
}

+ 17
- 0
samples/Sample.RabbitMQ.Postgres.DashboardAuth/Sample.RabbitMQ.Postgres.DashboardAuth.csproj Vedi File

@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\DotNetCore.CAP.Dashboard\DotNetCore.CAP.Dashboard.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP.RabbitMQ\DotNetCore.CAP.RabbitMQ.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP.PostgreSql\DotNetCore.CAP.PostgreSql.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP\DotNetCore.CAP.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="5.0.3" />
</ItemGroup>
</Project>

+ 84
- 0
samples/Sample.RabbitMQ.Postgres.DashboardAuth/Startup.cs Vedi File

@@ -0,0 +1,84 @@
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Sample.RabbitMQ.Postgres.DashboardAuth
{
public class Startup
{
private readonly IConfiguration _configuration;

public Startup(IConfiguration configuration)
{
_configuration = configuration;
}

public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
services
.AddAuthorization()
.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.Authority = "https://demo.identityserver.io/";
options.ClientId = "interactive.confidential";
options.ClientSecret = "secret";
options.ResponseType = "code";
options.UsePkce = true;

options.Scope.Clear();
options.Scope.Add("openid");
options.Scope.Add("profile");
});
services.AddCap(cap =>
{
cap.UsePostgreSql(p =>
{
p.ConnectionString = _configuration.GetConnectionString("Postgres");
});

/*
* Use the command below to start a rabbitmq instance locally:
* docker run -d --name rabbitmq -p 15672:15672 -p 5672:5672 rabbitmq:management
*/
cap.UseRabbitMQ(r =>
{
r.Port = 5672;
r.HostName = "127.0.0.1";
r.UserName = "guest";
r.Password = "guest";
});

cap.UseDashboard(d =>
{
d.UseChallengeOnAuth = true;
d.Authorization = new[] {new HttpContextDashboardFilter()};
});
});

services.AddControllers();
}

public void Configure(IApplicationBuilder app)
{
app.UseAuthentication();
app.UseRouting();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}

+ 13
- 0
samples/Sample.RabbitMQ.Postgres.DashboardAuth/appsettings.json Vedi File

@@ -0,0 +1,13 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"Postgres": "Server=127.0.0.1;Port=5432;Database=cap;Uid=postgres;Pwd=root;Include Error Detail=true;"
}
}

+ 9
- 2
src/DotNetCore.CAP.Dashboard/CAP.DashboardMiddleware.cs Vedi File

@@ -10,6 +10,7 @@ using DotNetCore.CAP.Dashboard.GatewayProxy;
using DotNetCore.CAP.Dashboard.NodeDiscovery;
using DotNetCore.CAP.Dashboard.Resources;
using DotNetCore.CAP.Persistence;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
@@ -74,9 +75,9 @@ namespace DotNetCore.CAP
{
return app =>
{
app.UseCapDashboard();

next(app);
app.UseCapDashboard();
};
}
}
@@ -133,6 +134,12 @@ namespace DotNetCore.CAP

var isAuthenticated = context.User?.Identity?.IsAuthenticated;

if (_options.UseChallengeOnAuth)
{
await context.ChallengeAsync();
return;
}

context.Response.StatusCode = isAuthenticated == true
? (int)HttpStatusCode.Forbidden
: (int)HttpStatusCode.Unauthorized;


+ 6
- 0
src/DotNetCore.CAP.Dashboard/CAP.DashboardOptions.cs Vedi File

@@ -15,8 +15,14 @@ namespace DotNetCore.CAP
PathMatch = "/cap";
Authorization = new[] {new LocalRequestsOnlyAuthorizationFilter()};
StatsPollingInterval = 2000;
UseChallengeOnAuth = false;
}

/// <summary>
/// Indicates if executes a Challenge for Auth within ASP.NET middlewares
/// </summary>
public bool UseChallengeOnAuth { get; set; }

/// <summary>
/// The path for the Back To Site link. Set to <see langword="null" /> in order to hide the Back To Site link.
/// </summary>


Caricamento…
Annulla
Salva