我有一个MVC 3应用程序。安全方面主要有两个区域。第一个主要是防止公众访问,但不是真正敏感的信息。密码强度可能很弱,因为这两者都没有太大的危害。
第二区(区)受到限制。用户必须申请访问权限。如果用户获得访问权限,则会获得某个角色。因此,每个控制器方法都会根据该角色对用户进行自动调整。
我希望这些用户必须在下次登录时将密码更改为强密码才能进一步访问受限制的内容。
示例:
用户A申请访问权限。 访问被授予。密码策略 只要具有访问权限,该用户就会被更改。他们一定 在下次登录时更改密码,他们无法更改回来 密码较弱,只要他们有这个角色。
有没有安全的方法可以使用ASP.NET实现这个?
更新
我实际上已经使用了Chris提出的解决方案并且它可以工作,但是为了处理密码本身的验证,我实际上也从Micah提出的解决方案中获得了一些灵感。然而,事实证明,重写MembershipProvider.OnValidatingPassword也意味着还必须实现10 +抽象方法,我真的不需要解决这个问题。
我眼中的一个更好的解决方案是挂在Membership.ValidatingPassword EVENT上。我这样做是App_Start,然后我在事件处理程序中实现自己的密码验证,这解决了我的问题。
为了与你分享解决方案,我将它呈现在这里,与克里斯解决方案一起解决了我的问题,希望也能为其他人解决:
void App_Start()
{
//To do custom validation on certain passwords set new event handler
Membership.ValidatingPassword += Membership_ValidatingPassword;
}
private void Membership_ValidatingPassword(object sender, ValidatePasswordEventArgs e)
{
//If the user is a new user, we let registration happen without strong password
if (e.IsNewUser) return;
MembershipUser membershipUser = Membership.GetUser(e.UserName);
Guid userId = Guid.Parse(membershipUser.ProviderUserKey.ToString());
//First check if the pwd is strong enough to be flagged, if so we flag it
//using regex to validate the password (20 char, 2 uppercase so on)
if (MyValidationClass.IsStrongPassword(e.Password, 20, 2, 4, 1))
{
//if the user does not already have a flag we set one
MyValidationClass.SetStrongPasswordFlag(userId);
}
else
{
//If the user needs strong pwd, we cancel the operation and throw exception
if (MyValidationClass.NeedsStrongPassword(e.UserName))
{
e.FailureInformation =
new MembershipPasswordException("Password does not satisfy reqirements!");
e.Cancel = true;
}
else
{
MyValidationClass.RemoveStrongPasswordFlag(userId);
}
}
}
答案 0 :(得分:2)
您可以编写自己的授权属性以适应两者。您只需在应用程序的相关部分使用它:
例如:
public class HasChangedPasswordAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
UserRepository repo = new UserRepository();
var user = repo.GetCurrentUser();
bool hasSecurelyChangedPassword = user.HasSecurelyChangedPassword;
return hasSecurelyChangedPassword;
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Result = new RedirectResult("/Account/ChangePassword");
}
}
以上将检查用户是否已安全地更改了密码。如果没有,它会将它们重定向到更改密码的新页面。一旦他们改变它,将标志设置为已更改。
然后您可以像这样使用它:
[HasChangedPassword]
[Authorize(Roles="SuperRole")]
public ActionResult MySecureAction()
{
...
}
显然,您可以将这两个属性集成到一个属性中,但为了显示示例,它们将在上面分开。
答案 1 :(得分:1)
您需要覆盖MembershipProvider.OnValidatingPassword
答案 2 :(得分:-1)
当用户尝试输入新密码时,可能更简单的方法是检查客户端密码的强度。有关使用JQuery的一些示例,请查看此list。
关于升级和重置密码的事务,这是您的代码可以处理的事情,即用户表中将用户重定向到新注册页面的标志。但是当他们设置密码(并且可能与适当的强度相匹配)时,可以提交密码......