//----------------------------------------------------------------------------- // 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 Authenticate(ReadOnlyCollection 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 Authenticate(ReadOnlyCollection 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 authPolicies = new List(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 Authenticate(ReadOnlyCollection 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; } } }