//****************************************************************************************************** // SecurityPrincipal.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: // ---------------------------------------------------------------------------------------------------- // 03/22/2010 - Pinal C. Patel // Generated original version of source code. // 12/03/2010 - Pinal C. Patel // Modified IsInRole() to allow for translation of role name before applying security using it. // 12/20/2012 - Starlynn Danyelle Gilliam // Modified Header. // //****************************************************************************************************** using System; using System.Linq; using System.Security.Principal; namespace GSF.Security { /// /// A class that implements interface to facilitate custom role-based security. /// /// /// public class SecurityPrincipal : IPrincipal { #region [ Members ] // Fields private readonly SecurityIdentity m_identity; #endregion #region [ Constructors ] /// /// Initializes a new instance of the class. /// /// An object. /// Value specified for is null. public SecurityPrincipal(SecurityIdentity identity) { if (identity == null) throw new ArgumentNullException(nameof(identity)); m_identity = identity; } #endregion #region [ Properties ] /// /// Gets the object of the user. /// public SecurityIdentity Identity { get { return m_identity; } } /// /// Gets the object of the user. /// IIdentity IPrincipal.Identity { get { return m_identity; } } #endregion #region [ Methods ] /// /// Determines whether the user is a member of either of the specified . /// /// Comma separated list of roles to check. /// true if the user is a member of either of the specified , otherwise false. public bool IsInRole(string roles) { if (!m_identity.Provider.UserData.IsDefined || !m_identity.Provider.IsUserAuthenticated || m_identity.Provider.UserData.IsDisabled || m_identity.Provider.UserData.IsLockedOut) { // No need to check user roles. return false; } // Check if user has any one of the specified roles. foreach (string role in roles.Split(',')) { if (m_identity.Provider.UserData.Roles.FirstOrDefault(currentRole => (SecurityProviderUtility.IsRegexMatch(m_identity.Provider.TranslateRole(role.Trim()), currentRole))) != null) return true; } return false; } #endregion #region [ Static ] // Static Methods /// /// Gets the reason phrase to return for an unauthorized response. /// /// Security principal being authenticated, can be null. /// Authentication scheme in use. /// true to use detailed response from security provider. /// Reason phrase to return for an unauthorized response. /// /// Detailed provider response should normally only be used for diagnostics, a more obscure reason is considered /// more secure since it limits knowledge about the successful elements of an authentication attempt. /// public static string GetFailureReasonPhrase(SecurityPrincipal securityPrincipal, string authorizationScheme = "Basic", bool useProviderReason = false) { if ((object)securityPrincipal == null) return "Invalid user name or password"; if (useProviderReason) { // The security provider should be able to provide a reason for the failure string failureReason = securityPrincipal.Identity.Provider?.AuthenticationFailureReason; if (!string.IsNullOrEmpty(failureReason)) return failureReason; } if (authorizationScheme == "Basic") return "Invalid user name or password"; return "Missing credentials"; } #endregion } }