Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/BasicSample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ type Query {
// remove claims to see the failure
var authorizedUser = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim("role", "Admin") }));

string json = await schema.ExecuteAsync(_ =>
string json = await schema.ExecuteAsync(options =>
{
_.Query = "{ viewer { id name } }";
_.ValidationRules = serviceProvider
options.Query = "{ viewer { id name } }";
options.ValidationRules = serviceProvider
.GetServices<IValidationRule>()
.Concat(DocumentValidator.CoreRules);
_.RequestServices = serviceProvider;
_.UserContext = new GraphQLUserContext { User = authorizedUser };
options.RequestServices = serviceProvider;
options.UserContext = new GraphQLUserContext { User = authorizedUser };
});

Console.WriteLine(json);
Expand Down
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>

<PropertyGroup>
<VersionPrefix>4.0.0-preview</VersionPrefix>
<VersionPrefix>4.1.0-preview</VersionPrefix>
<LangVersion>8.0</LangVersion>
<Authors>Joe McBride</Authors>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ namespace GraphQL.Authorization
public ClaimAuthorizationRequirement(string claimType, System.Collections.Generic.IEnumerable<string> allowedValues) { }
public ClaimAuthorizationRequirement(string claimType, params string[] allowedValues) { }
public ClaimAuthorizationRequirement(string claimType, System.Collections.Generic.IEnumerable<string> allowedValues, System.Collections.Generic.IEnumerable<string> displayValues) { }
public System.Collections.Generic.IEnumerable<string> AllowedValues { get; }
public string ClaimType { get; }
public System.Collections.Generic.IEnumerable<string> DisplayValues { get; }
public System.Threading.Tasks.Task Authorize(GraphQL.Authorization.AuthorizationContext context) { }
}
public interface IAuthorizationEvaluator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ namespace GraphQL.Authorization
/// </summary>
public class ClaimAuthorizationRequirement : IAuthorizationRequirement
{
private readonly string _claimType;
private readonly IEnumerable<string> _displayValues;
private readonly IEnumerable<string> _allowedValues;

/// <summary>
/// Creates a new instance of <see cref="ClaimAuthorizationRequirement"/> with
/// the specified claim type.
Expand Down Expand Up @@ -53,41 +49,58 @@ public ClaimAuthorizationRequirement(string claimType, params string[] allowedVa
/// </summary>
public ClaimAuthorizationRequirement(string claimType, IEnumerable<string> allowedValues, IEnumerable<string> displayValues)
{
_claimType = claimType ?? throw new ArgumentNullException(nameof(claimType));
_allowedValues = allowedValues ?? Enumerable.Empty<string>();
_displayValues = displayValues;
ClaimType = claimType ?? throw new ArgumentNullException(nameof(claimType));
AllowedValues = allowedValues ?? Enumerable.Empty<string>();
DisplayValues = displayValues;
}

/// <summary>
/// Claim type that claims principal from <see cref="AuthorizationContext"/> should have.
/// </summary>
public string ClaimType { get; }

/// <summary>
/// List of claim values, which, if present, the claim must match.
/// </summary>
public IEnumerable<string> AllowedValues { get; }

/// <summary>
/// Specifies the set of displayed claim values that will be used
/// to generate an error message if the requirement is not met.
/// If null then values from <see cref="AllowedValues"/> are used.
/// </summary>
public IEnumerable<string> DisplayValues { get; }

/// <inheritdoc />
public Task Authorize(AuthorizationContext context)
{
bool found = false;

if (context.User != null)
{
if (_allowedValues == null || !_allowedValues.Any())
if (AllowedValues == null || !AllowedValues.Any())
{
found = context.User.Claims.Any(
claim => string.Equals(claim.Type, _claimType, StringComparison.OrdinalIgnoreCase));
claim => string.Equals(claim.Type, ClaimType, StringComparison.OrdinalIgnoreCase));
}
else
{
found = context.User.Claims.Any(
claim => string.Equals(claim.Type, _claimType, StringComparison.OrdinalIgnoreCase)
&& _allowedValues.Contains(claim.Value, StringComparer.Ordinal));
claim => string.Equals(claim.Type, ClaimType, StringComparison.OrdinalIgnoreCase)
&& AllowedValues.Contains(claim.Value, StringComparer.Ordinal));
}
}

if (!found)
{
if (_allowedValues != null && _allowedValues.Any())
if (AllowedValues != null && AllowedValues.Any())
{
string values = string.Join(", ", _displayValues ?? _allowedValues);
context.ReportError($"Required claim '{_claimType}' with any value of '{values}' is not present.");
string values = string.Join(", ", DisplayValues ?? AllowedValues);
context.ReportError($"Required claim '{ClaimType}' with any value of '{values}' is not present.");
}
else
{
context.ReportError($"Required claim '{_claimType}' is not present.");
context.ReportError($"Required claim '{ClaimType}' is not present.");
}
}

Expand Down