`node-oidc-provider` with Email verification - email-verification

I'm creating an OIDC provider with oidc-provider. For now, my Registration flow required email verification step, which is handler outside oidc-provider. This approach works but it leads to an issue that user can not automatically login after setting up their password.
I thinking of creating a new prompt policy name email-verification, something like:
https://<auth-endpoint>?client_id=...&prompt=email-verification
I wonder:
Is this flow acceptable with OpenID Connect specs?
Is there any document, tutorial or example in terms of specs or implementations of this approach?
The case user register in mobile app, but open email link in web (we have a mobile app with different client_id and of course, different redirect_uri. What should we redirect user to the app without error.
Thanks,

Related

How to create single JWT authentication and authorisation server for multiple website and mobile apps in ASP.NET Core

I find setting up the auth services for every website is cumbersome.
This is my scenario: I have currently three websites for example example.com, example.org and example.space and their mobile apps respectively.
I found it's tiring to configure auth for each of them separately. What I want is to create a centralise auth service running on a different port with a different database. For example on example.net:7000.
Whenever users request to be authenticated by sending their email and password to example.com/auth, example.org/auth or maybe just example.net/auth they will receive a JWT token which can be used to access the protected resources on the respective sites or their mobile apps. And it should be without opening any website from the browser in case of the mobile apps.
I mean users shouldn't be aware of this process that their credentials is being handling by a single server. It's kind of like Google where user can login on to gmail.com and also gets logged in to google.com.
I have taken a look to Openiddict but found out that it has some redirections involved (to auth a user, the user is being redirected to the auth server and then send back to the previous url). I want it to be like machine to machine communication with no user interactions involved rather than sending an JSON containing their credential in a simple HTTP POST API request.
How can I achieve this? Is there any example repository.
Note: I am using Flutter for the mobile apps.

RESTful registration with activation email

I'm working on creating a REST API and one feature is to allow users to register. The general flow is the following:
The user specifies his email and password using the client application (SPA application) and presses the submit button.
A request to the API is made. The API adds the user to the database, generates a verification token and sends an email to the user.
The user verifies his email and clicks a confirmation link.
The API marks the user account as verified.
My question is regarding the confirmation link.
Should the link point to the client SPA application? In this case, the client application will make a POST request to the API with the verification token and the user email.
Also, how should the API know the link to the client application (the link needs to be added in the email and this is done by the API). Should the API store this link, or should the SPA client send the verification link to the API when sending the request to register the user?
Another approach would be for the link to go to an endpoint defined by the API. In this case a GET request will be made with the user email and verification token and the API will set the account as verified and inform the user that his account is now active.
I have read that this approach doesn't conform to the REST principles because a GET request should never change the state of a resource. In this case, the user resource will be modified.
I'm not sure which of the 2 solutions is better or if there is a better solution, so my question is what is the best approach?
Thanks!
Should the link point to the client SPA application?
If your 'Client SPA application' is the sole frontend for end-users, then yes: it should point there. Some people deploy a separate oauth2 / authentication server but that doesn't sound like it's the case here.
The client application will make a POST request to the API with the verification token and the user email.
The token should be enough. I'd avoid sending email addresses through urls.
Also, how should the API know the link to the client application (the link needs to be added in the email and this is done by the API). Should the API store this link, or should the SPA client send the verification link to the API when sending the request to register the user?
Both seem like really valid designs. If you want the API to be completely unaware of the front-end and support a multitude of frontends, it would make sense to me that the client sends their own endpoints. There is a security concern though, you don't want arbitrary clients to register arbitrary urls.
If you're just building a single frontend, I don't see a problem with the API knowing the activation url. It also sounds like it would be easy to change if your requirements change later.
I'm not sure which of the 2 solutions is better or if there is a better solution, so my question is what is the best approach?
Ultimately it doesn't really matter that much. Neither approach sounds like you're really painting yourself into a corner. Either you have a standard endpoint that uses a javascript HTTP request to activate a user, or you have a separate endpoint that redirects a user after activation. Both will work.

Why should I use One tap sign in over Chrome's Credential Management API

Am a bit confused about the One tap sign in that was announced by google earlier this year. Our application already users Credential Management API in Chrome, which essentially provides the user with login options based on the credentials that user has saved for our site on previous visit (passwords that are saved in chrome). When I read the documentation for One tap sign in, it promises to do the same thing, but using Google's client api id. Our application has its own ID provider with our own database of user name and passwords, from the documentation it looks like One Tap sign in does not support custom ID providers. Can anyone shed more light on this, why would I use one against the other?
Thanks
Karthik
I see two major differences:
One Tap is passwordless - it uses a token based login that never exposes the user's password. Chrome Credential Management API stores and retrieves actual passwords in Chrome's password store.
One Tap is purely web based - Chrome Credential Management API relies on Chrome's specific implementation. One Tap is a purely web based workflow so it will work across browsers.
One Tap is a much better long term login solution in my opinion. The Credential Management API is experimental and currently only supported in Chrome.
https://developer.mozilla.org/en-US/docs/Web/API/Credential_Management_API#Browser_compatibility
I lead product development at Google for the one-tap/auto sign-in library, we designed it such that the library includes the Credential Management API and extends to provide assistance in account creation, secure passwordless, and cross-browsers support.
In particular, if you make a request for existing credentials with code like this:
googleyolo.retrieve({
supportedAuthMethods: [
"https://accounts.google.com",
"googleyolo://id-and-password"
],
supportedIdTokenProviders: [
{ uri: "https://accounts.google.com", clientId: "CLIENT_ID" }
]
});
then any saved username/passwords from the Credential Management API will be returned (in browsers supporting the API) along with token data for Google Accounts. The one-tap/auto sign-in JavaScript library wraps the Credential Management API for credential retrieval.
Furthermore, the library provides a googleyolo.hint method to show an email selector for one-tap selection of a verified email address to assist in new account creation, or to link to an existing account, and then be auto signed-in next time with token instead of password, across all browsers, so long as the same Google Account is active.
I'd suggest using the one-tap/auto sign-in library and consuming tokens as well as passwords in order to get assisted sign-up, keep existing users signed-in automatically, and provide functionality even if the browser does not support the Credential Management API.
As for the question about using your own database of username / password, the hope with this library is you could implement the ability to create accounts and auto sign-in to these and existing accounts with an OpenID Connect ID tokens representing the user's identity. With the one-tap / auto sign-in UX, these are not only much more usable, but far more secure then passwords and mitigate creation of weak/re-used passwords. Please consider this or, even better, a hosted auth solution like Firebase Auth or Auth0 and include the one-tap UX in the frontend UI.

Using the Ionic Auth Service and my custom API

Many mobile apps require user login. That's why Ionic launched their Auth service (https://docs.ionic.io/services/auth/). I can create users via the Auth service itself or via the Ionic API. I also can save custom data for each user. Very nice is also that I can sen targeted push notifications to my users. Seems like a nice out-of-the-box solution.
But most of the time apps have more complex logic (user can post something, user can order something, make a payment, ...). The simple user with some atributes from Ionic does not help much in those cases.
So I need to authorize the users not only inside the app but also against some custom API. And this is where my questions come up...what's the best way to do this?
Some things that came to my mind:
When creating the user in Ionic, also create the same user with the same email and password in my API. So I can make authorized requests. But this does not user any token and I would have to pass my password in every request, also I am worried about data consistency. What if the user changes its password?
Use the internal Ionic user ID, create one global token and use user ID and global token to authenticate the user in my API. But is this secure?
Another worry in my mind: If I save user name, email etc in the Ionic Auth system I would have to access it via their API every time I need it in my own system. For example: A user orders a product in the app. Then my system needs to send out a confirmation to the user. I would have to access the Ionic API to know that users email...and so own.
I think this is all confusing.
Is Ionic Auth not made for those situation? Then, I don't see what it's made for at all...
Is ionic Auth just not there yet...?
Am I just not getting it?

Identity Server 3 - Silent sign-in / sign in without login page. Including single sign on

I have come across a number of articles that discuss a similar matter but I cannot find a definitive answer.
My company would like to begin using Identity Server 3, however one of the requirements is to be able to authenticate an external user without them having to manually enter their credentials.
This must be capable of providing single sign on capabilities also as we have 3 different systems and our users should only have to sign in once.
Essentially, the external user has their own CRM.
The CRM holds their username and password for our software.
They then click a button in their CRM to launch our application
This redirects them to our website with a payload containing their credentials
We call a web service to authenticate the user
It is fundamental that we do not change this process for our partners.
Can I implement a custom service provider to provide the authentication or is there some other way of achieving this? If so, could you point me in the right direction for how this can be done?
Many thanks
Craig
I would assume that you'd create a mechanism for their CRM to get a token at the time the client logs into their site and then have them send that token via url to your callback page. This would use the machine-to-machine type grant, or the client-credentials flow. Then that page could validate the token and log the user in. There would have to be some sort of unique identifier between the two systems like email or something. Just an idea.