Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Identity 2.2.1 - send confirmation email with code, not with link

I've successfully build simple registration system using ASP.NET Identity 2.2.1.
I only needed API so I've build simple controller that allows creating account using route account/create, when account is created user receives SMS message with token needed to confirm his phone, same time I'm generating link that is needed to verify email address and I'm sending it to user email address. Then user need to input token from SMS (do request to account/confirm_phone) and click link in email he receives.
These two actions are needed to activate account, this part works fine.

I have requirement to change email link to email token, similar to one used to confirm phone number, so instead of clicking link user will have to input that token (request to account/confirm_email)

Method GenerateEmailConfirmationTokenAsync returns very long code that becomes part of link send in email, I'd like it to return 6 digit token.

I can't reuse GeneratePhoneConfirmationTokenAsync because this will generate same token as send via SMS.

I've searched over the internet and I wasn't able to find any information how to customize token generated by GenerateEmailConfirmationTokenAsync method.

Is it possible to configure that token generator so it will return 6 (or any configurable length) digit code that I can use to confirm user email address.

I'm aware that link send to user is better option, but as I wrote this is requirement I got and I can't change that.

like image 318
Misiu Avatar asked Oct 26 '16 12:10

Misiu


1 Answers

I've had a good careful look on this and I'm afraid you are out of luck.

ASP.Net Identity framework (v2.2.x) has 2 token providers: DataProtectorTokenProvider and EmailTokenProvider.

DataProtectorTokenProvider gives you a very long token that is no good for manual copy-paste. But it allows to set a timespan: DataProtectorTokenProvider.TokenLifespan. By default it is set to 1 day - see constractor of that class. Token generated by this provider contains current UTC time, userId, security stamp and additional string purpose which can be anything, but on validation this must be the same as on generation. This is usually is "email" or "phone". Then all that data is encrypted by IDataProtector. Hence you get very long and nasty looking string.

You can have variable life span for different tokens, but you'll have to do a magic dance around setting correct value in DataProtectorTokenProvider.TokenLifespan before validating every particular token.

Another option EmailTokenProvider - this class is inherited from TotpSecurityStampBasedTokenProvider. This token provider generates One Time Password (OTP) based on Rfc6238. This token is time-sensitive and becomes invalid once the time-window is passed. See section 5.2 for more details. Default time-window for identity is set to be 3 minutes. See line:

private static readonly TimeSpan _timestep = TimeSpan.FromMinutes(3);

in Rfc6238AuthenticationService. But Rfc6238 says that implementation must allow for more than 1 time-window. Given implementation allows total of 6 minutes token lifespan. And there is no way to change that without implementing your own Rfc6238.

So Identity does not provide you the means to implement your requirement - you'll have to generate tokens yourself and store them with the timestamp. Perhaps only one of them - short token with longer lifespan. The default SMS implementation is already short-lived and short for manual entry.

like image 151
trailmax Avatar answered Sep 20 '22 20:09

trailmax