e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
143 lines
6.1 KiB
C#
143 lines
6.1 KiB
C#
//-----------------------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
namespace System.ServiceModel
|
|
{
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.IdentityModel.Policy;
|
|
using System.ServiceModel.Channels;
|
|
using System.Collections;
|
|
using System.ServiceModel.Security.Tokens;
|
|
using System.ServiceModel.Security;
|
|
|
|
public class ServiceAuthenticationManager
|
|
{
|
|
public virtual ReadOnlyCollection<IAuthorizationPolicy> Authenticate(ReadOnlyCollection<IAuthorizationPolicy> authPolicy, Uri listenUri, ref Message message)
|
|
{
|
|
return authPolicy;
|
|
}
|
|
}
|
|
|
|
internal class SCTServiceAuthenticationManagerWrapper : ServiceAuthenticationManager
|
|
{
|
|
ServiceAuthenticationManager wrappedAuthenticationManager;
|
|
|
|
internal SCTServiceAuthenticationManagerWrapper(ServiceAuthenticationManager wrappedServiceAuthManager)
|
|
{
|
|
if (wrappedServiceAuthManager == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("wrappedServiceAuthManager");
|
|
}
|
|
|
|
this.wrappedAuthenticationManager = wrappedServiceAuthManager;
|
|
}
|
|
|
|
public override ReadOnlyCollection<IAuthorizationPolicy> Authenticate(ReadOnlyCollection<IAuthorizationPolicy> authPolicy, Uri listenUri, ref Message message)
|
|
{
|
|
if ((message != null) &&
|
|
(message.Properties != null) &&
|
|
(message.Properties.Security != null) &&
|
|
(message.Properties.Security.TransportToken != null) &&
|
|
(message.Properties.Security.ServiceSecurityContext != null) &&
|
|
(message.Properties.Security.ServiceSecurityContext.AuthorizationPolicies != null))
|
|
{
|
|
List<IAuthorizationPolicy> authPolicies = new List<IAuthorizationPolicy>(message.Properties.Security.ServiceSecurityContext.AuthorizationPolicies);
|
|
foreach (IAuthorizationPolicy policy in message.Properties.Security.TransportToken.SecurityTokenPolicies)
|
|
{
|
|
authPolicies.Remove(policy);
|
|
}
|
|
authPolicy = authPolicies.AsReadOnly();
|
|
}
|
|
|
|
return this.wrappedAuthenticationManager.Authenticate(authPolicy, listenUri, ref message);
|
|
}
|
|
}
|
|
|
|
internal class ServiceAuthenticationManagerWrapper : ServiceAuthenticationManager
|
|
{
|
|
ServiceAuthenticationManager wrappedAuthenticationManager;
|
|
string[] filteredActionUriCollection;
|
|
|
|
internal ServiceAuthenticationManagerWrapper(ServiceAuthenticationManager wrappedServiceAuthManager, string[] actionUriFilter)
|
|
{
|
|
if (wrappedServiceAuthManager == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("wrappedServiceAuthManager");
|
|
}
|
|
|
|
if ((actionUriFilter != null) && (actionUriFilter.Length > 0))
|
|
{
|
|
this.filteredActionUriCollection = new string[actionUriFilter.Length];
|
|
for (int i = 0; i < actionUriFilter.Length; ++i)
|
|
{
|
|
this.filteredActionUriCollection[i] = actionUriFilter[i];
|
|
}
|
|
}
|
|
|
|
this.wrappedAuthenticationManager = wrappedServiceAuthManager;
|
|
}
|
|
|
|
public override ReadOnlyCollection<IAuthorizationPolicy> Authenticate(ReadOnlyCollection<IAuthorizationPolicy> authPolicy, Uri listenUri, ref Message message)
|
|
{
|
|
if (CanSkipAuthentication(message))
|
|
{
|
|
return authPolicy;
|
|
}
|
|
|
|
if (this.filteredActionUriCollection != null)
|
|
{
|
|
for (int i = 0; i < this.filteredActionUriCollection.Length; ++i)
|
|
{
|
|
if ((message != null) &&
|
|
(message.Headers != null) &&
|
|
!String.IsNullOrEmpty(message.Headers.Action) &&
|
|
(message.Headers.Action == this.filteredActionUriCollection[i]))
|
|
{
|
|
return authPolicy;
|
|
}
|
|
}
|
|
}
|
|
|
|
return this.wrappedAuthenticationManager.Authenticate(authPolicy, listenUri, ref message);
|
|
}
|
|
|
|
//
|
|
// We skip the authentication step if the client already has an SCT and there are no Transport level tokens.
|
|
// ServiceAuthenticationManager would have been called when the SCT was issued and there is no need to do
|
|
// Authentication again. If TransportToken was present then we would call ServiceAutenticationManager as
|
|
// TransportTokens are not authenticated during SCT issuance.
|
|
//
|
|
bool CanSkipAuthentication(Message message)
|
|
{
|
|
if ((message != null) && (message.Properties != null) && (message.Properties.Security != null) && (message.Properties.Security.TransportToken == null))
|
|
{
|
|
if ((message.Properties.Security.ProtectionToken != null) &&
|
|
(message.Properties.Security.ProtectionToken.SecurityToken != null) &&
|
|
(message.Properties.Security.ProtectionToken.SecurityToken.GetType() == typeof(SecurityContextSecurityToken)))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (message.Properties.Security.HasIncomingSupportingTokens)
|
|
{
|
|
foreach (SupportingTokenSpecification tokenSpecification in message.Properties.Security.IncomingSupportingTokens)
|
|
{
|
|
if ((tokenSpecification.SecurityTokenAttachmentMode == SecurityTokenAttachmentMode.Endorsing) &&
|
|
(tokenSpecification.SecurityToken.GetType() == typeof(SecurityContextSecurityToken)))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
}
|
|
|