Aspnet Core 1.0 Identity User Manager ConfirmEmailAsync returns InvalidToken - asp.net-core

When the user clicks the Confirm Email link in the email they receive, the url directs the user to the ConfirmEmailAsync method in the Account Controller.
This method then returns the result of the call to the Email Token Provider.
var result = await _userManager.ConfirmEmailAsync(user, code);
I have captured the generated email token when the user registers and the token that is passed in the code variable above and they are identical.
I have tried Base64 encoding and decoding with no success, although I believe this is done automatically by the asp-net-core-identity-token-providers.
Any ideas ?

Generated tokens through identity are tied to the SecurityStamp on the user. If the stamp is updated for any reason, all previously sent tokens are invalidated. Changing or setting a password would cause this to happen.
This could be an order of operations problem. Do you by chance save the register password after you send the email to validate the email they provided?
For instance, this will fail:
Send email with token
Save the register info like the password
Try to use the token.
Instead, this should work:
Save the register info
Send email with token
Try to use token
That scenario is just an example as I can't be sure that is the way your code is setup. That said, if the tokens are the same, it is likely the securitystamp that is the problem. Keep tabs on it in your database throughout the process and see if something is updating it.

Related

Keycloak Action Tokens: How to invalidate user's previous action when they request multiple (e.g. Reset Password)

I want to be able to invalidate any action token for a user within an authentication flow.
The scenario is the user sends a reset password and receives an email with an associated action token. The user then sends another reset password and gets another email with a different action token associated. For the length of the first action token expiry time the user can utilise the links in both emails - however I'd like to be able to identify within my custom reset password authentication flow that the user is requesting a duplicate action request and invalidate their earlier action token(s) so that only their latest reset password link works.
I've been looking at the below objects but had no luck finding an action token store associated with all the user's activity rather than just their current authenticated session.
AuthenticationFlowContext context;
List<UserSessionModel> sessions = context.getSession().sessions().getUserSessions(context.getRealm(), user);
RootAuthenticationSessionModel parentSessions = context.getAuthenticationSession().getParentSession();
ActionTokenStoreProvider actionTokenStore = session.getProvider(ActionTokenStoreProvider.class);
Thanks in advance.
I've resolved this by maintaining a Table of users and action tokens per flow. This means when the user initiates a new action flow I can grab the previous token if still valid and use the ActionTokenStoreProvider to invalidate it replacing it with the new token. I am still hoping keycloak has some internal mechanism to manage this rather than my own custom code. Drop a solution if you know of this!

Creating a "pre-signed/tokenized" URL which skips the login step (Json Web Tokens)

I'm working on an application where an administrator will send a unique link to a user for them to fill out a form. The system requires authentication in order to fill out a form, however I would like this unique link to "skip" the login step for the user. ie when the user receives the link, they can simply click it and fill out the form without logging in, but behind the scenes the user is actually authenticated with a Json Web token. Ideally I would like the link to never expire, or possibly after 1 year so the user could use the link 6 months down the road and the link will seamlessly still work for the user.
The most obvious solution would be to generate a JWT token with a lengthy expiry when the admin generates the link and just include the token in the url that is sent to the user. When the user receives the link, they already have a JWT token so they don't need to login. However this feels like it may be insecure because now the user has a JWT token for their user with a long expiry sitting in their email inbox.
I think I might be able to include information in the JWT token that would restrict it for that specific purpose (filling out the form), but I'm not even sure if I'm on the right path here.
What is the best way to do this, is there any other recommended ways to create sort of a "pre-signed" url that skips the login step?
I'm using ASP.NET Core as the backend, but I'm not sure if it's relevant as this is more of a general authentication / JWT problem.
doesn't matter what precautions you take, anyone who gets a hold of the email would be authenticated. I would consider PGP (or the like) in sending email to user.

How to reset isVerified email verification feathers js

I have a feathers.js app the also uses vue for the frontend. Also using feather-authentication-management. Using mongodb that creates the isVerified and sets it to false. Trying to find out correct way to change isVerified to true when the user returns with the token.
It's handled when you call a verifySignup call with the token e.g. if you use the verifySignupLong action with the verification code, assuming it's valid and not expired, the verifier will set isVerified to true.
Per the docs (under "Hooks") they don't send the initial sign-up verification request. On an after/create hook you can access the verification code (user.verifyToken) and send it to the user (how you do this is up to you - as part of a link, or as a code they have to paste in, etc.) Then if the user is not verified (isVerified is false) you capture that information, call verifySignupLong with the token, and then see if they are verified.
We build a link that includes the email address and verify token, and send that in an email to the user, which they click and the server unpacks that query string and makes the appropriate call to authManagement.

Can/should IdentityServer4 be used to create a token for user-email verification

I have IdentityServer4 setup for API authentication although I have a use case where I want to verify that a guest (user) is essentially a valid user. A valid user in my case is anyone with a valid email address, so I want to do the following:
send the user an email with a verification token (preferably something which is a mash up of their email address, some salt and an expiry
the user can then enter this token into my app and they are "allowed" to go ahead
I was wondering if IdentityServer4 can/should be used to achieve the above?
Their tools show that you can generate a token although I am very new to this topic so was hoping for some guidance.
No, the tokens Identity Server deals with are access_tokens which are to do with claims-based authentication.
The tokens you need to use for email verification are commonly referred to as User Tokens, or one-time passwords (OTP). You can find a wealth of information on how to generate/consume these using those search terms but if you use the aspnet identity classes such as the UserManager you will find it has some in-built read to use. Or you can register your own UserTokenProvider with the UserManager.
In general you'd do something like this:
Use your UserTokenProvider to get a token (otp) for a specific user. The UserManager will use the security hash of that user and your own 'reason' (e.g. "EmailVerification") to generate the short OTP.
You could then wrap that OTP into an object that includes the email address, a userid maybe, and whatever you like. Safe Base64 encode it (there is a helper function within Identity Server that has this in fact, making sure it doesn't have the superfluous _ at the end which will mess with HTML links), put it in an email to the user
User clicks your link which takes them to your 'verify password' controller, with your mashed up token as payload. You decode it, work out which user it was for, get UserManager to verify the OTP part is still valid.
Job done.
If you want them to enter the OTP into your app directly, while logged in, then you could just skip the whole mash-up part of emailing a link, and email the short OTP directly.

Authentication on Instagram to get the access_token using the API

I'm using the Instagram API and want to get the access_token in order to throw api requests over my own account. When I try to follow the first step and get the authorization code programmatically using RestTemplate I can't get it work.
String AUTHORIZE_URL = "https://api.instagram.com/oauth/authorize/?client_id=<CLIENT_ID>&redirect_uri=<REDIRECT_URI>&response_type=code";
String url = String.format(AUTHORIZE_URL, clientId, redirectUri);
String o = restTemplate.getForObject(url, String.class);
The response is the html code of the login page because Instagram requires the user to be logged in to check if the app is authorized (of course it is, since the app an the user belongs to my own account).
How can I authenticate before throwing that request so they return the code to my redirectUri and not complain about login?
Note: I tried simulating the request to their login form but it returned a 403 Forbidden.
NOTE: I already got a valid access_token, manually generated, and it works perfectly but I want to implement also a process to re-generate a new access_token automatically since they may invalidate it at any time in the future.
Even though our access tokens do not specify an expiration time, your app should handle the case that either the user revokes access, or Instagram expires the token after some period of time. If the token is no longer valid, API responses will contain an “error_type=OAuthAccessTokenError”. In this case you will need to re-authenticate the user to obtain a new valid token.
In other words: do not assume your access_token is valid forever.
Instagram is upgrading their APIs and the flows. Earlier we needed access token to bypass forced login screen. Since yesterday, they have removed that.
Now if you call this code, it will check if you are already logged in or not. If so, it will call the AUTHORIZE_URL of yours and will send a response code. The format will be either:
On success validation - http://your-redirect-uri?code=CODE
On error - http://your-redirect-uri?error=access_denied&error_reason=user_denied&error_description=The+user+denied+your+request
Now what I'm doing is I'm directly calling the above URL of yours every time. Now if the user is logged in, a response code will be sent to you, else user will be asked to login and validate your app and then the code will be sent. Technically, you are eliminating the possibility of the error case! So no need of overhead of storing access token in your database or verifying its validity.
Just try and check now what happens.
PS: If you want to check API behavior, simply type the URL on the browser and check what it returns! It helped me a lot while coding and debugging! :)