AuthorizationRule.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / Web / Configuration / AuthorizationRule.cs / 1305376 / AuthorizationRule.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.Configuration { 
    using System; 
    using System.Xml;
    using System.Configuration; 
    using System.Collections.Specialized;
    using System.Collections;
    using System.Globalization;
    using System.IO; 
    using System.Text;
    using System.Security.Principal; 
    using System.Web.Util; 
    using System.ComponentModel;
    using System.Security.Permissions; 

    public sealed class AuthorizationRule : ConfigurationElement {
        private static readonly TypeConverter s_PropConverter = new CommaDelimitedStringCollectionConverter();
 
        private static ConfigurationPropertyCollection _properties;
        private static readonly ConfigurationProperty _propVerbs = 
            new ConfigurationProperty("verbs", 
                                        typeof(CommaDelimitedStringCollection),
                                        null, 
                                        s_PropConverter,
                                        null,
                                        ConfigurationPropertyOptions.None);
        private static readonly ConfigurationProperty _propUsers = 
            new ConfigurationProperty("users",
                                        typeof(CommaDelimitedStringCollection), 
                                        null, 
                                        s_PropConverter,
                                        null, 
                                        ConfigurationPropertyOptions.None);
        private static readonly ConfigurationProperty _propRoles =
            new ConfigurationProperty("roles",
                                        typeof(CommaDelimitedStringCollection), 
                                        null,
                                        s_PropConverter, 
                                        null, 
                                        ConfigurationPropertyOptions.None);
        private AuthorizationRuleAction _Action = AuthorizationRuleAction.Allow; 
        internal string _ActionString = AuthorizationRuleAction.Allow.ToString();


        private string _ElementName = "allow"; 

        private CommaDelimitedStringCollection _Roles = null; 
        private CommaDelimitedStringCollection _Verbs = null; 
        private CommaDelimitedStringCollection _Users = null;
 
        private StringCollection _RolesExpanded;
        private StringCollection _UsersExpanded;

        private char[] _delimiters = { ',' }; 

        private string machineName = null; 
        private const String _strAnonUserTag = "?"; 
        private const String _strAllUsersTag = "*";
        private bool _AllUsersSpecified = false; 
        private bool _AnonUserSpecified = false;
        private bool DataReady = false;
        private bool _Everyone = false;
        internal bool Everyone { get { return _Everyone; } } 
        private bool _ActionModified = false;
 
        static AuthorizationRule() { 
            // Property initialization
            _properties = new ConfigurationPropertyCollection(); 

            // If updating, check out CloneMutableExposedObjects
            _properties.Add(_propVerbs);
            _properties.Add(_propUsers); 
            _properties.Add(_propRoles);
        } 
 
        internal AuthorizationRule() {
        } 

        public AuthorizationRule(AuthorizationRuleAction action) : this() {
            Action = action;
        } 

        protected override ConfigurationPropertyCollection Properties { 
            get { 
                return _properties;
            } 
        }

        protected override void Unmerge(ConfigurationElement sourceElement,
                                                ConfigurationElement parentElement, 
                                                ConfigurationSaveMode saveMode) {
            AuthorizationRule parentProviders = parentElement as AuthorizationRule; 
            AuthorizationRule sourceProviders = sourceElement as AuthorizationRule; 

            if (parentProviders != null) { 
                parentProviders.UpdateUsersRolesVerbs();
            }
            if (sourceProviders != null) {
                sourceProviders.UpdateUsersRolesVerbs(); 
            }
            base.Unmerge(sourceElement, parentElement, saveMode); 
        } 

        protected override void Reset(ConfigurationElement parentElement) { 
            AuthorizationRule parentProviders = parentElement as AuthorizationRule;

            if (parentProviders != null) {
                parentProviders.UpdateUsersRolesVerbs(); 
            }
            base.Reset(parentElement); 
            EvaluateData(); 
        }
 
        internal void AddRole(string role) {
            if (!String.IsNullOrEmpty(role)) {
                role = role.ToLower(CultureInfo.InvariantCulture);
            } 
            Roles.Add(role);
            RolesExpanded.Add(ExpandName(role)); 
        } 

        internal void AddUser(string user) { 
            if (!String.IsNullOrEmpty(user)) {
                user = user.ToLower(CultureInfo.InvariantCulture);
            }
            Users.Add(user); 
            UsersExpanded.Add(ExpandName(user));
        } 
 
        private void UpdateUsersRolesVerbs() {
            CommaDelimitedStringCollection roles; 
            CommaDelimitedStringCollection users;
            CommaDelimitedStringCollection verbs;

            roles = (CommaDelimitedStringCollection)Roles; 
            users = (CommaDelimitedStringCollection)Users;
            verbs = (CommaDelimitedStringCollection)Verbs; 
 
            if (roles.IsModified) {
                _RolesExpanded = null;   // throw away old collection and force a new one to be created 
                base[_propRoles] = roles;  // Update property bag
            }

            if (users.IsModified) { 
                _UsersExpanded = null;   // throw away old collection and force a new one to be created
                base[_propUsers] = users;  // Update property bag 
            } 

            if (verbs.IsModified) { 
                base[_propVerbs] = verbs;  // Update property bag
            }
        }
        protected override bool IsModified() { 
            UpdateUsersRolesVerbs();
            return _ActionModified || base.IsModified() || (((CommaDelimitedStringCollection)Users).IsModified) || 
                (((CommaDelimitedStringCollection)Roles).IsModified) || 
                (((CommaDelimitedStringCollection)Verbs).IsModified);
        } 

        protected override void ResetModified() {
            _ActionModified = false;
            base.ResetModified(); 
        }
 
        public override bool Equals(object obj) { 
            AuthorizationRule o = obj as AuthorizationRule;
            bool bRet = false; 
            if (o != null) {
                UpdateUsersRolesVerbs();

                bRet = (o.Verbs.ToString() == Verbs.ToString() && 
                        o.Roles.ToString() == Roles.ToString() &&
                        o.Users.ToString() == Users.ToString() && 
                        o.Action == Action); 
            }
            return bRet; 
        }

        public override int GetHashCode() {
            string __verbs = Verbs.ToString(); 
            string __roles = Roles.ToString();
            string __users = Users.ToString(); 
 
            if (__verbs == null) {
                __verbs = String.Empty; 
            }
            if (__roles == null) {
                __roles = String.Empty;
            } 
            if (__users == null) {
                __users = String.Empty; 
            } 

            int hHashCode = HashCodeCombiner.CombineHashCodes(__verbs.GetHashCode(), __roles.GetHashCode(), 
                                                              __users.GetHashCode(), (int)Action);

            return hHashCode;
        } 

        protected override void SetReadOnly() { 
            ((CommaDelimitedStringCollection)Users).SetReadOnly(); 
            ((CommaDelimitedStringCollection)Roles).SetReadOnly();
            ((CommaDelimitedStringCollection)Verbs).SetReadOnly(); 
            base.SetReadOnly();
        }

        ///  
        ///       Defines the action that needs to be taken if the rule is satisfied.
        ///      
        ///  

        // 
        // No Configuration properties are set on this property because its supposed to be hidden to tools.
        //
        public AuthorizationRuleAction Action {
            get { 
                return _Action;
            } 
            set { 
                _ElementName = value.ToString().ToLower(CultureInfo.InvariantCulture);
                _Action = value; 
                _ActionString = _Action.ToString();
                _ActionModified = true;
            }
        } 

        ///  
        ///      Defines a list of verbs needed to satisfy the rule 
        ///     
        ///  

        [ConfigurationProperty("verbs")]
        [TypeConverter(typeof(CommaDelimitedStringCollectionConverter))]
        public StringCollection Verbs { 
            get {
                if (_Verbs == null) { 
                    CommaDelimitedStringCollection propertyBagValue; 

                    propertyBagValue = (CommaDelimitedStringCollection)base[_propVerbs]; 

                    if (propertyBagValue == null) {
                        _Verbs = new CommaDelimitedStringCollection();
                    } 
                    else {
                        // Clone it so we don't give back same mutable 
                        // object as possibly parent 
                        _Verbs = propertyBagValue.Clone();
                    } 
                }

                return (StringCollection)_Verbs;
            } 
        }
 
        ///  
        ///      Defines a list of users authorized for this rule.
        ///      
        /// 

        [ConfigurationProperty("users")]
        [TypeConverter(typeof(CommaDelimitedStringCollectionConverter))] 
        public StringCollection Users {
            get { 
                if (_Users == null) { 
                    CommaDelimitedStringCollection propertyBagValue;
 
                    propertyBagValue = (CommaDelimitedStringCollection)base[_propUsers];

                    if (propertyBagValue == null) {
                        _Users = new CommaDelimitedStringCollection(); 
                    }
                    else { 
                        // Clone it so we don't give back same mutable 
                        // object as possibly parent
                        _Users = propertyBagValue.Clone(); 
                    }

                    _UsersExpanded = null; // throw away old collection and force a new one to be created
                } 

                return (StringCollection)_Users; 
            } 
        }
 
        [ConfigurationProperty("roles")]
        [TypeConverter(typeof(CommaDelimitedStringCollectionConverter))]
        public StringCollection Roles {
            get { 
                if (_Roles == null) {
                    CommaDelimitedStringCollection propertyBagValue; 
 
                    propertyBagValue = (CommaDelimitedStringCollection)base[_propRoles];
 
                    if (propertyBagValue == null) {
                        _Roles = new CommaDelimitedStringCollection();
                    }
                    else { 
                        // Clone it so we don't give back same mutable
                        // object as possibly parent 
                        _Roles = propertyBagValue.Clone(); 
                    }
 
                    _RolesExpanded = null; // throw away old collection and force a new one to be created
                }

                return (StringCollection)_Roles; 
            }
        } 
 
        internal StringCollection UsersExpanded {
            get { 
                if (_UsersExpanded == null) {
                    _UsersExpanded = CreateExpandedCollection(Users);
                }
 
                return _UsersExpanded;
            } 
        } 

        internal StringCollection RolesExpanded { 
            get {
                if (_RolesExpanded == null) {
                    _RolesExpanded = CreateExpandedCollection(Roles);
                } 

                return _RolesExpanded; 
            } 
        }
 
        protected override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey) {
            bool DataToWrite = false;
            UpdateUsersRolesVerbs();            // the ismodifed can be short circuited
 
            if (base.SerializeElement(null, false) == true) {
                if (writer != null) { 
                    writer.WriteStartElement(_ElementName); 
                    DataToWrite |= base.SerializeElement(writer, false);
                    writer.WriteEndElement(); 
                }
                else
                    DataToWrite |= base.SerializeElement(writer, false);
            } 
            return DataToWrite;
        } 
 
        private string ExpandName(string name) {
            string ExpandedName = name; 

            if (StringUtil.StringStartsWith(name, @".\")) {
                if (machineName == null) {
                    machineName = HttpServerUtility.GetMachineNameInternal().ToLower(CultureInfo.InvariantCulture); 
                }
 
                ExpandedName = machineName + name.Substring(1); 
            }
 
            return ExpandedName;
        }

        private StringCollection CreateExpandedCollection(StringCollection collection) { 
            StringCollection ExpandedCollection = new StringCollection();
 
            foreach (string name in collection) { 
                string ExpandedName = ExpandName(name);
                ExpandedCollection.Add(ExpandedName); 
            }

            return ExpandedCollection;
        } 

        private void EvaluateData() { 
            if (DataReady == false) { 
                if (Users.Count > 0) {
                    foreach (string User in Users) { 
                        if (User.Length > 1) {
                            int foundIndex = User.IndexOfAny(new char[] { '*', '?' });

                            if (foundIndex >= 0) { 
                                throw new ConfigurationErrorsException(SR.GetString(SR.Auth_rule_names_cant_contain_char, User[foundIndex].ToString(CultureInfo.InvariantCulture)));
                            } 
                        } 

                        if (User.Equals(_strAllUsersTag)) { 
                            _AllUsersSpecified = true;
                        }

                        if (User.Equals(_strAnonUserTag)) { 
                            _AnonUserSpecified = true;
                        } 
                    } 
                }
 
                if (Roles.Count > 0) {
                    foreach (string Role in Roles) {
                        if (Role.Length > 0) {
                            int foundIndex = Role.IndexOfAny(new char[] { '*', '?' }); 

                            if (foundIndex >= 0) { 
                                throw new ConfigurationErrorsException(SR.GetString(SR.Auth_rule_names_cant_contain_char, Role[foundIndex].ToString(CultureInfo.InvariantCulture))); 
                            }
                        } 
                    }
                }

                _Everyone = (_AllUsersSpecified && (Verbs.Count == 0)); 
                _RolesExpanded = CreateExpandedCollection(Roles);
                _UsersExpanded = CreateExpandedCollection(Users); 
                if (Roles.Count == 0 && Users.Count == 0) { 
                    throw new ConfigurationErrorsException(SR.GetString(SR.Auth_rule_must_specify_users_andor_roles));
                } 
                DataReady = true;
            }
        }
 
        internal bool IncludesAnonymous {
            get { 
                EvaluateData(); 
                return (_AnonUserSpecified && Verbs.Count == 0);
            } 
        }

        protected override void PreSerialize(XmlWriter writer) {
            EvaluateData(); 
        }
 
        protected override void PostDeserialize() { 
            EvaluateData();
        } 

        /////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////
        // 0 => Don't know, 1 => Yes, -1 => No 
        internal int IsUserAllowed(IPrincipal user, String verb) {
            EvaluateData(); 
 
            int answer = ((Action == AuthorizationRuleAction.Allow) ? 1 : -1); // return value if this rule applies
 
            if (Everyone) {
                return answer;
            }
 
            ///////////////////////////////////////////////////
            // Step 1: Make sure the verbs match 
            if (!FindVerb(verb)) { 
                return 0;
            } 

            //////////////////////////////////////////////////
            // Step 2a: See if the rule applies to all users
            if (_AllUsersSpecified) { // All users specified 
                return answer;
            } 
 
            //////////////////////////////////////////////////
            // Step 2b: See if the rule applies to anonymous user and this user is anonymous 
            if (_AnonUserSpecified && !user.Identity.IsAuthenticated) {
                return answer;
            }
 
            //////////////////////////////////////////////////
            // Step 3: Is user is WindowsIdentity, use the expanded 
            //         set of users and roles 
            StringCollection users;
            StringCollection roles; 

            if (user.Identity is WindowsIdentity) {
                users = UsersExpanded;
                roles = RolesExpanded; 
            }
            else { 
                users = Users; 
                roles = Roles;
            } 

            ////////////////////////////////////////////////////
            // Step 4: See if the user is specified
            if (users.Count > 0 && FindUser(users, user.Identity.Name)) { 
                return answer;
            } 
 
            ////////////////////////////////////////////////////
            // Step 5: See if the user is in any specified role 
            if (roles.Count > 0 && IsTheUserInAnyRole(roles, user)) {
                return answer;
            }
 
            // Rule doesn't apply
            return 0; 
        } 

        ///////////////////////////////////////////////////////////////////////// 
        private bool FindVerb(String verb) {
            if (Verbs.Count < 1) {
                return true; // No verbs specified => all verbs are allowed
            } 

            foreach (string sVerb in Verbs) { 
                if (String.Equals(sVerb, verb, StringComparison.OrdinalIgnoreCase)) { 
                    return true;
                } 
            }
            return false;
        }
 
        private bool FindUser(StringCollection users, String principal) {
            foreach (string user in users) { 
                if (String.Equals(user, principal, StringComparison.OrdinalIgnoreCase)) { 
                    return true;
                } 
            }
            return false;
        }
 
        private bool IsTheUserInAnyRole(StringCollection roles, IPrincipal principal) {
            if (!HttpRuntime.DisableProcessRequestInApplicationTrust) { 
                if (HttpRuntime.NamedPermissionSet != null && HttpRuntime.ProcessRequestInApplicationTrust) { 
                    HttpRuntime.NamedPermissionSet.PermitOnly();
                } 
            }

            foreach (string role in roles) {
                if (principal.IsInRole(role)) { 
                    return true; // Found it!
                } 
            } 
            // Not in any specified role
            return false; 
        }
    } // class AuthorizationRule
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK