620 lines · 23.1 KB · C#
RawDownload
//******************************************************************************************************//  SecurityProviderBase.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.//  05/24/2010 - Pinal C. Patel//       Modified RefreshData() method to not query the AD at all for external user.//  05/27/2010 - Pinal C. Patel//       Added usage example to code comments.//  06/15/2010 - Pinal C. Patel//       Added checks to the in-process caching logic.//  06/24/2010 - Pinal C. Patel//       Added LogError() and LogLogin() methods.//  06/25/2010 - Pinal C. Patel//       Fixed a issue in the caching mechanism employed in Current static property.//  12/03/2010 - Pinal C. Patel//       Added TranslateRole() to allow providers to perform translation on role name.//  01/05/2011 - Pinal C. Patel//       Added CanRefreshData, CanUpdateData, CanResetPassword and CanChangePassword properties along //       with accompanying RefreshData(), UpdateData(), ResetPassword() and ChangePassword() methods.//  11/23/2011 - J. Ritchie Carroll//       Modified to support buffer optimized ISupportBinaryImage.//  12/20/2012 - Starlynn Danyelle Gilliam//       Modified Header.////****************************************************************************************************** using System;using System.Configuration;using System.Diagnostics;using System.Runtime.InteropServices;using System.Security;using GSF.Configuration; namespace GSF.Security{    /// <summary>    /// Base class for a provider of role-based security in applications.    /// </summary>    /// <example>    /// This examples shows how to extend <see cref="SecurityProviderBase"/> to use a flat-file for the security data store:    /// <code>    /// using System.Data;    /// using System.IO;    /// using GSF;    /// using GSF.Data;    /// using GSF.IO;    /// using GSF.Security;    ///     /// namespace CustomSecurity    /// {    ///     public class FlatFileSecurityProvider : SecurityProviderBase    ///     {    ///         private const int LeastPrivilegedLevel = 5;    ///     ///         public FlatFileSecurityProvider(string username)    ///             : base(username)    ///         {    ///         }    ///     ///         public override bool RefreshData()    ///         {    ///             // Check for a valid username.    ///             if (string.IsNullOrEmpty(UserData.Username))    ///                 return false;    ///     ///             // Check if a file name is specified.    ///             if (string.IsNullOrEmpty(ConnectionString))    ///                 return false;    ///     ///             // Check if file exist on file system.    ///             string file = FilePath.GetAbsolutePath(ConnectionString);    ///             if (!File.Exists(file))    ///                 return false;    ///     ///             // Read the data from the specified file.    ///             DataTable data = File.ReadAllText(file).ToDataTable(",", true);    ///             DataRow[] user = data.Select(string.Format("Username = '{0}'", UserData.Username));    ///             if (user.Length > 0)    ///             {    ///                 // User exists in the specified file.    ///                 UserData.IsDefined = true;    ///                 UserData.Password = user[0]["Password"].ToNonNullString();    ///     ///                 for (int i = LeastPrivilegedLevel; i >= int.Parse(user[0]["Level"].ToNonNullString()); i--)    ///                 {    ///                     UserData.Roles.Add(i.ToString());    ///                 }    ///             }    ///     ///             return true;    ///         }    ///     ///         public override bool Authenticate(string password)    ///         {    ///             // Compare password hashes to authenticate.    ///             return (UserData.Password == SecurityProviderUtility.EncryptPassword(password));    ///         }    ///     }    /// }    /// </code>    /// Config file entries that go along with the above example:    /// <code>    /// <![CDATA[    /// <?xml version="1.0"?>    /// <configuration>    ///   <configSections>    ///     <section name="categorizedSettings" type="GSF.Configuration.CategorizedSettingsSection, GSF.Core" />    ///   </configSections>    ///   <categorizedSettings>    ///     <securityProvider>    ///       <add name="ApplicationName" value="SEC_APP" description="Name of the application being secured as defined in the backend security datastore."    ///         encrypted="false" />    ///       <add name="ConnectionString" value="Security.csv" description="Connection string to be used for connection to the backend security datastore."    ///         encrypted="false" />    ///       <add name="ProviderType" value="CustomSecurity.FlatFileSecurityProvider, CustomSecurity"    ///         description="The type to be used for enforcing security." encrypted="false" />    ///       <add name="IncludedResources" value="*=*" description="Semicolon delimited list of resources to be secured along with role names."    ///         encrypted="false" />    ///       <add name="ExcludedResources" value="" description="Semicolon delimited list of resources to be excluded from being secured."    ///         encrypted="false" />    ///       <add name="NotificationSmtpServer" value="localhost" description="SMTP server to be used for sending out email notification messages."    ///         encrypted="false" />    ///       <add name="NotificationSenderEmail" value="sender@company.com" description="Email address of the sender of email notification messages."     ///         encrypted="false" />    ///     </securityProvider>    ///   </categorizedSettings>    /// </configuration>    /// ]]>    /// </code>    /// </example>    /// <seealso cref="SecurityIdentity"/>    /// <seealso cref="SecurityPrincipal"/>    public abstract class SecurityProviderBase : ISecurityProvider    {        #region [ Members ]         // Constants         /// <summary>        /// Specifies the default value for the <see cref="ApplicationName"/> property.        /// </summary>        public const string DefaultApplicationName = "SEC_APP";         /// <summary>        /// Specifies the default value for the <see cref="ConnectionString"/> property.        /// </summary>        public const string DefaultConnectionString = "Primary={Server=DB1;Database=AppSec;Trusted_Connection=True};Backup={Server=DB2;Database=AppSec;Trusted_Connection=True}";         /// <summary>        /// Specifies the default value for the <see cref="PersistSettings"/> property.        /// </summary>        public const bool DefaultPersistSettings = true;         /// <summary>        /// Specifies the default value for the <see cref="SettingsCategory"/> property.        /// </summary>        public const string DefaultSettingsCategory = "SecurityProvider";         // Events         /// <summary>        /// Occurs when the class has been disposed.        /// </summary>        public event EventHandler Disposed;         // Fields        private string m_applicationName;        private string m_connectionString;        private SecureString m_securePassword;        private string m_authenticationFailureReason;        private string m_settingsCategory;        private readonly UserData m_userData;        private bool m_persistSettings;        private readonly bool m_canRefreshData;        private readonly bool m_canUpdateData;        private readonly bool m_canResetPassword;        private readonly bool m_canChangePassword;        private LogEventFunctionSignature m_logEvent;        private bool m_enabled;        private bool m_initialized;        private bool m_disposed;         #endregion         #region [ Constructors ]         /// <summary>        /// Initializes a new instance of the security provider.        /// </summary>        /// <param name="username">Name that uniquely identifies the user.</param>        /// <param name="canRefreshData">true if the security provider can refresh <see cref="UserData"/> from the backend data store, otherwise false.</param>        /// <param name="canUpdateData">true if the security provider can update <see cref="UserData"/> in the backend data store, otherwise false.</param>        /// <param name="canResetPassword">true if the security provider can reset user password, otherwise false.</param>        /// <param name="canChangePassword">true if the security provider can change user password, otherwise false.</param>        protected SecurityProviderBase(string username, bool canRefreshData, bool canUpdateData, bool canResetPassword, bool canChangePassword)        {            // Initialize member variables.            m_userData = new UserData(username);            m_canRefreshData = canRefreshData;            m_canUpdateData = canUpdateData;            m_canResetPassword = canResetPassword;            m_canChangePassword = canChangePassword;            m_applicationName = DefaultApplicationName;            m_connectionString = DefaultConnectionString;            m_persistSettings = DefaultPersistSettings;            m_settingsCategory = DefaultSettingsCategory;            m_logEvent = EventLog.WriteEntry;        }         /// <summary>        /// Releases the unmanaged resources before the security provider is reclaimed by <see cref="GC"/>.        /// </summary>        ~SecurityProviderBase()        {            Dispose(false);        }         #endregion         #region [ Properties ]         /// <summary>        /// Gets or sets the name of the application being secured as defined in the backend security datastore.        /// </summary>        public string ApplicationName        {            get            {                return m_applicationName;            }            set            {                m_applicationName = value;            }        }         /// <summary>        /// Gets or sets the connection string to be used for connection to the backend security datastore.        /// </summary>        public string ConnectionString        {            get            {                return m_connectionString;            }            set            {                m_connectionString = value;            }        }         /// <summary>        /// Gets or sets the password as a <see cref="SecureString"/>.        /// </summary>        public virtual SecureString SecurePassword        {            get            {                return m_securePassword;            }            set            {                if ((object)m_securePassword != null)                    m_securePassword.Dispose();                 m_securePassword = value;            }        }         /// <summary>        /// Gets or sets <see cref="SecurePassword"/> as clear text password.        /// </summary>        public string Password        {            get            {                return SecurePassword.ToUnsecureString();            }            set            {                SecurePassword = value.ToSecureString();            }        }         /// <summary>        /// Gets or sets the <see cref="LogEventFunctionSignature"/> to use for logging security events for the <see cref="SecurityProviderBase"/> implementation.        /// </summary>        /// <remarks>        /// Set <see cref="LogEvent"/> to <c>null</c> to use default handler, i.e., <see cref="EventLog.WriteEntry(string,string,EventLogEntryType,int)"/>.        /// </remarks>        public virtual LogEventFunctionSignature LogEvent        {            get            {                return m_logEvent;            }            set            {                if ((object)value == null)                    m_logEvent = EventLog.WriteEntry;                else                    m_logEvent = value;            }        }         /// <summary>        /// Gets or sets a boolean value that indicates whether security provider settings are to be saved to the config file.        /// </summary>        public bool PersistSettings        {            get            {                return m_persistSettings;            }            set            {                m_persistSettings = value;            }        }         /// <summary>        /// Gets or sets the category under which security provider settings are to be saved to the config file if the <see cref="PersistSettings"/> property is set to true.        /// </summary>        /// <exception cref="ArgumentNullException">The value being assigned is a null or empty string.</exception>        public string SettingsCategory        {            get            {                return m_settingsCategory;            }            set            {                if (string.IsNullOrEmpty(value))                    throw new ArgumentNullException("value");                 m_settingsCategory = value;            }        }         /// <summary>        /// Gets or sets a boolean value that indicates whether the security provider is currently enabled.        /// </summary>        public bool Enabled        {            get            {                return m_enabled;            }            set            {                m_enabled = value;            }        }         /// <summary>        /// Gets a flag that indicates whether the object has been disposed.        /// </summary>        public bool IsDisposed        {            get            {                return m_disposed;            }        }         /// <summary>        /// Gets the <see cref="UserData"/> object containing information about the user.        /// </summary>        public virtual UserData UserData        {            get            {                return m_userData;            }        }         /// <summary>        /// Gets a boolean value that indicates whether <see cref="RefreshData"/> operation is supported.        /// </summary>        public virtual bool CanRefreshData        {            get            {                return m_canRefreshData;            }        }         /// <summary>        /// Geta a boolean value that indicates whether <see cref="UpdateData"/> operation is supported.        /// </summary>        public virtual bool CanUpdateData        {            get            {                return m_canUpdateData;            }        }         /// <summary>        /// Gets a boolean value that indicates whether <see cref="ResetPassword"/> operation is supported.        /// </summary>        public virtual bool CanResetPassword        {            get            {                return m_canResetPassword;            }        }         /// <summary>        /// Gets a boolean value that indicates whether <see cref="ChangePassword"/> operation is supported.        /// </summary>        public virtual bool CanChangePassword        {            get            {                return m_canChangePassword;            }        }         /// <summary>        /// Gets or allows derived classes to set an authentication failure reason.        /// </summary>        public virtual string AuthenticationFailureReason        {            get            {                return m_authenticationFailureReason;            }            protected set            {                m_authenticationFailureReason = value;            }        }         /// <summary>        /// Gets current intialization state.        /// </summary>        protected bool Initialized        {            get            {                return m_initialized;            }         }         #endregion         #region [ Methods ]         #region [ Abstract ]         /// <summary>        /// When overridden in a derived class, authenticates the user.        /// </summary>        /// <param name="password">Password to be used for authentication.</param>        /// <returns>true if the user is authenticated, otherwise false.</returns>        public abstract bool Authenticate(string password);         /// <summary>        /// When overridden in a derived class, refreshes the <see cref="UserData"/> from the backend datastore.        /// </summary>        /// <returns>true if <see cref="UserData"/> is refreshed, otherwise false.</returns>        public abstract bool RefreshData();         /// <summary>        /// When overridden in a derived class, updates the <see cref="UserData"/> in the backend datastore.        /// </summary>        /// <returns>true if <see cref="UserData"/> is updated, otherwise false.</returns>        public abstract bool UpdateData();         /// <summary>        /// When overridden in a derived class, resets user password in the backend datastore.        /// </summary>        /// <param name="securityAnswer">Answer to the user's security question.</param>        /// <returns>true if the password is reset, otherwise false.</returns>        public abstract bool ResetPassword(string securityAnswer);         /// <summary>        /// When overridden in a derived class, changes user password in the backend datastore.        /// </summary>        /// <param name="oldPassword">User's current password.</param>        /// <param name="newPassword">User's new password.</param>

Lines 1–500 of 620.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t