//****************************************************************************************************** // SecurityPolicy.cs - Gbtc // // Copyright © 2012, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the MIT License (MIT), the "License"; you may // not use this file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/MIT // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 04/22/2010 - Pinal C. Patel // Generated original version of source code. // 05/27/2010 - Pinal C. Patel // Added usage example to code comments. // Modified Evaluate() to make use of IncludedResources and ExcludedResources config file settings. // 06/02/2010 - Pinal C. Patel // Added authentication check to Evaluate() method. // 08/11/2010 - Pinal C. Patel // Made key methods virtual for extensibility. // 10/14/2010 - Pinal C. Patel // Modified GetResourceName() to return path and query for consistency across WCF hosting // environments (i.e. ASP.NET, WAS, etc.). // 12/20/2012 - Starlynn Danyelle Gilliam // Modified Header. // //****************************************************************************************************** using System; using System.Collections.Generic; using System.IdentityModel.Claims; using System.IdentityModel.Policy; using System.Security; using System.Security.Principal; using System.ServiceModel; using System.Threading; using GSF.Security; namespace GSF.ServiceModel { /// /// Represents an authorization policy that can be used by WCF services for enabling role-based security. /// /// /// Common config file entries: /// /// /// /// ///
/// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// ]]> /// /// Internal WCF service configuration: /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// ]]> /// /// External WCF service configuration: /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// ]]> /// /// /// public class SecurityPolicy : IAuthorizationPolicy { #region [ Members ] // Fields private Guid m_id; #endregion #region [ Constructors ] /// /// Initializes a new instance of the class. /// public SecurityPolicy() { m_id = Guid.NewGuid(); } #endregion #region [ Properties ] /// /// Gets the identifier of this instance. /// public string Id { get { return m_id.ToString(); } } /// /// Gets a claim set that represents the issuer of this . /// public ClaimSet Issuer { get { return ClaimSet.System; } } #endregion #region [ Methods ] /// /// Evaluates the and initializes security. /// /// An object. /// Custom state of the . /// public virtual bool Evaluate(EvaluationContext evaluationContext, ref object state) { // In order for this to work properly security on the binding must be configured to use windows security. // When this is done the caller's windows identity is available to us here and can be used to derive from // it the security principal that can be used by WCF service code downstream for implementing security. object property; if (evaluationContext.Properties.TryGetValue("Identities", out property)) { // Extract and assign the caller's windows identity to current thread if available. IList identities = property as List; if ((object)identities == null) throw new SecurityException(string.Format("Null Identities in Evaluation Context for '{0}'", Thread.CurrentPrincipal.Identity)); foreach (IIdentity identity in identities) { if (identity is WindowsIdentity) { Thread.CurrentPrincipal = new WindowsPrincipal((WindowsIdentity)identity); break; } } } string resource = GetResourceName(); if (SecurityProviderUtility.IsResourceSecurable(resource)) { // Initialize the security principal from caller's windows identity if uninitialized. SecurityProviderCache.ValidateCurrentProvider(); // Setup the principal to be attached to the thread on which WCF service will execute. evaluationContext.Properties["Principal"] = Thread.CurrentPrincipal; // Verify that the current thread principal has been authenticated. if (!Thread.CurrentPrincipal.Identity.IsAuthenticated) throw new SecurityException(string.Format("Authentication failed for user '{0}'", Thread.CurrentPrincipal.Identity.Name)); // Perform a top-level permission check on the resource being accessed. if (!SecurityProviderUtility.IsResourceAccessible(resource)) throw new SecurityException(string.Format("Access to '{0}' is denied", resource)); return true; } // Setup the principal to be attached to the thread on which WCF service will execute. evaluationContext.Properties["Principal"] = Thread.CurrentPrincipal; return true; } /// /// Gets the name of resource being accessed. /// /// .. property value. protected virtual string GetResourceName() { return OperationContext.Current.IncomingMessageHeaders.To.PathAndQuery; } #endregion } }