Ensure schemes aren't used on components authorization. Fixes #10570 (#12239)

This commit is contained in:
Steve Sanderson 2019-07-17 09:33:51 +01:00 committed by GitHub
parent 96f55fcf25
commit f4f5b16e93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 0 deletions

View File

@ -102,10 +102,27 @@ namespace Microsoft.AspNetCore.Components
private async Task<bool> IsAuthorizedAsync(ClaimsPrincipal user)
{
var authorizeData = GetAuthorizeData();
EnsureNoAuthenticationSchemeSpecified(authorizeData);
var policy = await AuthorizationPolicy.CombineAsync(
AuthorizationPolicyProvider, authorizeData);
var result = await AuthorizationService.AuthorizeAsync(user, Resource, policy);
return result.Succeeded;
}
private static void EnsureNoAuthenticationSchemeSpecified(IAuthorizeData[] authorizeData)
{
// It's not meaningful to specify a nonempty scheme, since by the time Components
// authorization runs, we already have a specific ClaimsPrincipal (we're stateful).
// To avoid any confusion, ensure the developer isn't trying to specify a scheme.
for (var i = 0; i < authorizeData.Length; i++)
{
var entry = authorizeData[i];
if (!string.IsNullOrEmpty(entry.AuthenticationSchemes))
{
throw new NotSupportedException($"The authorization data specifies an authentication scheme with value '{entry.AuthenticationSchemes}'. Authentication schemes cannot be specified for components.");
}
}
}
}
}

View File

@ -427,6 +427,24 @@ namespace Microsoft.AspNetCore.Components
});
}
[Fact]
public void RejectsNonemptyScheme()
{
// Arrange
var authorizationService = new TestAuthorizationService();
var renderer = CreateTestRenderer(authorizationService);
var rootComponent = new TestAuthStateProviderComponent(builder =>
{
builder.OpenComponent<AuthorizeViewCoreWithScheme>(0);
builder.CloseComponent();
});
renderer.AssignRootComponentId(rootComponent);
// Act/Assert
var ex = Assert.Throws<NotSupportedException>(rootComponent.TriggerRender);
Assert.Equal("The authorization data specifies an authentication scheme with value 'test scheme'. Authentication schemes cannot be specified for components.", ex.Message);
}
private static TestAuthStateProviderComponent WrapInAuthorizeView(
RenderFragment<AuthenticationState> childContent = null,
RenderFragment<AuthenticationState> authorizedContent = null,
@ -557,5 +575,11 @@ namespace Microsoft.AspNetCore.Components
{
public string PolicyName { get; set; }
}
public class AuthorizeViewCoreWithScheme : AuthorizeViewCore
{
protected override IAuthorizeData[] GetAuthorizeData()
=> new[] { new AuthorizeAttribute { AuthenticationSchemes = "test scheme" } };
}
}
}