ASP.NET&Spring.NET&NHibernate最佳实践(十九)——第4章权限子系统(12)

本文介绍了一个自定义的Hibernate成员资格提供程序,该程序用于管理ASP.NET应用程序中的用户认证信息,包括用户密码的更改及密码问题和答案的更新。

成员资格信息提供类(HibernateMembershipProvider.cs)

using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Security;
using System.Collections.Specialized;
using System.Configuration.Provider;
using System.Text.RegularExpressions;
using Guushuuse.SalaryPrj.Security.Service;
using System.Collections;
using System.Globalization;
using Guushuuse.SalaryPrj.Security.DomainModel;
using System.Security.Cryptography;

namespace Guushuuse.SalaryPrj.Security.Providers
{
    
/**//// <summary>
    
///管理数据库中 ASP.NET 应用程序的成员资格信息存储
    
/// </summary>

    public class HibernateMembershipProvider : MembershipProvider
    
{
        
private string _applicationName;
        
private bool _enablePasswordReset;
        
private bool _enablePasswordRetrieval;
        
private int _maxInvalidPasswordAttempts;
        
private int _minRequiredNonAlphanumericCharacters;
        
private int _minRequiredPasswordLength;
        
private int _passwordAttemptWindow;
        
private MembershipPasswordFormat _passwordFormat;
        
private string _passwordStrengthRegularExpression;
        
private bool _requiresQuestionAndAnswer;
        
private bool _requiresUniqueEmail;

        
属性#region 属性

        
/**//// <summary>
        
/// 获取或设置要存储和检索其成员资格信息的应用程序的名称
        
/// </summary>

        public override string ApplicationName
        
{
            
get
            
{
                
return _applicationName;
            }

            
set
            
{
                
if (String.IsNullOrEmpty(value))
                
{
                    
throw new ArgumentNullException("Provider application name not null.");
                }

                
if (value.Length > 255)
                
{
                    
throw new ProviderException("Provider application name too long.");
                }

                _applicationName 
= value;

            }

        }


        
/**//// <summary>
        
/// 获取一个值,指示成员资格提供程序是否配置为允许用户重置其密码
        
/// </summary>

        public override bool EnablePasswordReset
        
{
            
get return _enablePasswordReset; }
        }


        
/**//// <summary>
        
/// 获取一个值,指示成员资格提供程序是否配置为允许用户检索其密码
        
/// </summary>

        public override bool EnablePasswordRetrieval
        
{
            
get return _enablePasswordRetrieval; }
        }


        
/**//// <summary>
        
/// 获取锁定成员资格用户前允许的无效密码或无效密码提示问题答案尝试次数
        
/// </summary>

        public override int MaxInvalidPasswordAttempts
        
{
            
get return _maxInvalidPasswordAttempts; }
        }


        
/**//// <summary>
        
/// 获取有效密码中必须包含的最少特殊字符数
        
/// </summary>

        public override int MinRequiredNonAlphanumericCharacters
        
{
            
get return _minRequiredNonAlphanumericCharacters; }
        }


        
/**//// <summary>
        
/// 获取密码所要求的最小长度
        
/// </summary>

        public override int MinRequiredPasswordLength
        
{
            
get return _minRequiredPasswordLength; }
        }


        
/**//// <summary>
        
/// 获取在锁定成员资格用户之前允许的最大无效密码或无效密码提示问题答案尝试次数的分钟数
        
/// </summary>

        public override int PasswordAttemptWindow
        
{
            
get return _passwordAttemptWindow; }
        }


        
/**//// <summary>
        
/// 获取一个值,表示用于在成员资格数据库中存储密码的格式
        
/// </summary>

        public override MembershipPasswordFormat PasswordFormat
        
{
            
get return _passwordFormat; }
        }


        
/**//// <summary>
        
/// 获取用于计算密码的正则表达式
        
/// </summary>

        public override string PasswordStrengthRegularExpression
        
{
            
get return _passwordStrengthRegularExpression; }
        }


        
/**//// <summary>
        
/// 获取一个值,指示成员资格提供程序是否配置为要求用户在进行密码重置和检索时回答密码提示问题
        
/// </summary>

        public override bool RequiresQuestionAndAnswer
        
{
            
get return _requiresQuestionAndAnswer; }
        }


        
/**//// <summary>
        
/// 获取一个值,指示成员资格提供程序是否配置为要求每个用户名具有唯一的电子邮件地址
        
/// </summary>

        public override bool RequiresUniqueEmail
        
{
            
get return _requiresUniqueEmail; }
        }


        
#endregion
 属性

        
方法#region 方法

        
/**//// <summary>
        
/// 使用 ASP.NET 应用程序配置文件中指定的属性值初始化成员资格提供程序
        
/// </summary>
        
/// <param name="name"></param>
        
/// <param name="config"></param>

        public override void Initialize(string name, NameValueCollection config)
        
{
            
if (config == null)
            
{
                
throw new ArgumentNullException("config");
            }


            
if (String.IsNullOrEmpty(name))
            
{
                name 
= "HibernateMembershipProvider";
            }


            
if (String.IsNullOrEmpty(config["description"]))
            
{
                config.Remove(
"description");
                config.Add(
"description""GFC.Security Membership Provider");
            }


            
base.Initialize(name, config);

            
this._enablePasswordRetrieval = SecUtility.GetBooleanValue(config, "enablePasswordRetrieval"false);
            
this._enablePasswordReset = SecUtility.GetBooleanValue(config, "enablePasswordReset"true);
            
this._requiresQuestionAndAnswer = SecUtility.GetBooleanValue(config, "requiresQuestionAndAnswer"true);
            
this._requiresUniqueEmail = SecUtility.GetBooleanValue(config, "requiresUniqueEmail"true);
            
this._maxInvalidPasswordAttempts = SecUtility.GetIntValue(config, "maxInvalidPasswordAttempts"5false0);
            
this._passwordAttemptWindow = SecUtility.GetIntValue(config, "passwordAttemptWindow"10false0);
            
this._minRequiredPasswordLength = SecUtility.GetIntValue(config, "minRequiredPasswordLength"7false128);
            
this._minRequiredNonAlphanumericCharacters = SecUtility.GetIntValue(config, "minRequiredNonalphanumericCharacters"1true128);

            
this._passwordStrengthRegularExpression = config["passwordStrengthRegularExpression"];
            
if (this._passwordStrengthRegularExpression != null)
            
{
                
this._passwordStrengthRegularExpression = this._passwordStrengthRegularExpression.Trim();
                
if (this._passwordStrengthRegularExpression.Length != 0)
                
{
                    
try
                    
{
                        
new Regex(this._passwordStrengthRegularExpression);
                    }

                    
catch (ArgumentException e)
                    
{
                        
throw new ProviderException(e.Message, e);
                    }

                }

            }

            
else
            
{
                
this._passwordStrengthRegularExpression = String.Empty;
            }


            
this._applicationName = config["applicationName"];
            
if (String.IsNullOrEmpty(this._applicationName))
            
{
                
this._applicationName = SecUtility.GetDefaultAppName();
            }


            
if (this._applicationName.Length > 255)
            
{
                
throw new ProviderException("Provider application name is too long, max length is 255.");
            }


            
if (!ServiceLocator.ApplicationService.ApplicationExists(this._applicationName))
            
{
                ServiceLocator.ApplicationService.CreateApplication(
this._applicationName);
            }


            
string strTemp = config["passwordFormat"];
            
if (strTemp == null)
            
{
                strTemp 
= "Hashed";
            }


            
switch (strTemp)
            
{
                
case "Clear":
                    
this._passwordFormat = MembershipPasswordFormat.Clear;
                    
break;
                
case "Encrypted":
                    
this._passwordFormat = MembershipPasswordFormat.Encrypted;
                    
break;
                
case "Hashed":
                    
this._passwordFormat = MembershipPasswordFormat.Hashed;
                    
break;
                
default:
                    
throw new ProviderException("Bad password format.");
            }


            
if (this._passwordFormat == MembershipPasswordFormat.Hashed && this._enablePasswordRetrieval)
            
{
                
throw new ProviderException("Provider cannot retrieve hashed password.");
            }


            config.Remove(
"applicationName");
            config.Remove(
"enablePasswordRetrieval");
            config.Remove(
"enablePasswordReset");
            config.Remove(
"requiresQuestionAndAnswer");
            config.Remove(
"requiresUniqueEmail");
            config.Remove(
"maxInvalidPasswordAttempts");
            config.Remove(
"passwordAttemptWindow");
            config.Remove(
"passwordFormat");
            config.Remove(
"name");
            config.Remove(
"description");
            config.Remove(
"minRequiredPasswordLength");
            config.Remove(
"minRequiredNonalphanumericCharacters");
            config.Remove(
"passwordStrengthRegularExpression");

            
if (config.Count > 0)
            
{
                
string attribUnrecognized = config.GetKey(0);
                
if (!String.IsNullOrEmpty(attribUnrecognized))
                
{
                    
throw new ProviderException("Provider unrecognized attribute: " + attribUnrecognized);
                }

            }

        }


        
/**//// <summary>
        
/// 修改用户密码
        
/// </summary>
        
/// <param name="username"></param>
        
/// <param name="oldPassword"></param>
        
/// <param name="newPassword"></param>
        
/// <returns></returns>

        public override bool ChangePassword(string username, string oldPassword, string newPassword)
        
{
            SecUtility.CheckParameter(
ref username, truetruetrue255"username");
            SecUtility.CheckParameter(
ref oldPassword, truetruefalse128"oldPassword");
            SecUtility.CheckParameter(
ref newPassword, truetruefalse128"newPassword");

            
string salt;
            MembershipPasswordFormat passwordFormat;

            
if (!CheckPassword(username, oldPassword, falsefalseout salt, out passwordFormat))
            
{
                
return false;
            }


            
if (newPassword.Length < this._minRequiredPasswordLength)
            
{
                
throw new ArgumentException("New Password too short.");
            }


            
int nonAlphanumericCharacters = 0;

            
for (int i = 0; i < newPassword.Length; i++)
            
{
                
if (!char.IsLetterOrDigit(newPassword, i))
                
{
                    nonAlphanumericCharacters
++;
                }

            }


            
if (nonAlphanumericCharacters < this._minRequiredNonAlphanumericCharacters)
            
{
                
throw new ArgumentException("Password need more non alpha numeric chars.");
            }


            
if ((this._passwordStrengthRegularExpression.Length > 0&& !Regex.IsMatch(newPassword, this._passwordStrengthRegularExpression))
            
{
                
throw new ArgumentException("Password does not match regular expression.");
            }


            
string pass = EncodePassword(newPassword, passwordFormat, salt);

            
if (pass.Length > 128)
            
{
                
throw new ArgumentException("Membership password too long.");
            }


            ValidatePasswordEventArgs args 
= new ValidatePasswordEventArgs(username, newPassword, false);
            
this.OnValidatingPassword(args);
            
if (args.Cancel)
            
{
                
if (args.FailureInformation != null)
                
{
                    
throw args.FailureInformation;
                }

                
throw new ArgumentException("Membership custom password validation failure.");
            }


            
int status = ServiceLocator.UserService.UpdatePassword(this._applicationName, username, pass, salt, passwordFormat,
                DateTime.UtcNow);

            
if (status != 0)
            
{
                
string errText = GetExceptionText(status);

                
if (IsStatusDueToBadPassword(status))
                
{
                    
throw new MembershipPasswordException(errText);
                }

                
throw new ProviderException(errText);
            }


            
return true;
        }


        
/**//// <summary>
        
/// 更新成员资格数据库中用户的密码提示问题和答案
        
/// </summary>
        
/// <param name="username"></param>
        
/// <param name="password"></param>
        
/// <param name="newPasswordQuestion"></param>
        
/// <param name="newPasswordAnswer"></param>
        
/// <returns></returns>

        public override bool ChangePasswordQuestionAndAnswer(string username, string password,
            
string newPasswordQuestion, string newPasswordAnswer)
        
{
            SecUtility.CheckParameter(
ref username, truetruetrue255"username");
            SecUtility.CheckParameter(
ref password, truetruefalse128"password");

            
string salt;
            MembershipPasswordFormat passwordFormat;

            
if (!CheckPassword(username, password, falsefalseout salt, out passwordFormat))
            
{
                
return false;
            }


            SecUtility.CheckParameter(
ref newPasswordQuestion, this.RequiresQuestionAndAnswer, this.RequiresQuestionAndAnswer, false255"newPasswordQuestion");

            
if (newPasswordAnswer != null)
            
{
                newPasswordAnswer 
= newPasswordAnswer.Trim();
            }


            SecUtility.CheckParameter(
ref newPasswordAnswer, this.RequiresQuestionAndAnswer, this.RequiresQuestionAndAnswer, false128"newPasswordAnswer");

            
string answer;
            
if (!String.IsNullOrEmpty(newPasswordAnswer))
            
{
                answer 
= EncodePassword(newPasswordAnswer.ToLower(CultureInfo.InvariantCulture), passwordFormat, salt);
            }

            
else
            
{
                answer 
= newPasswordAnswer;
            }


            SecUtility.CheckParameter(
ref answer, this._requiresQuestionAndAnswer, this._requiresQuestionAndAnswer, false128"newPasswordAnswer");

            
int status = ServiceLocator.UserService.ChangePasswordQuestionAndAnswer(this._applicationName, username, newPasswordQuestion, answer);

            
if (status != 0)
            
{
                
throw new ProviderException(GetExceptionText(status));
            }


            
return true;
        }

转载于:https://www.cnblogs.com/guushuuse/archive/2008/05/17/1201503.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值