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,35 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace System.IdentityModel.Selectors
|
||||
{
|
||||
using System.ComponentModel;
|
||||
|
||||
public enum AudienceUriMode
|
||||
{
|
||||
Never,
|
||||
Always,
|
||||
BearerKeyOnly
|
||||
}
|
||||
|
||||
public static class AudienceUriModeValidationHelper
|
||||
{
|
||||
public static bool IsDefined(AudienceUriMode validationMode)
|
||||
{
|
||||
return validationMode == AudienceUriMode.Never
|
||||
|| validationMode == AudienceUriMode.Always
|
||||
|| validationMode == AudienceUriMode.BearerKeyOnly;
|
||||
}
|
||||
|
||||
internal static void Validate(AudienceUriMode value)
|
||||
{
|
||||
if (!IsDefined(value))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("value", (int)value,
|
||||
typeof(AudienceUriMode)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.IdentityModel.Selectors
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IdentityModel.Claims;
|
||||
using System.IdentityModel.Policy;
|
||||
using System.IdentityModel.Tokens;
|
||||
using System.Security.Principal;
|
||||
|
||||
public class CustomUserNameSecurityTokenAuthenticator : UserNameSecurityTokenAuthenticator
|
||||
{
|
||||
UserNamePasswordValidator validator;
|
||||
|
||||
public CustomUserNameSecurityTokenAuthenticator(UserNamePasswordValidator validator)
|
||||
{
|
||||
if (validator == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("validator");
|
||||
this.validator = validator;
|
||||
}
|
||||
|
||||
protected override ReadOnlyCollection<IAuthorizationPolicy> ValidateUserNamePasswordCore(string userName, string password)
|
||||
{
|
||||
this.validator.Validate(userName, password);
|
||||
return SecurityUtils.CreateAuthorizationPolicies(new UserNameClaimSet(userName, validator.GetType().Name));
|
||||
}
|
||||
|
||||
class UserNameClaimSet : DefaultClaimSet, IIdentityInfo
|
||||
{
|
||||
IIdentity identity;
|
||||
|
||||
public UserNameClaimSet(string userName, string authType)
|
||||
{
|
||||
if (userName == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("userName");
|
||||
|
||||
this.identity = SecurityUtils.CreateIdentity(userName, authType);
|
||||
|
||||
List<Claim> claims = new List<Claim>(2);
|
||||
claims.Add(new Claim(ClaimTypes.Name, userName, Rights.Identity));
|
||||
claims.Add(Claim.CreateNameClaim(userName));
|
||||
Initialize(ClaimSet.System, claims);
|
||||
}
|
||||
|
||||
public IIdentity Identity
|
||||
{
|
||||
get { return this.identity; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.IdentityModel.Selectors
|
||||
{
|
||||
using System.IdentityModel.Tokens;
|
||||
|
||||
static class EmptySecurityTokenResolver
|
||||
{
|
||||
static readonly SecurityTokenResolver _instance
|
||||
= SecurityTokenResolver.CreateDefaultSecurityTokenResolver( EmptyReadOnlyCollection<SecurityToken>.Instance, false );
|
||||
|
||||
public static SecurityTokenResolver Instance { get { return _instance; } }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.IdentityModel.Selectors
|
||||
{
|
||||
using System.IdentityModel.Tokens;
|
||||
|
||||
public class KerberosSecurityTokenAuthenticator : WindowsSecurityTokenAuthenticator
|
||||
{
|
||||
public KerberosSecurityTokenAuthenticator()
|
||||
{
|
||||
}
|
||||
|
||||
public KerberosSecurityTokenAuthenticator(bool includeWindowsGroups)
|
||||
: base(includeWindowsGroups)
|
||||
{
|
||||
}
|
||||
|
||||
protected override bool CanValidateTokenCore(SecurityToken token)
|
||||
{
|
||||
return token is KerberosReceiverSecurityToken;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.IdentityModel.Selectors
|
||||
{
|
||||
using System.IdentityModel.Tokens;
|
||||
using System.Net;
|
||||
using System.Security.Authentication.ExtendedProtection;
|
||||
using System.Security.Principal;
|
||||
|
||||
public class KerberosSecurityTokenProvider : SecurityTokenProvider
|
||||
{
|
||||
string servicePrincipalName;
|
||||
TokenImpersonationLevel tokenImpersonationLevel;
|
||||
NetworkCredential networkCredential;
|
||||
|
||||
public KerberosSecurityTokenProvider(string servicePrincipalName)
|
||||
: this(servicePrincipalName, TokenImpersonationLevel.Identification)
|
||||
{
|
||||
}
|
||||
|
||||
public KerberosSecurityTokenProvider(string servicePrincipalName, TokenImpersonationLevel tokenImpersonationLevel)
|
||||
: this(servicePrincipalName, tokenImpersonationLevel, null)
|
||||
{
|
||||
}
|
||||
|
||||
public KerberosSecurityTokenProvider(string servicePrincipalName, TokenImpersonationLevel tokenImpersonationLevel, NetworkCredential networkCredential)
|
||||
{
|
||||
if (servicePrincipalName == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("servicePrincipalName");
|
||||
if (tokenImpersonationLevel != TokenImpersonationLevel.Identification && tokenImpersonationLevel != TokenImpersonationLevel.Impersonation)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("tokenImpersonationLevel",
|
||||
SR.GetString(SR.ImpersonationLevelNotSupported, tokenImpersonationLevel)));
|
||||
}
|
||||
|
||||
this.servicePrincipalName = servicePrincipalName;
|
||||
this.tokenImpersonationLevel = tokenImpersonationLevel;
|
||||
this.networkCredential = networkCredential;
|
||||
}
|
||||
|
||||
public string ServicePrincipalName
|
||||
{
|
||||
get { return this.servicePrincipalName; }
|
||||
}
|
||||
|
||||
public TokenImpersonationLevel TokenImpersonationLevel
|
||||
{
|
||||
get { return this.tokenImpersonationLevel; }
|
||||
}
|
||||
|
||||
public NetworkCredential NetworkCredential
|
||||
{
|
||||
get { return this.networkCredential; }
|
||||
}
|
||||
|
||||
internal SecurityToken GetToken(TimeSpan timeout, ChannelBinding channelbinding)
|
||||
{
|
||||
return new KerberosRequestorSecurityToken(this.ServicePrincipalName,
|
||||
this.TokenImpersonationLevel, this.NetworkCredential,
|
||||
SecurityUniqueId.Create().Value, channelbinding);
|
||||
}
|
||||
protected override SecurityToken GetTokenCore(TimeSpan timeout)
|
||||
{
|
||||
return this.GetToken(timeout, null);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.IdentityModel.Selectors
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IdentityModel.Claims;
|
||||
using System.IdentityModel.Policy;
|
||||
using System.IdentityModel.Tokens;
|
||||
|
||||
public class RsaSecurityTokenAuthenticator : SecurityTokenAuthenticator
|
||||
{
|
||||
public RsaSecurityTokenAuthenticator()
|
||||
{
|
||||
}
|
||||
|
||||
protected override bool CanValidateTokenCore(SecurityToken token)
|
||||
{
|
||||
return token is RsaSecurityToken;
|
||||
}
|
||||
|
||||
protected override ReadOnlyCollection<IAuthorizationPolicy> ValidateTokenCore(SecurityToken token)
|
||||
{
|
||||
RsaSecurityToken rsaToken = (RsaSecurityToken)token;
|
||||
List<Claim> claims = new List<Claim>(2);
|
||||
claims.Add(new Claim(ClaimTypes.Rsa, rsaToken.Rsa, Rights.Identity));
|
||||
claims.Add(Claim.CreateRsaClaim(rsaToken.Rsa));
|
||||
|
||||
DefaultClaimSet claimSet = new DefaultClaimSet(ClaimSet.Anonymous, claims);
|
||||
List<IAuthorizationPolicy> policies = new List<IAuthorizationPolicy>(1);
|
||||
policies.Add(new UnconditionalPolicy(claimSet, rsaToken.ValidTo));
|
||||
return policies.AsReadOnly();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace System.IdentityModel.Selectors
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
using System.IdentityModel.Claims;
|
||||
using System.IdentityModel.Tokens;
|
||||
using System.IdentityModel.Policy;
|
||||
using System.Security.Principal;
|
||||
using System.Security;
|
||||
|
||||
public class SamlSecurityTokenAuthenticator : SecurityTokenAuthenticator
|
||||
{
|
||||
List<SecurityTokenAuthenticator> supportingAuthenticators;
|
||||
Collection<string> allowedAudienceUris;
|
||||
AudienceUriMode audienceUriMode;
|
||||
TimeSpan maxClockSkew;
|
||||
|
||||
public SamlSecurityTokenAuthenticator(IList<SecurityTokenAuthenticator> supportingAuthenticators)
|
||||
: this(supportingAuthenticators, TimeSpan.Zero)
|
||||
{ }
|
||||
|
||||
public SamlSecurityTokenAuthenticator(IList<SecurityTokenAuthenticator> supportingAuthenticators, TimeSpan maxClockSkew)
|
||||
{
|
||||
|
||||
if (supportingAuthenticators == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("supportingAuthenticators");
|
||||
|
||||
this.supportingAuthenticators = new List<SecurityTokenAuthenticator>(supportingAuthenticators.Count);
|
||||
for (int i = 0; i < supportingAuthenticators.Count; ++i)
|
||||
{
|
||||
this.supportingAuthenticators.Add(supportingAuthenticators[i]);
|
||||
}
|
||||
|
||||
this.maxClockSkew = maxClockSkew;
|
||||
this.audienceUriMode = AudienceUriMode.Always;
|
||||
this.allowedAudienceUris = new Collection<string>();
|
||||
}
|
||||
|
||||
public AudienceUriMode AudienceUriMode
|
||||
{
|
||||
get { return this.audienceUriMode; }
|
||||
set
|
||||
{
|
||||
AudienceUriModeValidationHelper.Validate(audienceUriMode);
|
||||
this.audienceUriMode = value;
|
||||
}
|
||||
}
|
||||
|
||||
public IList<string> AllowedAudienceUris
|
||||
{
|
||||
get { return this.allowedAudienceUris; }
|
||||
}
|
||||
|
||||
protected override bool CanValidateTokenCore(SecurityToken token)
|
||||
{
|
||||
return token is SamlSecurityToken;
|
||||
}
|
||||
|
||||
protected override ReadOnlyCollection<IAuthorizationPolicy> ValidateTokenCore(SecurityToken token)
|
||||
{
|
||||
if (token == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token");
|
||||
|
||||
SamlSecurityToken samlToken = token as SamlSecurityToken;
|
||||
|
||||
if (samlToken == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.SamlTokenAuthenticatorCanOnlyProcessSamlTokens, token.GetType().ToString())));
|
||||
|
||||
if (samlToken.Assertion.Signature == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.SamlTokenMissingSignature)));
|
||||
|
||||
if (!this.IsCurrentlyTimeEffective(samlToken))
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.SAMLTokenTimeInvalid, DateTime.UtcNow.ToUniversalTime(), samlToken.ValidFrom.ToString(), samlToken.ValidTo.ToString())));
|
||||
|
||||
if (samlToken.Assertion.SigningToken == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.SamlSigningTokenMissing)));
|
||||
|
||||
// Build the Issuer ClaimSet for this Saml token.
|
||||
ClaimSet issuer = null;
|
||||
bool canBeValidated = false;
|
||||
for (int i = 0; i < this.supportingAuthenticators.Count; ++i)
|
||||
{
|
||||
canBeValidated = this.supportingAuthenticators[i].CanValidateToken(samlToken.Assertion.SigningToken);
|
||||
if (canBeValidated)
|
||||
break;
|
||||
}
|
||||
if (!canBeValidated)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.SamlInvalidSigningToken)));
|
||||
issuer = ResolveClaimSet(samlToken.Assertion.SigningToken) ?? ClaimSet.Anonymous;
|
||||
|
||||
List<IAuthorizationPolicy> policies = new List<IAuthorizationPolicy>();
|
||||
for (int i = 0; i < samlToken.Assertion.Statements.Count; ++i)
|
||||
{
|
||||
policies.Add(samlToken.Assertion.Statements[i].CreatePolicy(issuer, this));
|
||||
}
|
||||
|
||||
|
||||
// Check AudienceUri if required
|
||||
// AudienceUriMode != Never - don't need to check can only be one of three
|
||||
// AudienceUriMode == Always
|
||||
// AudienceUriMode == BearerKey and there are no proof keys
|
||||
//
|
||||
if ((this.audienceUriMode == AudienceUriMode.Always)
|
||||
|| (this.audienceUriMode == AudienceUriMode.BearerKeyOnly) && (samlToken.SecurityKeys.Count < 1))
|
||||
{
|
||||
// throws if not found.
|
||||
bool foundAudienceCondition = false;
|
||||
if (this.allowedAudienceUris == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.SAMLAudienceUrisNotFound)));
|
||||
}
|
||||
|
||||
for (int i = 0; i < samlToken.Assertion.Conditions.Conditions.Count; i++)
|
||||
{
|
||||
|
||||
SamlAudienceRestrictionCondition audienceCondition = samlToken.Assertion.Conditions.Conditions[i] as SamlAudienceRestrictionCondition;
|
||||
if (audienceCondition == null)
|
||||
continue;
|
||||
|
||||
foundAudienceCondition = true;
|
||||
if (!ValidateAudienceRestriction(audienceCondition))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.SAMLAudienceUriValidationFailed)));
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundAudienceCondition)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.SAMLAudienceUriValidationFailed)));
|
||||
}
|
||||
|
||||
return policies.AsReadOnly();
|
||||
}
|
||||
|
||||
protected virtual bool ValidateAudienceRestriction(SamlAudienceRestrictionCondition audienceRestrictionCondition)
|
||||
{
|
||||
for (int i = 0; i < audienceRestrictionCondition.Audiences.Count; i++)
|
||||
{
|
||||
if (audienceRestrictionCondition.Audiences[i] == null)
|
||||
continue;
|
||||
|
||||
for (int j = 0; j < this.allowedAudienceUris.Count; j++)
|
||||
{
|
||||
if (StringComparer.Ordinal.Compare(audienceRestrictionCondition.Audiences[i].AbsoluteUri, this.allowedAudienceUris[j]) == 0)
|
||||
return true;
|
||||
else if (Uri.IsWellFormedUriString(this.allowedAudienceUris[j], UriKind.Absolute))
|
||||
{
|
||||
Uri uri = new Uri(this.allowedAudienceUris[j]);
|
||||
if (audienceRestrictionCondition.Audiences[i].Equals(uri))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual ClaimSet ResolveClaimSet(SecurityToken token)
|
||||
{
|
||||
if (token == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token");
|
||||
|
||||
for (int i = 0; i < this.supportingAuthenticators.Count; ++i)
|
||||
{
|
||||
if (this.supportingAuthenticators[i].CanValidateToken(token))
|
||||
{
|
||||
ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies = this.supportingAuthenticators[i].ValidateToken(token);
|
||||
AuthorizationContext authContext = AuthorizationContext.CreateDefaultAuthorizationContext(authorizationPolicies);
|
||||
if (authContext.ClaimSets.Count > 0)
|
||||
{
|
||||
return authContext.ClaimSets[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual ClaimSet ResolveClaimSet(SecurityKeyIdentifier keyIdentifier)
|
||||
{
|
||||
if (keyIdentifier == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifier");
|
||||
|
||||
RsaKeyIdentifierClause rsaKeyIdentifierClause;
|
||||
EncryptedKeyIdentifierClause encryptedKeyIdentifierClause;
|
||||
if (keyIdentifier.TryFind<RsaKeyIdentifierClause>(out rsaKeyIdentifierClause))
|
||||
{
|
||||
return new DefaultClaimSet(new Claim(ClaimTypes.Rsa, rsaKeyIdentifierClause.Rsa, Rights.PossessProperty));
|
||||
}
|
||||
else if (keyIdentifier.TryFind<EncryptedKeyIdentifierClause>(out encryptedKeyIdentifierClause))
|
||||
{
|
||||
return new DefaultClaimSet(Claim.CreateHashClaim(encryptedKeyIdentifierClause.GetBuffer()));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual IIdentity ResolveIdentity(SecurityToken token)
|
||||
{
|
||||
if (token == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token");
|
||||
|
||||
for (int i = 0; i < this.supportingAuthenticators.Count; ++i)
|
||||
{
|
||||
if (this.supportingAuthenticators[i].CanValidateToken(token))
|
||||
{
|
||||
ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies = this.supportingAuthenticators[i].ValidateToken(token);
|
||||
if (authorizationPolicies != null && authorizationPolicies.Count != 0)
|
||||
{
|
||||
for (int j = 0; j < authorizationPolicies.Count; ++j)
|
||||
{
|
||||
IAuthorizationPolicy policy = authorizationPolicies[j];
|
||||
if (policy is UnconditionalPolicy)
|
||||
{
|
||||
return ((UnconditionalPolicy)policy).PrimaryIdentity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual IIdentity ResolveIdentity(SecurityKeyIdentifier keyIdentifier)
|
||||
{
|
||||
if (keyIdentifier == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifier");
|
||||
|
||||
RsaKeyIdentifierClause rsaKeyIdentifierClause;
|
||||
if (keyIdentifier.TryFind<RsaKeyIdentifierClause>(out rsaKeyIdentifierClause))
|
||||
{
|
||||
return SecurityUtils.CreateIdentity(rsaKeyIdentifierClause.Rsa.ToXmlString(false), this.GetType().Name);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
bool IsCurrentlyTimeEffective(SamlSecurityToken token)
|
||||
{
|
||||
if (token.Assertion.Conditions != null)
|
||||
{
|
||||
return SecurityUtils.IsCurrentlyTimeEffective(token.Assertion.Conditions.NotBefore, token.Assertion.Conditions.NotOnOrAfter, this.maxClockSkew);
|
||||
}
|
||||
|
||||
// If SAML Condition is not present then the assertion is valid at any given time.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.IdentityModel.Selectors
|
||||
{
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IdentityModel.Diagnostics.Application;
|
||||
using System.IdentityModel.Policy;
|
||||
using System.IdentityModel.Tokens;
|
||||
using System.Runtime.Diagnostics;
|
||||
|
||||
public abstract class SecurityTokenAuthenticator
|
||||
{
|
||||
protected SecurityTokenAuthenticator() { }
|
||||
|
||||
public bool CanValidateToken(SecurityToken token)
|
||||
{
|
||||
if (token == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token");
|
||||
}
|
||||
return this.CanValidateTokenCore(token);
|
||||
}
|
||||
|
||||
public ReadOnlyCollection<IAuthorizationPolicy> ValidateToken(SecurityToken token)
|
||||
{
|
||||
if (token == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token");
|
||||
}
|
||||
if (!CanValidateToken(token))
|
||||
{
|
||||
// warning 56506: Parameter 'token' to this public method must be validated: A null-dereference can occur here.
|
||||
#pragma warning suppress 56506
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(SR.GetString(SR.CannotValidateSecurityTokenType, this, token.GetType())));
|
||||
}
|
||||
|
||||
EventTraceActivity eventTraceActivity = null;
|
||||
string tokenType = null;
|
||||
|
||||
if (TD.TokenValidationStartedIsEnabled())
|
||||
{
|
||||
eventTraceActivity = eventTraceActivity ?? EventTraceActivity.GetFromThreadOrCreate();
|
||||
tokenType = tokenType ?? token.GetType().ToString();
|
||||
TD.TokenValidationStarted(eventTraceActivity, tokenType, token.Id);
|
||||
}
|
||||
|
||||
ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies = ValidateTokenCore(token);
|
||||
if (authorizationPolicies == null)
|
||||
{
|
||||
string errorMsg = SR.GetString(SR.CannotValidateSecurityTokenType, this, token.GetType());
|
||||
if (TD.TokenValidationFailureIsEnabled())
|
||||
{
|
||||
eventTraceActivity = eventTraceActivity ?? EventTraceActivity.GetFromThreadOrCreate();
|
||||
tokenType = tokenType ?? token.GetType().ToString();
|
||||
TD.TokenValidationFailure(eventTraceActivity, tokenType, token.Id, errorMsg);
|
||||
}
|
||||
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(errorMsg));
|
||||
}
|
||||
|
||||
if (TD.TokenValidationSuccessIsEnabled())
|
||||
{
|
||||
eventTraceActivity = eventTraceActivity ?? EventTraceActivity.GetFromThreadOrCreate();
|
||||
tokenType = tokenType ?? token.GetType().ToString();
|
||||
TD.TokenValidationSuccess(eventTraceActivity, tokenType, token.Id);
|
||||
}
|
||||
|
||||
return authorizationPolicies;
|
||||
}
|
||||
|
||||
protected abstract bool CanValidateTokenCore(SecurityToken token);
|
||||
protected abstract ReadOnlyCollection<IAuthorizationPolicy> ValidateTokenCore(SecurityToken token);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.IdentityModel.Selectors
|
||||
{
|
||||
/// <summary>
|
||||
/// Uber class that will create SecurityTokenProvider, SecurityTokenAuthenticator and SecurityTokenSerializer objects
|
||||
/// </summary>
|
||||
public abstract class SecurityTokenManager
|
||||
{
|
||||
public abstract SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement);
|
||||
public abstract SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version);
|
||||
public abstract SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.IdentityModel.Selectors
|
||||
{
|
||||
using System.IdentityModel.Diagnostics;
|
||||
using System.IdentityModel.Tokens;
|
||||
using System.Runtime;
|
||||
using System.Threading;
|
||||
|
||||
public abstract class SecurityTokenProvider
|
||||
{
|
||||
protected SecurityTokenProvider() { }
|
||||
|
||||
public virtual bool SupportsTokenRenewal
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public virtual bool SupportsTokenCancellation
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public SecurityToken GetToken(TimeSpan timeout)
|
||||
{
|
||||
SecurityToken token = this.GetTokenCore(timeout);
|
||||
if (token == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.TokenProviderUnableToGetToken, this)));
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
public IAsyncResult BeginGetToken(TimeSpan timeout, AsyncCallback callback, object state)
|
||||
{
|
||||
return this.BeginGetTokenCore(timeout, callback, state);
|
||||
}
|
||||
|
||||
public SecurityToken EndGetToken(IAsyncResult result)
|
||||
{
|
||||
if (result == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("result");
|
||||
}
|
||||
SecurityToken token = this.EndGetTokenCore(result);
|
||||
if (token == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.TokenProviderUnableToGetToken, this)));
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
public SecurityToken RenewToken(TimeSpan timeout, SecurityToken tokenToBeRenewed)
|
||||
{
|
||||
if (tokenToBeRenewed == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokenToBeRenewed");
|
||||
}
|
||||
SecurityToken token = this.RenewTokenCore(timeout, tokenToBeRenewed);
|
||||
if (token == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.TokenProviderUnableToRenewToken, this)));
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
public IAsyncResult BeginRenewToken(TimeSpan timeout, SecurityToken tokenToBeRenewed, AsyncCallback callback, object state)
|
||||
{
|
||||
if (tokenToBeRenewed == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokenToBeRenewed");
|
||||
}
|
||||
return this.BeginRenewTokenCore(timeout, tokenToBeRenewed, callback, state);
|
||||
}
|
||||
|
||||
public SecurityToken EndRenewToken(IAsyncResult result)
|
||||
{
|
||||
if (result == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("result");
|
||||
}
|
||||
SecurityToken token = this.EndRenewTokenCore(result);
|
||||
if (token == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.TokenProviderUnableToRenewToken, this)));
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
public void CancelToken(TimeSpan timeout, SecurityToken token)
|
||||
{
|
||||
if (token == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token");
|
||||
}
|
||||
this.CancelTokenCore(timeout, token);
|
||||
}
|
||||
|
||||
public IAsyncResult BeginCancelToken(TimeSpan timeout, SecurityToken token, AsyncCallback callback, object state)
|
||||
{
|
||||
if (token == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token");
|
||||
}
|
||||
return this.BeginCancelTokenCore(timeout, token, callback, state);
|
||||
}
|
||||
|
||||
public void EndCancelToken(IAsyncResult result)
|
||||
{
|
||||
if (result == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("result");
|
||||
}
|
||||
this.EndCancelTokenCore(result);
|
||||
}
|
||||
|
||||
// protected methods
|
||||
protected abstract SecurityToken GetTokenCore(TimeSpan timeout);
|
||||
|
||||
protected virtual SecurityToken RenewTokenCore(TimeSpan timeout, SecurityToken tokenToBeRenewed)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.TokenRenewalNotSupported, this)));
|
||||
}
|
||||
|
||||
protected virtual void CancelTokenCore(TimeSpan timeout, SecurityToken token)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.TokenCancellationNotSupported, this)));
|
||||
}
|
||||
|
||||
protected virtual IAsyncResult BeginGetTokenCore(TimeSpan timeout, AsyncCallback callback, object state)
|
||||
{
|
||||
SecurityToken token = this.GetToken(timeout);
|
||||
return new SecurityTokenAsyncResult(token, callback, state);
|
||||
}
|
||||
|
||||
protected virtual SecurityToken EndGetTokenCore(IAsyncResult result)
|
||||
{
|
||||
return SecurityTokenAsyncResult.End(result);
|
||||
}
|
||||
|
||||
protected virtual IAsyncResult BeginRenewTokenCore(TimeSpan timeout, SecurityToken tokenToBeRenewed, AsyncCallback callback, object state)
|
||||
{
|
||||
SecurityToken token = this.RenewTokenCore(timeout, tokenToBeRenewed);
|
||||
return new SecurityTokenAsyncResult(token, callback, state);
|
||||
}
|
||||
|
||||
protected virtual SecurityToken EndRenewTokenCore(IAsyncResult result)
|
||||
{
|
||||
return SecurityTokenAsyncResult.End(result);
|
||||
}
|
||||
|
||||
protected virtual IAsyncResult BeginCancelTokenCore(TimeSpan timeout, SecurityToken token, AsyncCallback callback, object state)
|
||||
{
|
||||
this.CancelToken(timeout, token);
|
||||
return new SecurityTokenAsyncResult(null, callback, state);
|
||||
}
|
||||
|
||||
protected virtual void EndCancelTokenCore(IAsyncResult result)
|
||||
{
|
||||
SecurityTokenAsyncResult.End(result);
|
||||
}
|
||||
|
||||
internal protected class SecurityTokenAsyncResult : IAsyncResult
|
||||
{
|
||||
SecurityToken token;
|
||||
object state;
|
||||
ManualResetEvent manualResetEvent;
|
||||
object thisLock = new object();
|
||||
|
||||
public SecurityTokenAsyncResult(SecurityToken token, AsyncCallback callback, object state)
|
||||
{
|
||||
this.token = token;
|
||||
this.state = state;
|
||||
|
||||
if (callback != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
callback(this);
|
||||
}
|
||||
#pragma warning suppress 56500
|
||||
catch (Exception e)
|
||||
{
|
||||
if (Fx.IsFatal(e))
|
||||
throw;
|
||||
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(SR.GetString(SR.AsyncCallbackException), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public object AsyncState
|
||||
{
|
||||
get { return this.state; }
|
||||
}
|
||||
|
||||
public WaitHandle AsyncWaitHandle
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.manualResetEvent != null)
|
||||
{
|
||||
return this.manualResetEvent;
|
||||
}
|
||||
|
||||
lock (thisLock)
|
||||
{
|
||||
if (this.manualResetEvent == null)
|
||||
{
|
||||
this.manualResetEvent = new ManualResetEvent(true);
|
||||
}
|
||||
}
|
||||
return this.manualResetEvent;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CompletedSynchronously
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public bool IsCompleted
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public static SecurityToken End(IAsyncResult result)
|
||||
{
|
||||
if (result == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("result");
|
||||
}
|
||||
|
||||
SecurityTokenAsyncResult completedResult = result as SecurityTokenAsyncResult;
|
||||
if (completedResult == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.InvalidAsyncResult), "result"));
|
||||
}
|
||||
|
||||
return completedResult.token;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.IdentityModel.Selectors
|
||||
{
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Tokens;
|
||||
|
||||
public class SecurityTokenRequirement
|
||||
{
|
||||
const string Namespace = "http://schemas.microsoft.com/ws/2006/05/identitymodel/securitytokenrequirement";
|
||||
const string tokenTypeProperty = Namespace + "/TokenType";
|
||||
const string keyUsageProperty = Namespace + "/KeyUsage";
|
||||
const string keyTypeProperty = Namespace + "/KeyType";
|
||||
const string keySizeProperty = Namespace + "/KeySize";
|
||||
const string requireCryptographicTokenProperty = Namespace + "/RequireCryptographicToken";
|
||||
const string peerAuthenticationMode = Namespace + "/PeerAuthenticationMode";
|
||||
const string isOptionalTokenProperty = Namespace + "/IsOptionalTokenProperty";
|
||||
|
||||
const bool defaultRequireCryptographicToken = false;
|
||||
const SecurityKeyUsage defaultKeyUsage = SecurityKeyUsage.Signature;
|
||||
const SecurityKeyType defaultKeyType = SecurityKeyType.SymmetricKey;
|
||||
const int defaultKeySize = 0;
|
||||
const bool defaultIsOptionalToken = false;
|
||||
|
||||
Dictionary<string, object> properties;
|
||||
|
||||
public SecurityTokenRequirement()
|
||||
{
|
||||
properties = new Dictionary<string, object>();
|
||||
this.Initialize();
|
||||
}
|
||||
|
||||
static public string TokenTypeProperty { get { return tokenTypeProperty; } }
|
||||
static public string KeyUsageProperty { get { return keyUsageProperty; } }
|
||||
static public string KeyTypeProperty { get { return keyTypeProperty; } }
|
||||
static public string KeySizeProperty { get { return keySizeProperty; } }
|
||||
static public string RequireCryptographicTokenProperty { get { return requireCryptographicTokenProperty; } }
|
||||
static public string PeerAuthenticationMode { get { return peerAuthenticationMode; } }
|
||||
static public string IsOptionalTokenProperty { get { return isOptionalTokenProperty; } }
|
||||
|
||||
public string TokenType
|
||||
{
|
||||
get
|
||||
{
|
||||
string result;
|
||||
return (this.TryGetProperty<string>(TokenTypeProperty, out result)) ? result : null;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.properties[TokenTypeProperty] = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsOptionalToken
|
||||
{
|
||||
get
|
||||
{
|
||||
bool result;
|
||||
return (this.TryGetProperty<bool>(IsOptionalTokenProperty, out result)) ? result : defaultIsOptionalToken;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.properties[IsOptionalTokenProperty] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool RequireCryptographicToken
|
||||
{
|
||||
get
|
||||
{
|
||||
bool result;
|
||||
return (this.TryGetProperty<bool>(RequireCryptographicTokenProperty, out result)) ? result : defaultRequireCryptographicToken;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.properties[RequireCryptographicTokenProperty] = (object)value;
|
||||
}
|
||||
}
|
||||
|
||||
public SecurityKeyUsage KeyUsage
|
||||
{
|
||||
get
|
||||
{
|
||||
SecurityKeyUsage result;
|
||||
return (this.TryGetProperty<SecurityKeyUsage>(KeyUsageProperty, out result)) ? result : defaultKeyUsage;
|
||||
}
|
||||
set
|
||||
{
|
||||
SecurityKeyUsageHelper.Validate(value);
|
||||
this.properties[KeyUsageProperty] = (object)value;
|
||||
}
|
||||
}
|
||||
|
||||
public SecurityKeyType KeyType
|
||||
{
|
||||
get
|
||||
{
|
||||
SecurityKeyType result;
|
||||
return (this.TryGetProperty<SecurityKeyType>(KeyTypeProperty, out result)) ? result : defaultKeyType;
|
||||
}
|
||||
set
|
||||
{
|
||||
SecurityKeyTypeHelper.Validate(value);
|
||||
this.properties[KeyTypeProperty] = (object)value;
|
||||
}
|
||||
}
|
||||
|
||||
public int KeySize
|
||||
{
|
||||
get
|
||||
{
|
||||
int result;
|
||||
return (this.TryGetProperty<int>(KeySizeProperty, out result)) ? result : defaultKeySize;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", SR.GetString(SR.ValueMustBeNonNegative)));
|
||||
}
|
||||
this.Properties[KeySizeProperty] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public IDictionary<string, object> Properties
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.properties;
|
||||
}
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
this.KeyType = defaultKeyType;
|
||||
this.KeyUsage = defaultKeyUsage;
|
||||
this.RequireCryptographicToken = defaultRequireCryptographicToken;
|
||||
this.KeySize = defaultKeySize;
|
||||
this.IsOptionalToken = defaultIsOptionalToken;
|
||||
}
|
||||
|
||||
public TValue GetProperty<TValue>(string propertyName)
|
||||
{
|
||||
TValue result;
|
||||
if (!TryGetProperty<TValue>(propertyName, out result))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.SecurityTokenRequirementDoesNotContainProperty, propertyName)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool TryGetProperty<TValue>(string propertyName, out TValue result)
|
||||
{
|
||||
object dictionaryValue;
|
||||
if (!Properties.TryGetValue(propertyName, out dictionaryValue))
|
||||
{
|
||||
result = default(TValue);
|
||||
return false;
|
||||
}
|
||||
if (dictionaryValue != null && !typeof(TValue).IsAssignableFrom(dictionaryValue.GetType()))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.SecurityTokenRequirementHasInvalidTypeForProperty, propertyName, dictionaryValue.GetType(), typeof(TValue))));
|
||||
}
|
||||
result = (TValue)dictionaryValue;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.IdentityModel.Selectors
|
||||
{
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IdentityModel.Configuration;
|
||||
using System.IdentityModel.Tokens;
|
||||
using System.Xml;
|
||||
|
||||
public abstract class SecurityTokenResolver : ICustomIdentityConfiguration
|
||||
{
|
||||
public SecurityToken ResolveToken(SecurityKeyIdentifier keyIdentifier)
|
||||
{
|
||||
if (keyIdentifier == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifier");
|
||||
}
|
||||
SecurityToken token;
|
||||
if (!this.TryResolveTokenCore(keyIdentifier, out token))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.GetString(SR.UnableToResolveTokenReference, keyIdentifier)));
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
public bool TryResolveToken(SecurityKeyIdentifier keyIdentifier, out SecurityToken token)
|
||||
{
|
||||
if (keyIdentifier == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifier");
|
||||
}
|
||||
return TryResolveTokenCore(keyIdentifier, out token);
|
||||
}
|
||||
|
||||
public SecurityToken ResolveToken(SecurityKeyIdentifierClause keyIdentifierClause)
|
||||
{
|
||||
if (keyIdentifierClause == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause");
|
||||
}
|
||||
SecurityToken token;
|
||||
if (!this.TryResolveTokenCore(keyIdentifierClause, out token))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.GetString(SR.UnableToResolveTokenReference, keyIdentifierClause)));
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
public bool TryResolveToken(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token)
|
||||
{
|
||||
if (keyIdentifierClause == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause");
|
||||
}
|
||||
return this.TryResolveTokenCore(keyIdentifierClause, out token);
|
||||
}
|
||||
|
||||
public SecurityKey ResolveSecurityKey(SecurityKeyIdentifierClause keyIdentifierClause)
|
||||
{
|
||||
if (keyIdentifierClause == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause");
|
||||
}
|
||||
SecurityKey key;
|
||||
if (!this.TryResolveSecurityKeyCore(keyIdentifierClause, out key))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.GetString(SR.UnableToResolveKeyReference, keyIdentifierClause)));
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
public bool TryResolveSecurityKey(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityKey key)
|
||||
{
|
||||
if (keyIdentifierClause == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause");
|
||||
}
|
||||
return this.TryResolveSecurityKeyCore(keyIdentifierClause, out key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load custom configuration from Xml
|
||||
/// </summary>
|
||||
/// <param name="nodelist">Custom configuration elements</param>
|
||||
public virtual void LoadCustomConfiguration(XmlNodeList nodelist)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException(SR.GetString(SR.ID0023, this.GetType().AssemblyQualifiedName)));
|
||||
}
|
||||
|
||||
// protected methods
|
||||
protected abstract bool TryResolveTokenCore(SecurityKeyIdentifier keyIdentifier, out SecurityToken token);
|
||||
protected abstract bool TryResolveTokenCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token);
|
||||
protected abstract bool TryResolveSecurityKeyCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityKey key);
|
||||
|
||||
|
||||
public static SecurityTokenResolver CreateDefaultSecurityTokenResolver(ReadOnlyCollection<SecurityToken> tokens, bool canMatchLocalId)
|
||||
{
|
||||
return new SimpleTokenResolver(tokens, canMatchLocalId);
|
||||
}
|
||||
|
||||
class SimpleTokenResolver : SecurityTokenResolver
|
||||
{
|
||||
ReadOnlyCollection<SecurityToken> tokens;
|
||||
bool canMatchLocalId;
|
||||
|
||||
public SimpleTokenResolver(ReadOnlyCollection<SecurityToken> tokens, bool canMatchLocalId)
|
||||
{
|
||||
if (tokens == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokens");
|
||||
|
||||
this.tokens = tokens;
|
||||
this.canMatchLocalId = canMatchLocalId;
|
||||
}
|
||||
|
||||
protected override bool TryResolveSecurityKeyCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityKey key)
|
||||
{
|
||||
if (keyIdentifierClause == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause");
|
||||
|
||||
key = null;
|
||||
for (int i = 0; i < this.tokens.Count; ++i)
|
||||
{
|
||||
SecurityKey securityKey = this.tokens[i].ResolveKeyIdentifierClause(keyIdentifierClause);
|
||||
if (securityKey != null)
|
||||
{
|
||||
key = securityKey;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (keyIdentifierClause is EncryptedKeyIdentifierClause)
|
||||
{
|
||||
EncryptedKeyIdentifierClause keyClause = (EncryptedKeyIdentifierClause)keyIdentifierClause;
|
||||
SecurityKeyIdentifier keyIdentifier = keyClause.EncryptingKeyIdentifier;
|
||||
if (keyIdentifier != null && keyIdentifier.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < keyIdentifier.Count; i++)
|
||||
{
|
||||
SecurityKey unwrappingSecurityKey = null;
|
||||
if (TryResolveSecurityKey(keyIdentifier[i], out unwrappingSecurityKey))
|
||||
{
|
||||
byte[] wrappedKey = keyClause.GetEncryptedKey();
|
||||
string wrappingAlgorithm = keyClause.EncryptionMethod;
|
||||
byte[] unwrappedKey = unwrappingSecurityKey.DecryptKey(wrappingAlgorithm, wrappedKey);
|
||||
key = new InMemorySymmetricSecurityKey(unwrappedKey, false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return key != null;
|
||||
}
|
||||
|
||||
protected override bool TryResolveTokenCore(SecurityKeyIdentifier keyIdentifier, out SecurityToken token)
|
||||
{
|
||||
if (keyIdentifier == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifier");
|
||||
|
||||
token = null;
|
||||
for (int i = 0; i < keyIdentifier.Count; ++i)
|
||||
{
|
||||
|
||||
SecurityToken securityToken = ResolveSecurityToken(keyIdentifier[i]);
|
||||
if (securityToken != null)
|
||||
{
|
||||
token = securityToken;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (token != null);
|
||||
}
|
||||
|
||||
protected override bool TryResolveTokenCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token)
|
||||
{
|
||||
if (keyIdentifierClause == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause");
|
||||
|
||||
token = null;
|
||||
|
||||
SecurityToken securityToken = ResolveSecurityToken(keyIdentifierClause);
|
||||
if (securityToken != null)
|
||||
token = securityToken;
|
||||
|
||||
return (token != null);
|
||||
}
|
||||
|
||||
SecurityToken ResolveSecurityToken(SecurityKeyIdentifierClause keyIdentifierClause)
|
||||
{
|
||||
if (keyIdentifierClause == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause");
|
||||
|
||||
if (!this.canMatchLocalId && keyIdentifierClause is LocalIdKeyIdentifierClause)
|
||||
return null;
|
||||
|
||||
for (int i = 0; i < this.tokens.Count; ++i)
|
||||
{
|
||||
if (this.tokens[i].MatchesKeyIdentifierClause(keyIdentifierClause))
|
||||
return this.tokens[i];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.IdentityModel.Selectors
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Tokens;
|
||||
using System.Xml;
|
||||
|
||||
/// <summary>
|
||||
/// SecurityTokenSerializer is responsible for writing and reading SecurityKeyIdentifiers, SecurityKeyIdentifierClauses and SecurityTokens.
|
||||
/// In order to read SecurityTokens the SecurityTokenSerializer may need to resolve token references using the SecurityTokenResolvers that get passed in.
|
||||
/// The SecurityTokenSerializer is stateless
|
||||
/// Exceptions: XmlException, SecurityTokenException, NotSupportedException, InvalidOperationException, ArgumentException
|
||||
/// </summary>
|
||||
public abstract class SecurityTokenSerializer
|
||||
{
|
||||
// public methods
|
||||
public bool CanReadToken(XmlReader reader)
|
||||
{
|
||||
if (reader == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
|
||||
}
|
||||
return CanReadTokenCore(reader);
|
||||
}
|
||||
|
||||
public bool CanWriteToken(SecurityToken token)
|
||||
{
|
||||
if (token == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token");
|
||||
}
|
||||
return CanWriteTokenCore(token);
|
||||
}
|
||||
|
||||
public bool CanReadKeyIdentifier(XmlReader reader)
|
||||
{
|
||||
if (reader == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
|
||||
}
|
||||
return CanReadKeyIdentifierCore(reader);
|
||||
}
|
||||
|
||||
public bool CanWriteKeyIdentifier(SecurityKeyIdentifier keyIdentifier)
|
||||
{
|
||||
if (keyIdentifier == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifier");
|
||||
}
|
||||
return CanWriteKeyIdentifierCore(keyIdentifier);
|
||||
}
|
||||
|
||||
public bool CanReadKeyIdentifierClause(XmlReader reader)
|
||||
{
|
||||
if (reader == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
|
||||
}
|
||||
return CanReadKeyIdentifierClauseCore(reader);
|
||||
}
|
||||
|
||||
public bool CanWriteKeyIdentifierClause(SecurityKeyIdentifierClause keyIdentifierClause)
|
||||
{
|
||||
if (keyIdentifierClause == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause");
|
||||
}
|
||||
return CanWriteKeyIdentifierClauseCore(keyIdentifierClause);
|
||||
}
|
||||
|
||||
|
||||
public SecurityToken ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver)
|
||||
{
|
||||
if (reader == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
|
||||
}
|
||||
return ReadTokenCore(reader, tokenResolver);
|
||||
}
|
||||
|
||||
public void WriteToken(XmlWriter writer, SecurityToken token)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
|
||||
}
|
||||
if (token == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token");
|
||||
}
|
||||
WriteTokenCore(writer, token);
|
||||
}
|
||||
|
||||
public SecurityKeyIdentifier ReadKeyIdentifier(XmlReader reader)
|
||||
{
|
||||
if (reader == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
|
||||
}
|
||||
return ReadKeyIdentifierCore(reader);
|
||||
}
|
||||
|
||||
public void WriteKeyIdentifier(XmlWriter writer, SecurityKeyIdentifier keyIdentifier)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
|
||||
}
|
||||
if (keyIdentifier == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifier");
|
||||
}
|
||||
WriteKeyIdentifierCore(writer, keyIdentifier);
|
||||
}
|
||||
|
||||
public SecurityKeyIdentifierClause ReadKeyIdentifierClause(XmlReader reader)
|
||||
{
|
||||
if (reader == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
|
||||
}
|
||||
return ReadKeyIdentifierClauseCore(reader);
|
||||
}
|
||||
|
||||
public void WriteKeyIdentifierClause(XmlWriter writer, SecurityKeyIdentifierClause keyIdentifierClause)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
|
||||
}
|
||||
if (keyIdentifierClause == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause");
|
||||
}
|
||||
WriteKeyIdentifierClauseCore(writer, keyIdentifierClause);
|
||||
}
|
||||
|
||||
|
||||
// protected abstract methods
|
||||
protected abstract bool CanReadTokenCore(XmlReader reader);
|
||||
protected abstract bool CanWriteTokenCore(SecurityToken token);
|
||||
protected abstract bool CanReadKeyIdentifierCore(XmlReader reader);
|
||||
protected abstract bool CanWriteKeyIdentifierCore(SecurityKeyIdentifier keyIdentifier);
|
||||
protected abstract bool CanReadKeyIdentifierClauseCore(XmlReader reader);
|
||||
protected abstract bool CanWriteKeyIdentifierClauseCore(SecurityKeyIdentifierClause keyIdentifierClause);
|
||||
|
||||
protected abstract SecurityToken ReadTokenCore(XmlReader reader, SecurityTokenResolver tokenResolver);
|
||||
protected abstract void WriteTokenCore(XmlWriter writer, SecurityToken token);
|
||||
protected abstract SecurityKeyIdentifier ReadKeyIdentifierCore(XmlReader reader);
|
||||
protected abstract void WriteKeyIdentifierCore(XmlWriter writer, SecurityKeyIdentifier keyIdentifier);
|
||||
protected abstract SecurityKeyIdentifierClause ReadKeyIdentifierClauseCore(XmlReader reader);
|
||||
protected abstract void WriteKeyIdentifierClauseCore(XmlWriter writer, SecurityKeyIdentifierClause keyIdentifierClause);
|
||||
|
||||
internal abstract class KeyIdentifierClauseEntry
|
||||
{
|
||||
|
||||
protected abstract XmlDictionaryString LocalName { get; }
|
||||
protected abstract XmlDictionaryString NamespaceUri { get; }
|
||||
|
||||
public virtual bool CanReadKeyIdentifierClauseCore(XmlDictionaryReader reader)
|
||||
{
|
||||
return reader.IsStartElement(this.LocalName, this.NamespaceUri);
|
||||
}
|
||||
|
||||
public abstract SecurityKeyIdentifierClause ReadKeyIdentifierClauseCore(XmlDictionaryReader reader);
|
||||
|
||||
public abstract bool SupportsCore(SecurityKeyIdentifierClause keyIdentifierClause);
|
||||
|
||||
public abstract void WriteKeyIdentifierClauseCore(XmlDictionaryWriter writer, SecurityKeyIdentifierClause keyIdentifierClause);
|
||||
}
|
||||
|
||||
internal abstract class StrEntry
|
||||
{
|
||||
public abstract string GetTokenTypeUri();
|
||||
public abstract Type GetTokenType(SecurityKeyIdentifierClause clause);
|
||||
public abstract bool CanReadClause(XmlDictionaryReader reader, string tokenType);
|
||||
public abstract SecurityKeyIdentifierClause ReadClause(XmlDictionaryReader reader, byte[] derivationNonce, int derivationLength, string tokenType);
|
||||
public abstract bool SupportsCore(SecurityKeyIdentifierClause clause);
|
||||
public abstract void WriteContent(XmlDictionaryWriter writer, SecurityKeyIdentifierClause clause);
|
||||
}
|
||||
|
||||
internal abstract class SerializerEntries
|
||||
{
|
||||
public virtual void PopulateTokenEntries(IList<TokenEntry> tokenEntries) { }
|
||||
public virtual void PopulateKeyIdentifierEntries(IList<KeyIdentifierEntry> keyIdentifierEntries) { }
|
||||
public virtual void PopulateKeyIdentifierClauseEntries(IList<KeyIdentifierClauseEntry> keyIdentifierClauseEntries) { }
|
||||
public virtual void PopulateStrEntries(IList<StrEntry> strEntries) { }
|
||||
}
|
||||
|
||||
internal abstract class KeyIdentifierEntry
|
||||
{
|
||||
protected abstract XmlDictionaryString LocalName { get; }
|
||||
protected abstract XmlDictionaryString NamespaceUri { get; }
|
||||
|
||||
public virtual bool CanReadKeyIdentifierCore(XmlDictionaryReader reader)
|
||||
{
|
||||
return reader.IsStartElement(this.LocalName, this.NamespaceUri);
|
||||
}
|
||||
|
||||
public abstract SecurityKeyIdentifier ReadKeyIdentifierCore(XmlDictionaryReader reader);
|
||||
|
||||
public abstract bool SupportsCore(SecurityKeyIdentifier keyIdentifier);
|
||||
|
||||
public abstract void WriteKeyIdentifierCore(XmlDictionaryWriter writer, SecurityKeyIdentifier keyIdentifier);
|
||||
}
|
||||
|
||||
internal abstract class TokenEntry
|
||||
{
|
||||
Type[] tokenTypes = null;
|
||||
|
||||
protected abstract XmlDictionaryString LocalName { get; }
|
||||
protected abstract XmlDictionaryString NamespaceUri { get; }
|
||||
public Type TokenType { get { return GetTokenTypes()[0]; } }
|
||||
public abstract string TokenTypeUri { get; }
|
||||
protected abstract string ValueTypeUri { get; }
|
||||
|
||||
public bool SupportsCore(Type tokenType)
|
||||
{
|
||||
Type[] tokenTypes = GetTokenTypes();
|
||||
for (int i = 0; i < tokenTypes.Length; ++i)
|
||||
{
|
||||
if (tokenTypes[i].IsAssignableFrom(tokenType))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected abstract Type[] GetTokenTypesCore();
|
||||
|
||||
public Type[] GetTokenTypes()
|
||||
{
|
||||
if (this.tokenTypes == null)
|
||||
this.tokenTypes = GetTokenTypesCore();
|
||||
return this.tokenTypes;
|
||||
}
|
||||
|
||||
public virtual bool SupportsTokenTypeUri(string tokenTypeUri)
|
||||
{
|
||||
return (this.TokenTypeUri == tokenTypeUri);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.IdentityModel.Selectors
|
||||
{
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
public abstract class SecurityTokenVersion
|
||||
{
|
||||
public abstract ReadOnlyCollection<string> GetSecuritySpecifications();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.IdentityModel.Selectors
|
||||
{
|
||||
using System.IdentityModel.Tokens;
|
||||
using System.Web.Security;
|
||||
|
||||
public abstract class UserNamePasswordValidator
|
||||
{
|
||||
static UserNamePasswordValidator none;
|
||||
|
||||
public static UserNamePasswordValidator None
|
||||
{
|
||||
get
|
||||
{
|
||||
if (none == null)
|
||||
none = new NoneUserNamePasswordValidator();
|
||||
return none;
|
||||
}
|
||||
}
|
||||
|
||||
public static UserNamePasswordValidator CreateMembershipProviderValidator(MembershipProvider provider)
|
||||
{
|
||||
if (provider == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("provider");
|
||||
return new MembershipProviderValidator(provider);
|
||||
}
|
||||
|
||||
public abstract void Validate(string userName, string password);
|
||||
|
||||
class NoneUserNamePasswordValidator : UserNamePasswordValidator
|
||||
{
|
||||
public override void Validate(string userName, string password)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class MembershipProviderValidator : UserNamePasswordValidator
|
||||
{
|
||||
MembershipProvider provider;
|
||||
|
||||
public MembershipProviderValidator(MembershipProvider provider)
|
||||
{
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
public override void Validate(string userName, string password)
|
||||
{
|
||||
if (!this.provider.ValidateUser(userName, password))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(
|
||||
SR.GetString(SR.UserNameAuthenticationFailed, this.provider.GetType().Name)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.IdentityModel.Selectors
|
||||
{
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IdentityModel.Policy;
|
||||
using System.IdentityModel.Tokens;
|
||||
|
||||
public abstract class UserNameSecurityTokenAuthenticator : SecurityTokenAuthenticator
|
||||
{
|
||||
protected UserNameSecurityTokenAuthenticator()
|
||||
{
|
||||
}
|
||||
|
||||
protected override bool CanValidateTokenCore(SecurityToken token)
|
||||
{
|
||||
return token is UserNameSecurityToken;
|
||||
}
|
||||
|
||||
protected override ReadOnlyCollection<IAuthorizationPolicy> ValidateTokenCore(SecurityToken token)
|
||||
{
|
||||
UserNameSecurityToken userNameToken = (UserNameSecurityToken) token;
|
||||
return ValidateUserNamePasswordCore(userNameToken.UserName, userNameToken.Password);
|
||||
}
|
||||
|
||||
protected abstract ReadOnlyCollection<IAuthorizationPolicy> ValidateUserNamePasswordCore(string userName, string password);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace System.IdentityModel.Selectors
|
||||
{
|
||||
using System.IdentityModel.Tokens;
|
||||
|
||||
public class UserNameSecurityTokenProvider : SecurityTokenProvider
|
||||
{
|
||||
UserNameSecurityToken userNameToken;
|
||||
|
||||
public UserNameSecurityTokenProvider(string userName, string password)
|
||||
{
|
||||
if (userName == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("userName");
|
||||
}
|
||||
|
||||
this.userNameToken = new UserNameSecurityToken(userName, password);
|
||||
}
|
||||
|
||||
protected override SecurityToken GetTokenCore(TimeSpan timeout)
|
||||
{
|
||||
return this.userNameToken;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.IdentityModel.Selectors
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IdentityModel.Claims;
|
||||
using System.IdentityModel.Policy;
|
||||
using System.IdentityModel.Tokens;
|
||||
|
||||
public class WindowsSecurityTokenAuthenticator : SecurityTokenAuthenticator
|
||||
{
|
||||
bool includeWindowsGroups;
|
||||
|
||||
public WindowsSecurityTokenAuthenticator()
|
||||
: this(WindowsClaimSet.DefaultIncludeWindowsGroups)
|
||||
{
|
||||
}
|
||||
|
||||
public WindowsSecurityTokenAuthenticator(bool includeWindowsGroups)
|
||||
{
|
||||
this.includeWindowsGroups = includeWindowsGroups;
|
||||
}
|
||||
|
||||
protected override bool CanValidateTokenCore(SecurityToken token)
|
||||
{
|
||||
return token is WindowsSecurityToken;
|
||||
}
|
||||
|
||||
protected override ReadOnlyCollection<IAuthorizationPolicy> ValidateTokenCore(SecurityToken token)
|
||||
{
|
||||
WindowsSecurityToken windowsToken = (WindowsSecurityToken)token;
|
||||
WindowsClaimSet claimSet = new WindowsClaimSet(windowsToken.WindowsIdentity, windowsToken.AuthenticationType, this.includeWindowsGroups, windowsToken.ValidTo);
|
||||
return SecurityUtils.CreateAuthorizationPolicies(claimSet, windowsToken.ValidTo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.IdentityModel.Selectors
|
||||
{
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.IdentityModel.Claims;
|
||||
using System.IdentityModel.Policy;
|
||||
using System.IdentityModel.Tokens;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Security.Principal;
|
||||
|
||||
public class WindowsUserNameSecurityTokenAuthenticator : UserNameSecurityTokenAuthenticator
|
||||
{
|
||||
bool includeWindowsGroups;
|
||||
|
||||
public WindowsUserNameSecurityTokenAuthenticator()
|
||||
: this(WindowsClaimSet.DefaultIncludeWindowsGroups)
|
||||
{
|
||||
}
|
||||
|
||||
public WindowsUserNameSecurityTokenAuthenticator(bool includeWindowsGroups)
|
||||
{
|
||||
this.includeWindowsGroups = includeWindowsGroups;
|
||||
}
|
||||
|
||||
protected override ReadOnlyCollection<IAuthorizationPolicy> ValidateUserNamePasswordCore(string userName, string password)
|
||||
{
|
||||
string domain = null;
|
||||
string[] strings = userName.Split('\\');
|
||||
if (strings.Length != 1)
|
||||
{
|
||||
if (strings.Length != 2 || string.IsNullOrEmpty(strings[0]))
|
||||
{
|
||||
// Only support one slash and domain cannot be empty (consistent with windowslogon).
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.IncorrectUserNameFormat));
|
||||
}
|
||||
|
||||
// This is the downlevel case - domain\userName
|
||||
userName = strings[1];
|
||||
domain = strings[0];
|
||||
}
|
||||
|
||||
const uint LOGON32_PROVIDER_DEFAULT = 0;
|
||||
const uint LOGON32_LOGON_NETWORK_CLEARTEXT = 8;
|
||||
SafeCloseHandle tokenHandle = null;
|
||||
try
|
||||
{
|
||||
if (!NativeMethods.LogonUser(userName, domain, password, LOGON32_LOGON_NETWORK_CLEARTEXT, LOGON32_PROVIDER_DEFAULT, out tokenHandle))
|
||||
{
|
||||
int error = Marshal.GetLastWin32Error();
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(SR.GetString(SR.FailLogonUser, userName), new Win32Exception(error)));
|
||||
}
|
||||
|
||||
WindowsIdentity windowsIdentity = new WindowsIdentity(tokenHandle.DangerousGetHandle(), SecurityUtils.AuthTypeBasic);
|
||||
WindowsClaimSet claimSet = new WindowsClaimSet(windowsIdentity, SecurityUtils.AuthTypeBasic, this.includeWindowsGroups, false);
|
||||
return SecurityUtils.CreateAuthorizationPolicies(claimSet, claimSet.ExpirationTime);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (tokenHandle != null)
|
||||
tokenHandle.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,381 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.IdentityModel.Selectors
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Tokens;
|
||||
using System.Net;
|
||||
using System.Runtime;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Permissions;
|
||||
using System.Text;
|
||||
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
|
||||
|
||||
// Most of codes are copied from \ndp\fx\src\security\system\security\cryptography\x509\X509Chain.cs
|
||||
class X509CertificateChain
|
||||
{
|
||||
public const uint DefaultChainPolicyOID = CAPI.CERT_CHAIN_POLICY_BASE;
|
||||
bool useMachineContext;
|
||||
X509ChainPolicy chainPolicy;
|
||||
uint chainPolicyOID = X509CertificateChain.DefaultChainPolicyOID;
|
||||
|
||||
public X509CertificateChain()
|
||||
: this(false)
|
||||
{
|
||||
}
|
||||
|
||||
public X509CertificateChain(bool useMachineContext)
|
||||
{
|
||||
this.useMachineContext = useMachineContext;
|
||||
}
|
||||
|
||||
public X509CertificateChain(bool useMachineContext, uint chainPolicyOID)
|
||||
{
|
||||
this.useMachineContext = useMachineContext;
|
||||
// One of the condition to pass NT_AUTH is the issuer of the cert must be trusted by NT auth.
|
||||
// Simply add to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\EnterpriseCertificates\NTAuth\Certificates
|
||||
this.chainPolicyOID = chainPolicyOID;
|
||||
}
|
||||
|
||||
public X509ChainPolicy ChainPolicy
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.chainPolicy == null)
|
||||
{
|
||||
this.chainPolicy = new X509ChainPolicy();
|
||||
}
|
||||
return this.chainPolicy;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.chainPolicy = value;
|
||||
}
|
||||
}
|
||||
|
||||
public X509ChainStatus[] ChainStatus
|
||||
{
|
||||
#pragma warning suppress 56503
|
||||
get { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); }
|
||||
}
|
||||
|
||||
// There are 2 steps in chain validation.
|
||||
// 1) BuildChain by calling CAPI.CertGetCertificateChain. The result is
|
||||
// the chain context containing the chain and status.
|
||||
// 2) VerifyChain by calling CAPI.CertVerifyCertificateChainPolicy.
|
||||
// Refer to MB50916, Since Vista out-of-the-box will trust the chain with PeerTrust,
|
||||
// we include the flag to ignore PeerTrust for CAPI.CertVerifyCertificateChainPolicy.
|
||||
[Fx.Tag.SecurityNote(Critical = "Builds chain trust through interop calls.",
|
||||
Safe = "Proteced by StorePermission and WebPermission demands.")]
|
||||
[SecuritySafeCritical]
|
||||
[StorePermission(SecurityAction.Demand, CreateStore = true, OpenStore = true, EnumerateCertificates = true)]
|
||||
public bool Build(X509Certificate2 certificate)
|
||||
{
|
||||
if (certificate == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("certificate");
|
||||
if (certificate.Handle == IntPtr.Zero)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("certificate", SR.GetString(SR.ArgumentInvalidCertificate));
|
||||
|
||||
SafeCertChainHandle safeCertChainHandle = SafeCertChainHandle.InvalidHandle;
|
||||
X509ChainPolicy chainPolicy = this.ChainPolicy;
|
||||
chainPolicy.VerificationTime = DateTime.Now;
|
||||
if (chainPolicy.RevocationMode == X509RevocationMode.Online)
|
||||
{
|
||||
if (certificate.Extensions[CAPI.szOID_CRL_DIST_POINTS] != null ||
|
||||
certificate.Extensions[CAPI.szOID_AUTHORITY_INFO_ACCESS] != null)
|
||||
{
|
||||
// If there is a CDP or AIA extension, we demand unrestricted network access and store add permission
|
||||
// since CAPI can download certificates into the CA store from the network.
|
||||
PermissionSet ps = new PermissionSet(PermissionState.None);
|
||||
ps.AddPermission(new WebPermission(PermissionState.Unrestricted));
|
||||
ps.AddPermission(new StorePermission(StorePermissionFlags.AddToStore));
|
||||
ps.Demand();
|
||||
}
|
||||
}
|
||||
|
||||
BuildChain(this.useMachineContext ? new IntPtr(CAPI.HCCE_LOCAL_MACHINE) : new IntPtr(CAPI.HCCE_CURRENT_USER),
|
||||
certificate.Handle,
|
||||
chainPolicy.ExtraStore,
|
||||
chainPolicy.ApplicationPolicy,
|
||||
chainPolicy.CertificatePolicy,
|
||||
chainPolicy.RevocationMode,
|
||||
chainPolicy.RevocationFlag,
|
||||
chainPolicy.VerificationTime,
|
||||
chainPolicy.UrlRetrievalTimeout,
|
||||
out safeCertChainHandle);
|
||||
|
||||
// Verify the chain using the specified policy.
|
||||
CAPI.CERT_CHAIN_POLICY_PARA PolicyPara = new CAPI.CERT_CHAIN_POLICY_PARA(Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_POLICY_PARA)));
|
||||
CAPI.CERT_CHAIN_POLICY_STATUS PolicyStatus = new CAPI.CERT_CHAIN_POLICY_STATUS(Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_POLICY_STATUS)));
|
||||
|
||||
// Ignore peertrust. Peer trust caused the chain to succeed out-of-the-box in Vista.
|
||||
// This new flag is only available in Vista.
|
||||
PolicyPara.dwFlags = (uint)chainPolicy.VerificationFlags | CAPI.CERT_CHAIN_POLICY_IGNORE_PEER_TRUST_FLAG;
|
||||
|
||||
if (!CAPI.CertVerifyCertificateChainPolicy(new IntPtr(this.chainPolicyOID),
|
||||
safeCertChainHandle,
|
||||
ref PolicyPara,
|
||||
ref PolicyStatus))
|
||||
{
|
||||
int error = Marshal.GetLastWin32Error();
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(error));
|
||||
}
|
||||
|
||||
if (PolicyStatus.dwError != CAPI.S_OK)
|
||||
{
|
||||
int error = (int)PolicyStatus.dwError;
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(SR.GetString(SR.X509ChainBuildFail,
|
||||
SecurityUtils.GetCertificateId(certificate), new CryptographicException(error).Message)));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[SecurityCritical]
|
||||
static unsafe void BuildChain(IntPtr hChainEngine,
|
||||
IntPtr pCertContext,
|
||||
X509Certificate2Collection extraStore,
|
||||
OidCollection applicationPolicy,
|
||||
OidCollection certificatePolicy,
|
||||
X509RevocationMode revocationMode,
|
||||
X509RevocationFlag revocationFlag,
|
||||
DateTime verificationTime,
|
||||
TimeSpan timeout,
|
||||
out SafeCertChainHandle ppChainContext)
|
||||
{
|
||||
SafeCertStoreHandle hCertStore = ExportToMemoryStore(extraStore, pCertContext);
|
||||
|
||||
CAPI.CERT_CHAIN_PARA ChainPara = new CAPI.CERT_CHAIN_PARA();
|
||||
ChainPara.cbSize = (uint)Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_PARA));
|
||||
|
||||
// Application policy
|
||||
SafeHGlobalHandle applicationPolicyHandle = SafeHGlobalHandle.InvalidHandle;
|
||||
SafeHGlobalHandle certificatePolicyHandle = SafeHGlobalHandle.InvalidHandle;
|
||||
try
|
||||
{
|
||||
if (applicationPolicy != null && applicationPolicy.Count > 0)
|
||||
{
|
||||
ChainPara.RequestedUsage.dwType = CAPI.USAGE_MATCH_TYPE_AND;
|
||||
ChainPara.RequestedUsage.Usage.cUsageIdentifier = (uint)applicationPolicy.Count;
|
||||
applicationPolicyHandle = CopyOidsToUnmanagedMemory(applicationPolicy);
|
||||
ChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = applicationPolicyHandle.DangerousGetHandle();
|
||||
}
|
||||
|
||||
// Certificate policy
|
||||
if (certificatePolicy != null && certificatePolicy.Count > 0)
|
||||
{
|
||||
ChainPara.RequestedIssuancePolicy.dwType = CAPI.USAGE_MATCH_TYPE_AND;
|
||||
ChainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier = (uint)certificatePolicy.Count;
|
||||
certificatePolicyHandle = CopyOidsToUnmanagedMemory(certificatePolicy);
|
||||
ChainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = certificatePolicyHandle.DangerousGetHandle();
|
||||
}
|
||||
|
||||
ChainPara.dwUrlRetrievalTimeout = (uint)timeout.Milliseconds;
|
||||
|
||||
FILETIME ft = new FILETIME();
|
||||
*((long*)&ft) = verificationTime.ToFileTime();
|
||||
|
||||
uint flags = MapRevocationFlags(revocationMode, revocationFlag);
|
||||
|
||||
// Build the chain.
|
||||
if (!CAPI.CertGetCertificateChain(hChainEngine,
|
||||
pCertContext,
|
||||
ref ft,
|
||||
hCertStore,
|
||||
ref ChainPara,
|
||||
flags,
|
||||
IntPtr.Zero,
|
||||
out ppChainContext))
|
||||
{
|
||||
int error = Marshal.GetLastWin32Error();
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(error));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (applicationPolicyHandle != null)
|
||||
applicationPolicyHandle.Dispose();
|
||||
if (certificatePolicyHandle != null)
|
||||
certificatePolicyHandle.Dispose();
|
||||
hCertStore.Close();
|
||||
}
|
||||
}
|
||||
|
||||
[Fx.Tag.SecurityNote(Critical = "Uses unmanaged code to create an in memory store which links to the original cert store."
|
||||
+ "User must protect the store handle.")]
|
||||
[SecurityCritical]
|
||||
static SafeCertStoreHandle ExportToMemoryStore(X509Certificate2Collection collection, IntPtr pCertContext)
|
||||
{
|
||||
CAPI.CERT_CONTEXT certContext = (CAPI.CERT_CONTEXT)Marshal.PtrToStructure(pCertContext, typeof(CAPI.CERT_CONTEXT));
|
||||
|
||||
// No extra store nor intermediate certificates
|
||||
if ((collection == null || collection.Count <= 0) && certContext.hCertStore == IntPtr.Zero)
|
||||
{
|
||||
return SafeCertStoreHandle.InvalidHandle;
|
||||
}
|
||||
|
||||
// we always want to use CERT_STORE_ENUM_ARCHIVED_FLAG since we want to preserve the collection in this operation.
|
||||
// By default, Archived certificates will not be included.
|
||||
SafeCertStoreHandle certStoreHandle = CAPI.CertOpenStore(
|
||||
new IntPtr(CAPI.CERT_STORE_PROV_MEMORY),
|
||||
CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
|
||||
IntPtr.Zero,
|
||||
CAPI.CERT_STORE_ENUM_ARCHIVED_FLAG | CAPI.CERT_STORE_CREATE_NEW_FLAG,
|
||||
null);
|
||||
|
||||
if (certStoreHandle == null || certStoreHandle.IsInvalid)
|
||||
{
|
||||
int error = Marshal.GetLastWin32Error();
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(error));
|
||||
}
|
||||
|
||||
//
|
||||
// We use CertAddCertificateLinkToStore to keep a link to the original store, so any property changes get
|
||||
// applied to the original store. This has a limit of 99 links per cert context however.
|
||||
//
|
||||
|
||||
// Add extra store
|
||||
if (collection != null && collection.Count > 0)
|
||||
{
|
||||
foreach (X509Certificate2 x509 in collection)
|
||||
{
|
||||
if (!CAPI.CertAddCertificateLinkToStore(certStoreHandle,
|
||||
x509.Handle,
|
||||
CAPI.CERT_STORE_ADD_ALWAYS,
|
||||
SafeCertContextHandle.InvalidHandle))
|
||||
{
|
||||
int error = Marshal.GetLastWin32Error();
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(error));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add intermediates
|
||||
// The hCertStore needs to be acquired from an X509Certificate2 object
|
||||
// constructed using a fresh cert context handle. If we simply refer to the hCertStore
|
||||
// property of the certContext local variable directly, there is a risk that we are accessing
|
||||
// a closed store. This is because if the X509Certificate2(rawdata) constructor closes the store handle (hCertStore).
|
||||
// There is no way to know which constructor was used at this point.
|
||||
//
|
||||
using ( SafeCertContextHandle safeCertContext
|
||||
= CAPI.CertCreateCertificateContext( certContext.dwCertEncodingType,
|
||||
certContext.pbCertEncoded,
|
||||
certContext.cbCertEncoded ) )
|
||||
{
|
||||
//
|
||||
// Create an X509Certificate2 using the new cert context that dup's the provided certificate.
|
||||
//
|
||||
X509Certificate2 intermediatesCert = new X509Certificate2( safeCertContext.DangerousGetHandle() );
|
||||
|
||||
//
|
||||
// Dereference the handle to this intermediate cert and use it to access the handle
|
||||
// of this certificate's cert store. Then, call CAPI.CertAddCertificateLinkToStore
|
||||
// on each cert in this store by wrapping this cert store handle with an X509Store
|
||||
// object.
|
||||
//
|
||||
CAPI.CERT_CONTEXT intermediatesCertContext = (CAPI.CERT_CONTEXT) Marshal.PtrToStructure( intermediatesCert.Handle, typeof( CAPI.CERT_CONTEXT ) );
|
||||
if (intermediatesCertContext.hCertStore != IntPtr.Zero)
|
||||
{
|
||||
X509Certificate2Collection intermediates = null;
|
||||
X509Store store = new X509Store(intermediatesCertContext.hCertStore);
|
||||
|
||||
try
|
||||
{
|
||||
intermediates = store.Certificates;
|
||||
foreach (X509Certificate2 x509 in intermediates)
|
||||
{
|
||||
if (!CAPI.CertAddCertificateLinkToStore(certStoreHandle,
|
||||
x509.Handle,
|
||||
CAPI.CERT_STORE_ADD_ALWAYS,
|
||||
SafeCertContextHandle.InvalidHandle))
|
||||
{
|
||||
int error = Marshal.GetLastWin32Error();
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(error));
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
SecurityUtils.ResetAllCertificates(intermediates);
|
||||
store.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return certStoreHandle;
|
||||
}
|
||||
|
||||
[Fx.Tag.SecurityNote(Critical = "Copies the oid collection to unamanged memory."
|
||||
+ "User must protect the handle.")]
|
||||
[SecurityCritical]
|
||||
static SafeHGlobalHandle CopyOidsToUnmanagedMemory(OidCollection oids)
|
||||
{
|
||||
SafeHGlobalHandle safeAllocHandle = SafeHGlobalHandle.InvalidHandle;
|
||||
if (oids == null || oids.Count == 0)
|
||||
return safeAllocHandle;
|
||||
|
||||
// Copy the oid strings to a local list to prevent a security race condition where
|
||||
// the OidCollection or individual oids can be modified by another thread and
|
||||
// potentially cause a buffer overflow
|
||||
List<string> oidStrs = new List<string>();
|
||||
foreach (Oid oid in oids) {
|
||||
oidStrs.Add(oid.Value);
|
||||
}
|
||||
|
||||
IntPtr pOid = IntPtr.Zero;
|
||||
IntPtr pNullTerminator = IntPtr.Zero;
|
||||
// Needs to be checked to avoid having large sets of oids overflow the sizes and allow
|
||||
// a potential buffer overflow
|
||||
checked {
|
||||
int ptrSize = oidStrs.Count * Marshal.SizeOf(typeof(IntPtr));
|
||||
int oidSize = 0;
|
||||
foreach (string oidStr in oidStrs) {
|
||||
oidSize += (oidStr.Length + 1);
|
||||
}
|
||||
safeAllocHandle = SafeHGlobalHandle.AllocHGlobal(ptrSize + oidSize);
|
||||
pOid = new IntPtr((long)safeAllocHandle.DangerousGetHandle() + ptrSize);
|
||||
}
|
||||
|
||||
for (int index = 0; index < oidStrs.Count; index++) {
|
||||
Marshal.WriteIntPtr(new IntPtr((long) safeAllocHandle.DangerousGetHandle() + index * Marshal.SizeOf(typeof(IntPtr))), pOid);
|
||||
byte[] ansiOid = Encoding.ASCII.GetBytes(oidStrs[index]);
|
||||
|
||||
if (ansiOid.Length != oidStrs[index].Length) {
|
||||
// We assumed single byte characters, fail if this is not the case. The exception is not ideal.
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.CollectionWasModified)));
|
||||
}
|
||||
|
||||
Marshal.Copy(ansiOid, 0, pOid, ansiOid.Length);
|
||||
pNullTerminator = new IntPtr((long) pOid + ansiOid.Length);
|
||||
Marshal.WriteByte(pNullTerminator, 0);
|
||||
|
||||
pOid = new IntPtr((long)pOid + oidStrs[index].Length + 1);
|
||||
}
|
||||
return safeAllocHandle;
|
||||
}
|
||||
|
||||
static uint MapRevocationFlags(X509RevocationMode revocationMode, X509RevocationFlag revocationFlag)
|
||||
{
|
||||
uint dwFlags = 0;
|
||||
if (revocationMode == X509RevocationMode.NoCheck)
|
||||
return dwFlags;
|
||||
|
||||
if (revocationMode == X509RevocationMode.Offline)
|
||||
dwFlags |= CAPI.CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY;
|
||||
|
||||
if (revocationFlag == X509RevocationFlag.EndCertificateOnly)
|
||||
dwFlags |= CAPI.CERT_CHAIN_REVOCATION_CHECK_END_CERT;
|
||||
else if (revocationFlag == X509RevocationFlag.EntireChain)
|
||||
dwFlags |= CAPI.CERT_CHAIN_REVOCATION_CHECK_CHAIN;
|
||||
else
|
||||
dwFlags |= CAPI.CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT;
|
||||
|
||||
return dwFlags;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user