IdentityResult result = manager.Create(user, "Password134567");
if (result.Succeeded)
{
var provider = new DpapiDataProtectionProvider("WebApp2015");
UserManager<User> userManager = new UserManager<User>(new UserStore<User>());
userManager.UserTokenProvider = new DataProtectorTokenProvider<User>(provider.Create(user.Id));
manager.UserTokenProvider = new DataProtectorTokenProvider<User>(provider.Create("ConfirmUser"));
var emailInfo = new Email();
string code = HttpUtility.UrlEncode(Context.GetOwinContext().GetUserManager<ApplicationUserManager>().GenerateEmailConfirmationToken(user.Id));
string callbackUrl = IdentityHelper.GetUserConfirmationRedirectUrl(code, user.Id, Request);
if (email.IndexOf("@") != -1)
{
if (assignedId == 0)
{
lblError.Text = "There was an error adding this user";
return;
}
string emailcontent = emailInfo.GetActivationEmailContent(assignedId, callbackUrl, userRole);
string subject = emailInfo.Subject;
if (string.IsNullOrEmpty(subject))
{
subject = "Your Membership";
}
Context.GetOwinContext()
.GetUserManager<ApplicationUserManager>()
.SendEmail(user.Id, subject, emailcontent);
if (user.EmailConfirmed)
{
IdentityModels.IdentityHelper.SignIn(manager, user, isPersistent: false);
IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response);
}
else
{
ErrorMessage.ForeColor = Color.Green;
ErrorMessage.Text = "An email has been sent to the user, once they verify their email they are ready to login.";
}
}
else
{
ErrorMessage.ForeColor = System.Drawing.Color.Green;
ErrorMessage.Text = "User has been created.";
}
var ra = new RoleActions();
ra.AddUserToRoll(txtEmail.Text, txtEmail.Text, userRole);
}
else
{
ErrorMessage.Text = result.Errors.FirstOrDefault();
}
protected void Page_Load(object sender, EventArgs e)
{
var code = IdentityHelper.GetCodeFromRequest(Request);
var userId = IdentityHelper.GetUserIdFromRequest(Request);
if (code != null && userId != null)
{
var manager = Context.GetOwinContext()
.GetUserManager<ApplicationUserManager>();
var confirmId = manager.FindById(userId);
if (confirmId != null)
{
var result = manager.ConfirmEmail(userId, HttpUtility.UrlDecode(code));
if (result.Succeeded)
{
return;
}
else
{
lblError.Text = result.Errors.FirstOrDefault();
txtNewPassword.TextMode= TextBoxMode.SingleLine;
txtNewPassword.Text = "Error contact support";
txtNewPassword2.TextMode= TextBoxMode.SingleLine;
txtNewPassword2.Text = result.Errors.FirstOrDefault();
txtNewPassword.Enabled = false;
txtNewPassword2.Enabled = false;
imageButton1.Enabled = false;
}
}
else
{
lblError.Text = "Account Does Not Exist";
imageButton1.Enabled = false;
}
}
}
我为您创建了一个精简的演示项目。它在这里的GitHub上托管,在这里的Azure上直播。它按照设计的方式工作(请参见Azure网站的编辑),使用了与您使用的类似但不完全相同的方法。
它从这个教程开始,然后我删除了这个NuGet演示代码附带的cruft:
Install-Package -Prerelease Microsoft.AspNet.Identity.Samples
出于您的目的,我的演示代码比NuGet示例更相关,因为它只关注令牌的创建和验证。特别要看一下这两个文件:
public partial class Startup
{
public static IDataProtectionProvider DataProtectionProvider
{
get;
private set;
}
public void ConfigureAuth(IAppBuilder app)
{
DataProtectionProvider =
new DpapiDataProtectionProvider("WebApp2015");
// other code removed
}
}
userManager.UserTokenProvider =
new DataProtectorTokenProvider<User>(
Startup.DataProtectionProvider.Create("UserToken"));
DataProtectorTokenProvider.create(string[]composes)
方法接受composes
参数。以下是MSDN对此的看法:
目的。用于确保受保护的数据只能出于正确的目的而不受保护的额外熵。
当您创建用户code
时,您(至少)使用了两种不同的目的:
userManager.UserTokenProvider =
new DataProtectorTokenProvider<User>(provider.Create(user.Id));
manager.UserTokenProvider =
new DataProtectorTokenProvider<User>(provider.Create("ConfirmUser"));
string code = Context
.GetOwinContext()
.GetUserManager<ApplicationUserManager ()
.GenerateEmailConfirmationToken(user.Id)
验证代码
时,可能使用了错误的目的。您在何处为用于确认电子邮件的ApplicationUserManager
分配UserTokenProvider
?它的目的论点必须是相同的!
var manager = Context.GetOwinContext()
.GetUserManager<ApplicationUserManager>();
var result = manager.ConfirmEmail(userId, HttpUtility.UrlDecode(code));
令牌很有可能是无效的,因为有时创建时使用的UserTokenProvider
目的与验证时使用的目的不同。
为什么有时会这样?彻底搜索代码,查找分配给UserTokenProvider
的所有位置。也许您会在意外的地方重写它(例如在属性中或在IdentityConfig.cs文件中),以便它看起来是随机的。
manager.UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser>
(dataProtectionProvider.Create("WebApp2015"))
{
TokenLifespan = TimeSpan.FromHours(3000)
};
请注意,我删除了很多代码,只关注您的令牌创建。
// 1.
IdentityResult result = manager.Create(user, "Password134567");
if (result.Succeeded)
{
var provider = new DpapiDataProtectionProvider("WebApp2015");
// 2.
UserManager<User> userManager =
new UserManager<User>(new UserStore<User>());
userManager.UserTokenProvider =
new DataProtectorTokenProvider<User>(provider.Create(user.Id));
// 3.
manager.UserTokenProvider =
new DataProtectorTokenProvider<User>(provider.Create("ConfirmUser"));
// 4.
string raw = Context.GetOwinContext()
.GetUserManager<ApplicationUserManager>()
.GenerateEmailConfirmationToken(user.Id)
// remaining code removed
}
我想知道我们是否可以简化上述操作,只使用一个UserManager
实例,如下所示。
// 1.
IdentityResult result = manager.Create(user, "Password134567");
if (result.Succeeded)
{
var provider = new DpapiDataProtectionProvider("WebApp2015");
manager.UserTokenProvider =
new DataProtectorTokenProvider<User>(provider.Create(user.Id));
// 3.
var provider = provider.Create("ConfirmUser");
manager.UserTokenProvider =
new DataProtectorTokenProvider<User>(provider);
// 4.
string raw = manager.GenerateEmailConfirmationToken(user.Id);
// remaining code removed
}
如果使用此方法,请确保在确认电子邮件期间使用相同的“验证者”
目的参数。
var code01 = CreateCode();
var code02 = UrlEncode(code01);
var request = CreateTheRequest(code02);
var response = GetTheResponse();
var code03 = GetTheCode(response);
var code04 = UrlDecode(code03);
Assert.AreEquals(code01, code04);
运行以上1万次,确保不存在任何问题。
我强烈怀疑问题在于在创建令牌时使用了一个ophyses
参数,而在确认时使用了另一个参数。只有一个目的,你可能会没事。
app.getDataProtectionProvider()
而不是DPAPIDataProtectionProvider
,因为Dpapi不能用于web场。我用python编写了代码,定期获取特定股票代码的数据。 我面临的问题是,这段代码大部分时间都运行良好。但是,偶尔,它会抛出一个错误,说“无效的应用编程接口调用”。 这种情况并非总是发生。也许一次就是3-4个电话。有时在第一个电话里。 我绝不会修改任何东西 怎么回事啊?
问题内容: 尝试为变量分配值时出现问题。当我尝试按以下顺序将日期作为元组或列表时,问题就会出现: 为什么要打apping? 我如何解决它? 令牌在Python中是什么意思? 问题答案: 在Python 3中,数字前导零是不允许的。例如: 等是不允许的,但应改为和。 但是,在Python 2中,前导零表示该数字是一个 八进制数 (以8为底),因此,或分别表示和,并且以八进制表示,但由于它不是有效的八
问题内容: 我有以下代码从PHP 数组中选取元素: 给定一个大数组,但只有几个元素(例如out ),这相对较慢,因此我想对其进行优化,以使并非所有元素都必须改组。这些值必须是唯一的。 我正在寻找性能最好的替代产品。我们可以假设它没有重复项并且被索引了。 问题答案: 这将提供5个元素,而且没有重复项,而且很快。密钥将被保留。 注意:您必须确保$ array包含5个或更多的元素,或者添加某种检查以防止
问题内容: 在这个问题中,Erik需要在Node.js中生成一个安全的随机令牌。有一种生成随机缓冲区的方法。但是,node中的base64编码不是网址安全的,它包含和而不是和。因此,我发现生成这种令牌的最简单方法是 有没有更优雅的方式? 问题答案: 尝试crypto.randomBytes(): “十六进制”编码在节点v0.6.x或更高版本中有效。
问题内容: 我有一种方法,它使用随机样本来近似计算。这种方法被称为数百万次,因此非常重要的是选择随机数的过程必须高效。 我不确定java到底有多快,但是我的程序似乎并没有像我期望的那样受益。 选择随机数时,我将执行以下操作(半伪代码): 现在,这显然具有最坏的最坏情况下的运行时间,因为理论上随机函数可以为永恒添加重复的数字,从而永远停留在while循环中。但是,数字是从{0..45}中选择的,因此
但是,一旦我们更改命令(更改位置fontfile=with text= 我得到以下错误 [Parsed_drawtext_0@02d88a80]无法加载字体“C”:无法找到匹配的字体