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();
|
Claims = (claims ?? Enumerable.Empty<Claim>()).ToList();
|
||||||
User = user;
|
User = user;
|
||||||
Resource = resource;
|
Resource = resource;
|
||||||
|
|
||||||
|
// user claims are copied to a new and mutable list
|
||||||
|
UserClaims = user != null
|
||||||
|
? user.Claims.ToList()
|
||||||
|
: new List<Claim>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -28,6 +33,14 @@ namespace Microsoft.AspNet.Security.Authorization
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ClaimsPrincipal User { get; private set; }
|
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>
|
/// <summary>
|
||||||
/// An optional resource associated to the check.
|
/// An optional resource associated to the check.
|
||||||
/// </summary>
|
/// </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.User != null)
|
||||||
{
|
{
|
||||||
if (context.Claims.Any(claim => user.HasClaim(claim.Type, claim.Value)))
|
if (ClaimsMatch(context.Claims, context.UserClaims))
|
||||||
{
|
{
|
||||||
context.Authorized = true;
|
context.Authorized = true;
|
||||||
}
|
}
|
||||||
|
|
@ -95,5 +95,16 @@ namespace Microsoft.AspNet.Security.Authorization
|
||||||
{
|
{
|
||||||
return AuthorizeAsync(claims, user, resource).Result;
|
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]
|
[Fact]
|
||||||
public void Check_ApplyCanMutateClaims()
|
public void Check_ApplyCanMutateCheckedClaims()
|
||||||
{
|
{
|
||||||
|
|
||||||
// Arrange
|
// Arrange
|
||||||
|
|
@ -272,5 +272,35 @@ namespace Microsoft.AspNet.Security.Test
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(allowed);
|
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