parent
c64934ad53
commit
b7ed0faa33
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Authorization
|
||||
{
|
||||
/// <summary>
|
||||
/// This class provides a base implementation for <see cref="IAuthorizationPolicy" />
|
||||
/// </summary>
|
||||
public abstract class AuthorizationPolicy : IAuthorizationPolicy
|
||||
{
|
||||
public int Order { get; set; }
|
||||
|
||||
public virtual Task ApplyingAsync(AuthorizationPolicyContext context)
|
||||
{
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public virtual Task ApplyAsync(AuthorizationPolicyContext context)
|
||||
{
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public virtual Task AppliedAsync(AuthorizationPolicyContext context)
|
||||
{
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,11 @@ namespace Microsoft.AspNet.Security.Authorization
|
|||
Claims = (claims ?? Enumerable.Empty<Claim>()).ToList();
|
||||
User = user;
|
||||
Resource = resource;
|
||||
|
||||
// user claims are copied to a new and mutable list
|
||||
UserClaims = user != null
|
||||
? user.Claims.ToList()
|
||||
: new List<Claim>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -28,6 +33,14 @@ namespace Microsoft.AspNet.Security.Authorization
|
|||
/// </summary>
|
||||
public ClaimsPrincipal User { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The claims of the user.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This list can be modified by policies for retries.
|
||||
/// </remarks>
|
||||
public IList<Claim> UserClaims { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// An optional resource associated to the check.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Authorization
|
||||
{
|
||||
public static class AuthorizationServiceExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks if a user has specific claims.
|
||||
/// </summary>
|
||||
/// <param name="claim">The claim to check against a specific user.</param>
|
||||
/// <param name="user">The user to check claims against.</param>
|
||||
/// <returns><value>true</value> when the user fulfills one of the claims, <value>false</value> otherwise.</returns>
|
||||
public static Task<bool> AuthorizeAsync(this IAuthorizationService service, Claim claim, ClaimsPrincipal user)
|
||||
{
|
||||
return service.AuthorizeAsync(new Claim[] { claim }, user);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a user has specific claims.
|
||||
/// </summary>
|
||||
/// <param name="claim">The claim to check against a specific user.</param>
|
||||
/// <param name="user">The user to check claims against.</param>
|
||||
/// <returns><value>true</value> when the user fulfills one of the claims, <value>false</value> otherwise.</returns>
|
||||
public static bool Authorize(this IAuthorizationService service, Claim claim, ClaimsPrincipal user)
|
||||
{
|
||||
return service.Authorize(new Claim[] { claim }, user);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a user has specific claims for a specific context obj.
|
||||
/// </summary>
|
||||
/// <param name="claim">The claim to check against a specific user.</param>
|
||||
/// <param name="user">The user to check claims against.</param>
|
||||
/// <param name="resource">The resource the claims should be check with.</param>
|
||||
/// <returns><value>true</value> when the user fulfills one of the claims, <value>false</value> otherwise.</returns>
|
||||
public static Task<bool> AuthorizeAsync(this IAuthorizationService service, Claim claim, ClaimsPrincipal user, object resource)
|
||||
{
|
||||
return service.AuthorizeAsync(new Claim[] { claim }, user, resource);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a user has specific claims for a specific context obj.
|
||||
/// </summary>
|
||||
/// <param name="claim">The claimsto check against a specific user.</param>
|
||||
/// <param name="user">The user to check claims against.</param>
|
||||
/// <param name="resource">The resource the claims should be check with.</param>
|
||||
/// <returns><value>true</value> when the user fulfills one of the claims, <value>false</value> otherwise.</returns>
|
||||
public static bool Authorize(this IAuthorizationService service, Claim claim, ClaimsPrincipal user, object resource)
|
||||
{
|
||||
return service.Authorize(new Claim[] { claim }, user, resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -55,7 +55,7 @@ namespace Microsoft.AspNet.Security.Authorization
|
|||
{
|
||||
if (context.User != null)
|
||||
{
|
||||
if (context.Claims.Any(claim => user.HasClaim(claim.Type, claim.Value)))
|
||||
if (ClaimsMatch(context.Claims, context.UserClaims))
|
||||
{
|
||||
context.Authorized = true;
|
||||
}
|
||||
|
|
@ -95,5 +95,16 @@ namespace Microsoft.AspNet.Security.Authorization
|
|||
{
|
||||
return AuthorizeAsync(claims, user, resource).Result;
|
||||
}
|
||||
|
||||
private bool ClaimsMatch([NotNull] IEnumerable<Claim> x, [NotNull] IEnumerable<Claim> y)
|
||||
{
|
||||
return x.Any(claim =>
|
||||
y.Any(userClaim =>
|
||||
string.Equals(claim.Type, userClaim.Type, StringComparison.OrdinalIgnoreCase) &&
|
||||
string.Equals(claim.Value, userClaim.Value, StringComparison.Ordinal)
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -243,7 +243,7 @@ namespace Microsoft.AspNet.Security.Test
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void Check_ApplyCanMutateClaims()
|
||||
public void Check_ApplyCanMutateCheckedClaims()
|
||||
{
|
||||
|
||||
// Arrange
|
||||
|
|
@ -272,5 +272,35 @@ namespace Microsoft.AspNet.Security.Test
|
|||
// Assert
|
||||
Assert.True(allowed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Check_PoliciesCanMutateUsersClaims()
|
||||
{
|
||||
|
||||
// Arrange
|
||||
var user = new ClaimsPrincipal(
|
||||
new ClaimsIdentity(new Claim[0], "Basic")
|
||||
);
|
||||
|
||||
var policies = new IAuthorizationPolicy[] {
|
||||
new FakePolicy() {
|
||||
ApplyAsyncAction = (context) => {
|
||||
if (!context.Authorized)
|
||||
{
|
||||
context.UserClaims.Add(new Claim("Permission", "CanDeleteComments"));
|
||||
context.Retry = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var authorizationService = new DefaultAuthorizationService(policies);
|
||||
|
||||
// Act
|
||||
var allowed = authorizationService.Authorize(new Claim("Permission", "CanDeleteComments"), user);
|
||||
|
||||
// Assert
|
||||
Assert.True(allowed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue