You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@ -0,0 +1,332 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IdentityModel.Diagnostics;
|
||||
using System.IdentityModel.Policy;
|
||||
using System.Security.Claims;
|
||||
using System.Security.Principal;
|
||||
|
||||
using SysClaimSet = System.IdentityModel.Claims.ClaimSet;
|
||||
|
||||
namespace System.IdentityModel.Tokens
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines an AuthorizationPolicy that carries the IDFx Claims. When IDFx is enabled
|
||||
/// a new set of Security Token Authenticators are added to the system. These Authenticators
|
||||
/// will generate the new Claims defined in System.Security.Claims.
|
||||
/// </summary>
|
||||
internal class AuthorizationPolicy : IAuthorizationPolicy
|
||||
{
|
||||
#pragma warning disable 1591
|
||||
public const string ClaimsPrincipalKey = "ClaimsPrincipal"; // This key must be different from "Principal". "Principal" is reserved for Custom mode.
|
||||
public const string IdentitiesKey = "Identities";
|
||||
#pragma warning restore 1591
|
||||
|
||||
List<ClaimsIdentity> _identityCollection = new List<ClaimsIdentity>();
|
||||
|
||||
//
|
||||
// Add an issuer to specify that this is a IDFx issued AuthorizationPolicy.
|
||||
//
|
||||
SysClaimSet _issuer = SysClaimSet.System;
|
||||
string _id = UniqueId.CreateUniqueId();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes an instance of <see cref="AuthorizationPolicy"/>
|
||||
/// </summary>
|
||||
public AuthorizationPolicy()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes an instance of <see cref="AuthorizationPolicy"/>
|
||||
/// </summary>
|
||||
/// <param name="identity">ClaimsIdentity for the AuthorizationPolicy.</param>
|
||||
/// <exception cref="ArgumentNullException">One of the input argument is null.</exception>
|
||||
public AuthorizationPolicy(ClaimsIdentity identity)
|
||||
{
|
||||
if (identity == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("identity");
|
||||
}
|
||||
|
||||
_identityCollection.Add(identity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes an instance of <see cref="AuthorizationPolicy"/>
|
||||
/// </summary>
|
||||
/// <param name="identityCollection">Collection of identities.</param>
|
||||
public AuthorizationPolicy(IEnumerable<ClaimsIdentity> identityCollection)
|
||||
{
|
||||
if (identityCollection == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("identityCollection");
|
||||
}
|
||||
|
||||
List<ClaimsIdentity> collection = new List<ClaimsIdentity>();
|
||||
foreach (ClaimsIdentity identity in identityCollection)
|
||||
{
|
||||
collection.Add(identity);
|
||||
}
|
||||
|
||||
_identityCollection = collection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a ClaimsIdentity collection.
|
||||
/// </summary>
|
||||
public ReadOnlyCollection<ClaimsIdentity> IdentityCollection
|
||||
{
|
||||
get
|
||||
{
|
||||
return _identityCollection.AsReadOnly();
|
||||
}
|
||||
}
|
||||
|
||||
#region IAuthorizationPolicy Members
|
||||
|
||||
/// <summary>
|
||||
/// Evaluates the current Policy. This is provided for backward compatibility
|
||||
/// of WCF Claims model. We always return true without affecting the EvaluationContext.
|
||||
/// </summary>
|
||||
/// <param name="evaluationContext">The current EvaluationContext.</param>
|
||||
/// <param name="state">The reference state object.</param>
|
||||
/// <returns>True if the Policy was successfully applied.</returns>
|
||||
public bool Evaluate(EvaluationContext evaluationContext, ref object state)
|
||||
{
|
||||
if (null == evaluationContext || null == evaluationContext.Properties)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("evaluationContext");
|
||||
}
|
||||
|
||||
if (0 == _identityCollection.Count)
|
||||
{
|
||||
//
|
||||
// Nothing to do here.
|
||||
//
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// Locate or create the ClaimsPrincipal
|
||||
//
|
||||
object principalObj = null;
|
||||
if (!evaluationContext.Properties.TryGetValue(ClaimsPrincipalKey, out principalObj))
|
||||
{
|
||||
ClaimsPrincipal principalToAdd = CreateClaimsPrincipalFromIdentities(_identityCollection);
|
||||
|
||||
evaluationContext.Properties.Add(ClaimsPrincipalKey, principalToAdd);
|
||||
|
||||
if (DiagnosticUtility.ShouldTrace(TraceEventType.Information))
|
||||
{
|
||||
TraceUtility.TraceEvent(
|
||||
TraceEventType.Information,
|
||||
TraceCode.Diagnostics,
|
||||
SR.GetString(SR.TraceSetPrincipalOnEvaluationContext),
|
||||
new ClaimsPrincipalTraceRecord(principalToAdd),
|
||||
null,
|
||||
null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ClaimsPrincipal principal = principalObj as ClaimsPrincipal;
|
||||
if (null != principal && null != principal.Identities)
|
||||
{
|
||||
principal.AddIdentities(_identityCollection);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Someone stomped on our ClaimsPrincipal property key in the properties collection
|
||||
// Just trace this for now.
|
||||
//
|
||||
if (DiagnosticUtility.ShouldTrace(TraceEventType.Error))
|
||||
{
|
||||
TraceUtility.TraceString(
|
||||
TraceEventType.Error,
|
||||
SR.GetString(SR.ID8004,
|
||||
ClaimsPrincipalKey));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Locate or create evaluationContext.Properties[ "Identities" ] with identities
|
||||
//
|
||||
object identitiesObj = null;
|
||||
if (!evaluationContext.Properties.TryGetValue(IdentitiesKey, out identitiesObj))
|
||||
{
|
||||
List<ClaimsIdentity> identities = new List<ClaimsIdentity>();
|
||||
foreach (ClaimsIdentity ici in _identityCollection)
|
||||
{
|
||||
identities.Add(ici);
|
||||
}
|
||||
|
||||
evaluationContext.Properties.Add(IdentitiesKey, identities);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<ClaimsIdentity> identities;
|
||||
identities = identitiesObj as List<ClaimsIdentity>;
|
||||
|
||||
foreach (ClaimsIdentity ici in _identityCollection)
|
||||
{
|
||||
identities.Add(ici);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static ClaimsPrincipal CreateClaimsPrincipalFromIdentities(IEnumerable<ClaimsIdentity> identities)
|
||||
{
|
||||
ClaimsIdentity selectedClaimsIdentity = SelectPrimaryIdentity(identities);
|
||||
|
||||
if (selectedClaimsIdentity == null)
|
||||
{
|
||||
//return an anonymous identity
|
||||
return new ClaimsPrincipal(new ClaimsIdentity());
|
||||
}
|
||||
|
||||
ClaimsPrincipal principal = CreateFromIdentity(selectedClaimsIdentity);
|
||||
|
||||
// Add the remaining identities.
|
||||
foreach (ClaimsIdentity identity in identities)
|
||||
{
|
||||
if (identity != selectedClaimsIdentity)
|
||||
{
|
||||
principal.AddIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
return principal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the appropriate implementation of an IClaimsPrincipal base on the
|
||||
/// type of the specified IIdentity (e.g. WindowsClaimsPrincipal for a WindowsIdentity).
|
||||
/// Note the appropriate IClaimsIdentity is generated based on the specified IIdentity
|
||||
/// as well.
|
||||
/// </summary>
|
||||
/// <param name="identity">An implementation of IIdentity</param>
|
||||
/// <returns>A claims-based principal.</returns>
|
||||
private static ClaimsPrincipal CreateFromIdentity(IIdentity identity)
|
||||
{
|
||||
if (null == identity)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("identity");
|
||||
}
|
||||
|
||||
WindowsIdentity wci = identity as WindowsIdentity;
|
||||
if (null != wci)
|
||||
{
|
||||
return new WindowsPrincipal(wci);
|
||||
}
|
||||
|
||||
WindowsIdentity wi = identity as WindowsIdentity;
|
||||
if (null != wi)
|
||||
{
|
||||
return new WindowsPrincipal(wi);
|
||||
}
|
||||
|
||||
ClaimsIdentity ici = identity as ClaimsIdentity;
|
||||
if (null != ici)
|
||||
{
|
||||
return new ClaimsPrincipal(ici);
|
||||
}
|
||||
|
||||
return new ClaimsPrincipal(new ClaimsIdentity(identity));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method iterates through the collection of ClaimsIdentities
|
||||
/// and determines which identity must be used as the primary one.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the identities collection contains a WindowsClaimsIdentity, it is the most preferred.
|
||||
/// If the identities collection contains an RsaClaimsIdentity, it is the least preferred.
|
||||
/// </remarks>
|
||||
private static ClaimsIdentity SelectPrimaryIdentity(IEnumerable<ClaimsIdentity> identities)
|
||||
{
|
||||
if (identities == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("identities");
|
||||
}
|
||||
|
||||
//
|
||||
// Loop through the identities to determine the primary identity.
|
||||
//
|
||||
ClaimsIdentity selectedClaimsIdentity = null;
|
||||
|
||||
foreach (ClaimsIdentity identity in identities)
|
||||
{
|
||||
if (identity is WindowsIdentity)
|
||||
{
|
||||
//
|
||||
// If there is a WindowsIdentity, return that.
|
||||
//
|
||||
selectedClaimsIdentity = identity;
|
||||
break;
|
||||
}
|
||||
else if (identity.FindFirst(ClaimTypes.Rsa) != null)
|
||||
{
|
||||
//this is a RSA identity
|
||||
//it is the least preffered identity
|
||||
if (selectedClaimsIdentity == null)
|
||||
{
|
||||
selectedClaimsIdentity = identity;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
else if (selectedClaimsIdentity == null)
|
||||
{
|
||||
//
|
||||
// If no primary identity has been selected yet, choose the current identity.
|
||||
//
|
||||
selectedClaimsIdentity = identity;
|
||||
}
|
||||
}
|
||||
|
||||
return selectedClaimsIdentity;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Issuer Claimset. This will return a DefaultClaimSet with just one claim
|
||||
/// whose ClaimType is http://schemas.microsoft.com/claims/identityclaim.
|
||||
/// </summary>
|
||||
public SysClaimSet Issuer
|
||||
{
|
||||
get
|
||||
{
|
||||
return _issuer;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IAuthorizationComponent Members
|
||||
|
||||
/// <summary>
|
||||
/// Returns an Id for the ClaimsPrincipal.
|
||||
/// </summary>
|
||||
public string Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user