mirror of https://github.com/Squidex/squidex.git
14 changed files with 277 additions and 126 deletions
@ -0,0 +1,21 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Constants.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
namespace Squidex.Configurations |
||||
|
{ |
||||
|
public class Constants |
||||
|
{ |
||||
|
public const string ApiPrefix = "/api"; |
||||
|
|
||||
|
public const string ApiScope = "squidex-api"; |
||||
|
|
||||
|
public const string FrontendClient = "squidex-frontend"; |
||||
|
|
||||
|
public const string IdentityPrefix = "/identity-server"; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,65 @@ |
|||||
|
// ==========================================================================
|
||||
|
// LazyClientStore.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
using IdentityServer4.Models; |
||||
|
using IdentityServer4.Stores; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Squidex.Infrastructure; |
||||
|
|
||||
|
namespace Squidex.Configurations.Identity |
||||
|
{ |
||||
|
public class LazyClientStore : IClientStore |
||||
|
{ |
||||
|
private readonly Dictionary<string, Client> clients = new Dictionary<string, Client>(StringComparer.OrdinalIgnoreCase); |
||||
|
|
||||
|
public LazyClientStore(IOptions<MyIdentityOptions> identityOptions) |
||||
|
{ |
||||
|
Guard.NotNull(identityOptions, nameof(identityOptions)); |
||||
|
|
||||
|
foreach (var client in CreateClients(identityOptions.Value)) |
||||
|
{ |
||||
|
clients[client.ClientId] = client; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public Task<Client> FindClientByIdAsync(string clientId) |
||||
|
{ |
||||
|
var client = clients.GetOrDefault(clientId); |
||||
|
|
||||
|
return Task.FromResult(client); |
||||
|
} |
||||
|
|
||||
|
private static IEnumerable<Client> CreateClients(MyIdentityOptions options) |
||||
|
{ |
||||
|
const string id = Constants.FrontendClient; |
||||
|
|
||||
|
yield return new Client |
||||
|
{ |
||||
|
ClientId = id, |
||||
|
ClientName = id, |
||||
|
RedirectUris = new List<string> |
||||
|
{ |
||||
|
options.BuildUrl("identity-server/client-callback-silent/"), |
||||
|
options.BuildUrl("identity-server/client-callback-popup/") |
||||
|
}, |
||||
|
AllowAccessTokensViaBrowser = true, |
||||
|
AllowedGrantTypes = GrantTypes.Implicit, |
||||
|
AllowedScopes = new List<string> |
||||
|
{ |
||||
|
StandardScopes.OpenId.Name, |
||||
|
StandardScopes.Profile.Name, |
||||
|
Constants.ApiScope |
||||
|
}, |
||||
|
RequireConsent = false |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,23 +1,23 @@ |
|||||
// ==========================================================================
|
// ==========================================================================
|
||||
// InfrastructureUsage.cs
|
// WebModule.cs
|
||||
// Squidex Headless CMS
|
// Squidex Headless CMS
|
||||
// ==========================================================================
|
// ==========================================================================
|
||||
// Copyright (c) Squidex Group
|
// Copyright (c) Squidex Group
|
||||
// All rights reserved.
|
// All rights reserved.
|
||||
// ==========================================================================
|
// ==========================================================================
|
||||
|
|
||||
using Microsoft.AspNetCore.Builder; |
using Autofac; |
||||
using Squidex.Pipeline; |
using Squidex.Pipeline; |
||||
|
|
||||
namespace Squidex.Configurations.Domain |
namespace Squidex.Configurations.Web |
||||
{ |
{ |
||||
public static class InfrastructureUsage |
public class WebModule : Module |
||||
{ |
{ |
||||
public static IApplicationBuilder UseMyApps(this IApplicationBuilder app) |
protected override void Load(ContainerBuilder builder) |
||||
{ |
{ |
||||
app.UseMiddleware<AppMiddleware>(); |
builder.RegisterType<AppFilterAttribute>() |
||||
|
.AsSelf() |
||||
return app; |
.SingleInstance(); |
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
@ -0,0 +1,51 @@ |
|||||
|
// ==========================================================================
|
||||
|
// AppMiddleware.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Microsoft.AspNetCore.Mvc.Filters; |
||||
|
using Squidex.Read.Apps.Services; |
||||
|
|
||||
|
namespace Squidex.Pipeline |
||||
|
{ |
||||
|
public sealed class AppFilterAttribute : ActionFilterAttribute |
||||
|
{ |
||||
|
private readonly IAppProvider appProvider; |
||||
|
|
||||
|
public AppFilterAttribute(IAppProvider appProvider) |
||||
|
{ |
||||
|
this.appProvider = appProvider; |
||||
|
} |
||||
|
|
||||
|
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) |
||||
|
{ |
||||
|
var appName = context.RouteData.Values["app"]?.ToString(); |
||||
|
|
||||
|
if (!string.IsNullOrWhiteSpace(appName)) |
||||
|
{ |
||||
|
var appId = await appProvider.FindAppIdByNameAsync(appName); |
||||
|
|
||||
|
if (!appId.HasValue) |
||||
|
{ |
||||
|
context.Result = new NotFoundResult(); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (!context.HttpContext.User.HasClaim("app", appName)) |
||||
|
{ |
||||
|
context.Result = new NotFoundResult(); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
context.HttpContext.Features.Set<IAppFeature>(new AppFeature(appId.Value)); |
||||
|
} |
||||
|
|
||||
|
await next(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,46 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// AppMiddleware.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System.Threading.Tasks; |
|
||||
using Microsoft.AspNetCore.Hosting; |
|
||||
using Microsoft.AspNetCore.Http; |
|
||||
using Squidex.Read.Apps.Services; |
|
||||
|
|
||||
namespace Squidex.Pipeline |
|
||||
{ |
|
||||
public sealed class AppMiddleware |
|
||||
{ |
|
||||
private readonly IAppProvider appProvider; |
|
||||
private readonly IHostingEnvironment appEnvironment; |
|
||||
private readonly RequestDelegate next; |
|
||||
|
|
||||
public AppMiddleware(RequestDelegate next, IAppProvider appProvider, IHostingEnvironment appEnvironment) |
|
||||
{ |
|
||||
this.next = next; |
|
||||
this.appProvider = appProvider; |
|
||||
this.appEnvironment = appEnvironment; |
|
||||
} |
|
||||
|
|
||||
public async Task Invoke(HttpContext context) |
|
||||
{ |
|
||||
var hostParts = context.Request.Host.ToString().Split('.'); |
|
||||
|
|
||||
if (appEnvironment.IsDevelopment() || hostParts.Length >= 3) |
|
||||
{ |
|
||||
var appId = await appProvider.FindAppIdByNameAsync(hostParts[0]); |
|
||||
|
|
||||
if (appId.HasValue) |
|
||||
{ |
|
||||
context.Features.Set<IAppFeature>(new AppFeature(appId.Value)); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
await next(context); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
Loading…
Reference in new issue