Skip to content

Commit

Permalink
feat: Allow to specify applicable authentication schemes
Browse files Browse the repository at this point in the history
  • Loading branch information
me-viper committed Jan 25, 2024
1 parent 511d91c commit e2ce5de
Show file tree
Hide file tree
Showing 17 changed files with 295 additions and 119 deletions.
6 changes: 3 additions & 3 deletions samples/CustomBuiltins/CustomBuiltins.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\OpaDotNet.Extensions.AspNetCore\OpaDotNet.Extensions.AspNetCore.csproj" />
<ProjectReference Include="..\..\src\OpaDotNet.Extensions.AspNetCore\OpaDotNet.Extensions.AspNetCore.csproj"/>
</ItemGroup>

<ItemGroup>
Expand All @@ -18,11 +18,11 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="OpaDotNet.Compilation.Cli" Version="1.6.0" />
<PackageReference Include="OpaDotNet.Compilation.Cli" Version="1.6.0"/>
</ItemGroup>

<ItemGroup>
<Content Remove="caps2.json" />
<Content Remove="caps2.json"/>
<EmbeddedResource Include="caps2.json">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
Expand Down
4 changes: 2 additions & 2 deletions samples/WebApp/WebApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\OpaDotNet.Extensions.AspNetCore\OpaDotNet.Extensions.AspNetCore.csproj" />
<ProjectReference Include="..\..\src\OpaDotNet.Extensions.AspNetCore\OpaDotNet.Extensions.AspNetCore.csproj"/>
</ItemGroup>

<ItemGroup>
Expand All @@ -18,7 +18,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="OpaDotNet.Compilation.Cli" Version="1.6.0" />
<PackageReference Include="OpaDotNet.Compilation.Cli" Version="1.6.0"/>
</ItemGroup>

</Project>
16 changes: 8 additions & 8 deletions samples/YarpApp/YarpApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="NetEscapades.Configuration.Yaml" Version="3.1.0" />
<PackageReference Include="OpaDotNet.Compilation.Interop" Version="1.6.0" />
<PackageReference Include="Yarp.ReverseProxy" Version="2.1.0" />
<PackageReference Include="NetEscapades.Configuration.Yaml" Version="3.1.0"/>
<PackageReference Include="OpaDotNet.Compilation.Interop" Version="1.6.0"/>
<PackageReference Include="Yarp.ReverseProxy" Version="2.1.0"/>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\OpaDotNet.Extensions.AspNetCore\OpaDotNet.Extensions.AspNetCore.csproj" />
<ProjectReference Include="..\..\src\OpaDotNet.Extensions.AspNetCore\OpaDotNet.Extensions.AspNetCore.csproj"/>
</ItemGroup>

<ItemGroup>
Expand All @@ -24,10 +24,10 @@
</ItemGroup>

<ItemGroup>
<None Remove="build\**" />
<Compile Remove="build\**" />
<Content Remove="build\**" />
<EmbeddedResource Remove="build\**" />
<None Remove="build\**"/>
<Compile Remove="build\**"/>
<Content Remove="build\**"/>
<EmbeddedResource Remove="build\**"/>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public CompiledBundlePolicySource(

if (MonitoringEnabled)
{
CompositeChangeToken MakePolicyChangeToken() => new( new[] { fileProvider.Watch(file), } );
CompositeChangeToken MakePolicyChangeToken() => new(new[] { fileProvider.Watch(file), });

void OnPolicyChange()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ namespace OpaDotNet.Extensions.AspNetCore;

internal sealed class OpaAuthorizationBuilder : IOpaAuthorizationBuilder
{
private readonly HashSet<string> _authenticationSchemes = new();

public IServiceCollection Services { get; }

public IReadOnlySet<string> AuthenticationSchemes => _authenticationSchemes;

public OpaAuthorizationBuilder(IServiceCollection services)
{
ArgumentNullException.ThrowIfNull(services);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ public class OpaAuthorizationOptions
[UsedImplicitly]
public bool IncludeClaimsInHttpRequest { get; set; }

/// <summary>
/// Authentication schemes OPA policies will be evaluated against.
/// </summary>
[UsedImplicitly]
public HashSet<string> AuthenticationSchemes { get; set; } = new();

/// <summary>
/// Directory containing policy bundle source code.
/// </summary>
Expand Down
15 changes: 11 additions & 4 deletions src/OpaDotNet.Extensions.AspNetCore/OpaPolicyProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,22 @@ public class OpaPolicyProvider : IAuthorizationPolicyProvider
{
private readonly IAuthorizationPolicyProvider _default;

public OpaPolicyProvider(IOptions<AuthorizationOptions> options)
: this(options, new DefaultAuthorizationPolicyProvider(options))
private readonly IReadOnlySet<string> _authenticationSchemes;

public OpaPolicyProvider(IOptions<AuthorizationOptions> options, IOptions<OpaAuthorizationOptions> opaOptions)
: this(options, opaOptions, new DefaultAuthorizationPolicyProvider(options))
{
}

public OpaPolicyProvider(IOptions<AuthorizationOptions> options, IAuthorizationPolicyProvider defaultProvider)
public OpaPolicyProvider(
IOptions<AuthorizationOptions> options,
IOptions<OpaAuthorizationOptions> opaOptions,
IAuthorizationPolicyProvider defaultProvider)
{
ArgumentNullException.ThrowIfNull(options);
ArgumentNullException.ThrowIfNull(defaultProvider);

_authenticationSchemes = opaOptions.Value.AuthenticationSchemes;
_default = defaultProvider;
}

Expand All @@ -29,7 +35,8 @@ public OpaPolicyProvider(IOptions<AuthorizationOptions> options, IAuthorizationP
if (!OpaPolicyRequirement.TryParse(policyName, out var opr))
return _default.GetPolicyAsync(policyName);

var policy = new AuthorizationPolicyBuilder();
var policy = new AuthorizationPolicyBuilder(_authenticationSchemes.ToArray());

policy.AddRequirements(opr);
return Task.FromResult<AuthorizationPolicy?>(policy.Build());
}
Expand Down
11 changes: 6 additions & 5 deletions src/OpaDotNet.Extensions.AspNetCore/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

#nullable enable
abstract OpaDotNet.Extensions.AspNetCore.OpaPolicySource.CompileBundleFromSource(bool recompiling, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.IO.Stream?>!
OpaDotNet.Extensions.AspNetCore.ClaimPolicyInput
Expand All @@ -7,6 +6,8 @@ OpaDotNet.Extensions.AspNetCore.ClaimPolicyInput.Type.get -> string!
OpaDotNet.Extensions.AspNetCore.ClaimPolicyInput.Type.init -> void
OpaDotNet.Extensions.AspNetCore.ClaimPolicyInput.Value.get -> string!
OpaDotNet.Extensions.AspNetCore.ClaimPolicyInput.Value.init -> void
OpaDotNet.Extensions.AspNetCore.CompiledBundlePolicySource
OpaDotNet.Extensions.AspNetCore.CompiledBundlePolicySource.CompiledBundlePolicySource(OpaDotNet.Compilation.Abstractions.IRegoCompiler! compiler, Microsoft.Extensions.Options.IOptions<OpaDotNet.Extensions.AspNetCore.OpaAuthorizationOptions!>! options, OpaDotNet.Extensions.AspNetCore.IOpaImportsAbiFactory! importsAbiFactory, Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory) -> void
OpaDotNet.Extensions.AspNetCore.ConfigurationPolicySource
OpaDotNet.Extensions.AspNetCore.ConfigurationPolicySource.ConfigurationPolicySource(OpaDotNet.Compilation.Abstractions.IRegoCompiler! compiler, Microsoft.Extensions.Options.IOptions<OpaDotNet.Extensions.AspNetCore.OpaAuthorizationOptions!>! authOptions, Microsoft.Extensions.Options.IOptionsMonitor<OpaDotNet.Extensions.AspNetCore.OpaPolicyOptions!>! policy, OpaDotNet.Extensions.AspNetCore.IOpaImportsAbiFactory! importsAbiFactory, Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory) -> void
OpaDotNet.Extensions.AspNetCore.CoreImportsAbi
Expand Down Expand Up @@ -45,6 +46,8 @@ OpaDotNet.Extensions.AspNetCore.IOpaPolicySource.OnPolicyUpdated() -> Microsoft.
OpaDotNet.Extensions.AspNetCore.OpaAuthorizationOptions
OpaDotNet.Extensions.AspNetCore.OpaAuthorizationOptions.AllowedHeaders.get -> System.Collections.Generic.HashSet<string!>!
OpaDotNet.Extensions.AspNetCore.OpaAuthorizationOptions.AllowedHeaders.set -> void
OpaDotNet.Extensions.AspNetCore.OpaAuthorizationOptions.AuthenticationSchemes.get -> System.Collections.Generic.HashSet<string!>!
OpaDotNet.Extensions.AspNetCore.OpaAuthorizationOptions.AuthenticationSchemes.set -> void
OpaDotNet.Extensions.AspNetCore.OpaAuthorizationOptions.EngineOptions.get -> OpaDotNet.Wasm.WasmPolicyEngineOptions?
OpaDotNet.Extensions.AspNetCore.OpaAuthorizationOptions.EngineOptions.set -> void
OpaDotNet.Extensions.AspNetCore.OpaAuthorizationOptions.Entrypoints.get -> System.Collections.Generic.HashSet<string!>?
Expand Down Expand Up @@ -88,8 +91,8 @@ OpaDotNet.Extensions.AspNetCore.OpaPolicyProvider
OpaDotNet.Extensions.AspNetCore.OpaPolicyProvider.GetDefaultPolicyAsync() -> System.Threading.Tasks.Task<Microsoft.AspNetCore.Authorization.AuthorizationPolicy!>!
OpaDotNet.Extensions.AspNetCore.OpaPolicyProvider.GetFallbackPolicyAsync() -> System.Threading.Tasks.Task<Microsoft.AspNetCore.Authorization.AuthorizationPolicy?>!
OpaDotNet.Extensions.AspNetCore.OpaPolicyProvider.GetPolicyAsync(string! policyName) -> System.Threading.Tasks.Task<Microsoft.AspNetCore.Authorization.AuthorizationPolicy?>!
OpaDotNet.Extensions.AspNetCore.OpaPolicyProvider.OpaPolicyProvider(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Authorization.AuthorizationOptions!>! options) -> void
OpaDotNet.Extensions.AspNetCore.OpaPolicyProvider.OpaPolicyProvider(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Authorization.AuthorizationOptions!>! options, Microsoft.AspNetCore.Authorization.IAuthorizationPolicyProvider! defaultProvider) -> void
OpaDotNet.Extensions.AspNetCore.OpaPolicyProvider.OpaPolicyProvider(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Authorization.AuthorizationOptions!>! options, Microsoft.Extensions.Options.IOptions<OpaDotNet.Extensions.AspNetCore.OpaAuthorizationOptions!>! opaOptions, Microsoft.AspNetCore.Authorization.IAuthorizationPolicyProvider! defaultProvider) -> void
OpaDotNet.Extensions.AspNetCore.OpaPolicyProvider.OpaPolicyProvider(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Authorization.AuthorizationOptions!>! options, Microsoft.Extensions.Options.IOptions<OpaDotNet.Extensions.AspNetCore.OpaAuthorizationOptions!>! opaOptions) -> void
OpaDotNet.Extensions.AspNetCore.OpaPolicyRequirement
OpaDotNet.Extensions.AspNetCore.OpaPolicyRequirement.Entrypoint.get -> string!
OpaDotNet.Extensions.AspNetCore.OpaPolicyRequirement.OpaPolicyRequirement(string! entrypoint) -> void
Expand All @@ -111,8 +114,6 @@ OpaDotNet.Extensions.AspNetCore.PathPolicySource.NeedsRecompilation.set -> void
OpaDotNet.Extensions.AspNetCore.PathPolicySource.PathPolicySource(OpaDotNet.Compilation.Abstractions.IRegoCompiler! compiler, Microsoft.Extensions.Options.IOptions<OpaDotNet.Extensions.AspNetCore.OpaAuthorizationOptions!>! options, OpaDotNet.Extensions.AspNetCore.IOpaImportsAbiFactory! importsAbiFactory, Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory) -> void
OpaDotNet.Extensions.AspNetCore.PathPolicySource.PolicyWatcher.get -> System.IDisposable?
OpaDotNet.Extensions.AspNetCore.PathPolicySource.PolicyWatcher.init -> void
OpaDotNet.Extensions.AspNetCore.CompiledBundlePolicySource
OpaDotNet.Extensions.AspNetCore.CompiledBundlePolicySource.CompiledBundlePolicySource(OpaDotNet.Compilation.Abstractions.IRegoCompiler! compiler, Microsoft.Extensions.Options.IOptions<OpaDotNet.Extensions.AspNetCore.OpaAuthorizationOptions!>! options, OpaDotNet.Extensions.AspNetCore.IOpaImportsAbiFactory! importsAbiFactory, Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory) -> void
OpaDotNet.Extensions.AspNetCore.ServiceCollectionExtensions
override OpaDotNet.Extensions.AspNetCore.ConfigurationPolicySource.CompileBundleFromSource(bool recompiling, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.IO.Stream?>!
override OpaDotNet.Extensions.AspNetCore.ConfigurationPolicySource.Dispose(bool disposing) -> void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,10 @@ public static IServiceCollection AddOpaAuthorization(
ArgumentNullException.ThrowIfNull(services);
ArgumentNullException.ThrowIfNull(configure);

services.AddOpaAuthorization();
configure(new OpaAuthorizationBuilder(services));
var builder = new OpaAuthorizationBuilder(services);
configure(builder);

services.AddOpaAuthorization(builder);

services.TryAddTransient<IOpaImportsAbi, CoreImportsAbi>();
services.TryAddSingleton<IOpaImportsAbiFactory>(
Expand All @@ -221,12 +223,15 @@ public static IServiceCollection AddOpaAuthorization(
return services;
}

private static IServiceCollection AddOpaAuthorization(this IServiceCollection services)
private static IServiceCollection AddOpaAuthorization(this IServiceCollection services, OpaAuthorizationBuilder builder)
{
services.AddOptions();
services.TryAddSingleton<OpaEvaluatorPoolProvider>();
services.TryAddSingleton<IAuthorizationPolicyProvider>(
p => new OpaPolicyProvider(p.GetRequiredService<IOptions<AuthorizationOptions>>())
p => new OpaPolicyProvider(
p.GetRequiredService<IOptions<AuthorizationOptions>>(),
p.GetRequiredService<IOptions<OpaAuthorizationOptions>>()
)
);
services.TryAddSingleton<IAuthorizationHandler, OpaPolicyHandler>();
services.TryAddSingleton<IOpaPolicyService, PooledOpaPolicyService>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Text.Encodings.Web;

using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace OpaDotNet.Extensions.AspNetCore.Tests;

internal class AlwaysFailAuthenticationSchemeHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
#if NET8_0_OR_GREATER
public AlwaysFailAuthenticationSchemeHandler(
IOptionsMonitor<AuthenticationSchemeOptions> options,
ILoggerFactory logger,
UrlEncoder encoder) : base(options, logger, encoder)
{
}
#else
public AlwaysFailAuthenticationSchemeHandler(
IOptionsMonitor<AuthenticationSchemeOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock) : base(options, logger, encoder, clock)
{
}
#endif

protected override Task<AuthenticateResult> HandleAuthenticateAsync()
{
var result = AuthenticateResult.NoResult();
return Task.FromResult(result);
}
}
Loading

0 comments on commit e2ce5de

Please sign in to comment.