-
-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Third-party authentication support #215
Comments
Request for inputI personally do not have this use-case and I am hesitant to start designing this feature right now, because it is critical that the design is sound and also satisfies diverse requirements. Designing according to what I imagine might be needed will probably result in a sub-optimal design. Therefore I ask that if this feature is of interest to you, please share you use-case in detail, including the desired authentication flow, what systems/API calls are involved etc. Thanks! |
We are using an external identity system, which may be connected to several other corporate identity providers. The login process may even happen at the corporate identity provider. Vendure would only get access to a jwt token, which contains userid (email), groups (roles), and some other info. We would like to use a custom function to validate this token. User management tasks should happen in the external identity system. The following link under "Authentication sequence in XS-UAA" contains a diagram and a description hows this happens: https://blogs.sap.com/2017/11/16/guide-for-user-authentication-and-authorization-in-sap-cloud-platform/ |
@Szbuli Thanks for the feedback. I'd like to dig into this workflow a bit more:
|
|
@Szbuli When the router allows access to the Vendure server, is the JWT in the header as a Bearer token or in a cookie? |
@michaelbromley as a bearer token |
I'm currently looking at the Nest.js passport.js integration. Originally I did use the Passport module with JWT for auth, but I eventually removed it because certain aspects were quite complex for what I needed at the time (see #25). The main advantage I see with using it is that it would then open up Vendure to making use of the many available Strategies designed to work with passport.js. On the other hand I want to be really certain that it solves the problem better than what we already have or could more simply achieve with something like the original proposal. Also the passport integration would impose certain structural patterns which I might not otherwise choose. Another aspect which @Szbuli's use-case highlights is the need to be able to custom authenticate any GraphQL operation, not just the Example:
Therefore, we'd need our custom auth solution to be able to define a function This |
@Szbuli I've been thinking more about this flow and trying to recreate a comparable test case locally using Keycloak:
What I run into so far is that the token is made available to the Admin UI app, but then the Admin UI app makes an initial request to the GraphQL API and has no way of knowing that it should forward the token. Therefore your JWT would not even make it to the GraphQL API and to any custom auth logic. So I then got thinking about if there is another way to solve this just using the existing Vendure plugin capabilities. Something like this:
Does that approach make sense in your case? |
In our case the client always uses a destination to reach the backend. By using the destination, it will contain the necessary token. Is it possible to deploy the admin UI as a separate static html app? You can look here for a hello world using express + passport with XSUAA. The frontend apps are using the approuter to access the backend. The jwt is automatically set when using the approuter destination (after a successful login). |
Just to stir the pot, here are some other observations:
|
@mdagit thank you, those are all really useful points to consider 👍 |
Note to self: consider the pros and cons of integrating with an existing pluggable auth solution such as https://github.com/accounts-js/accounts or passport.js |
If you're still considering this, I'm trying to get AccountsJS Oauth support/examples/docs up to date, and planning on doing the same trying to maintain the typeorm-postgres-transport package. (which recently got fixed by someone else on a github PR merged in release 0.0.27)! I would love to help with this feature/plugin, if you could guide me/help me out on any roadbloacks I might encounter. Let me know what you think Also a big Multi-Factor-Auth refactor is on the works by leo, and I know david has a working Magic Link like implementation. Also OTP is working on the examples. All of this could be a great addition/alternative to the regular ol' email/password login which will probably be a great option for at least 80% of the users of vendure |
I've started a proof-of-concept implementation of the following design and so far have all existing tests passing. Here's an overview of the design and a note on some use-case coverage:
Use-case: default username/password authAs mentioned, this use-case (the current default and only method of auth) is implemented and fully working in the proof-of-concept. Use-case: social loginPrior art: https://github.com/FlushBG/vendure-social-auth Not yet tried this, but here's how it should work (based on the social auth plugin linked above):
Use-case: SSOLet's say we have an existing corporate ID provider and we want our administrators to authenticate using their existing company-wide SSO (single sign-on) identity. This is probably the most complex use-case, since we need to think about how to authenticate into the Admin UI app as well as how to assign the correct Roles to those administrator users. I will explore this more as I work through this design. |
That definitely sounds like a solution to the issue! I will do some research on the SSO part, since I am not sure if any tokens are involved in the active directory authentication process. On the other hand, I would recommend against having an unknown data type, but probably follow some structure that is either an username/password object, or a token object. We could probably check how Passport.js handles the different auth options, since you are able to write your own strategy on top of their base. Maybe the blueprint will be useful. |
@FlushBG yeah I'm not really overjoyed by having an untyped So to enable different types of object as the input we could either:
|
@michaelbromley I remember doing heavy research on the union input types when I was building the plugin, it's a real bummer that they are not supported. What could be done is split the native and external mutations, and have them receive different input types. Not the best solution, especially if we are aiming for a generic authentication mechanism, but pretty type-safe nonetheless! |
Nope, don't want to split into separate mutations for each strategy (though I also did consider that briefly). Another idea would be to have the export class NativeAuthenticationStrategy implements AuthenticationStrategy {
name: 'native';
defineInput(): DocumentNode {
return gql`
input CredentialsInput {
username: String!
password: String!
}
`;
}
// ...
} Then on bootstrap we execute the input AuthenticationInput {
native: CredentialsInput;
}
extend type Mutation {
authenticate(method: AuthenticationMethod!, input: AuthenticationInput): LoginResult
} If we go with this idea, we could even _drop the authenticate(input: {
facebook: { token: "foo" }
}) {
# ...
} We would just have to enforce at run-time that only a single key of the |
Relates to #215. In this commit we are adding a new AuthenticationMethod entity, which stores authentication information for a given auth provider. The default username/password strategy is known as the "Native" strategy. This refactor does not add any new functionality, but sets up support for external auth providers whilst making sure all existing e2e tests pass. BREAKING CHANGE: A new `AuthenticationMethod` entity has been added, with a one-to-many relation to the existing User entities. Several properties that were formerly part of the User entity have now moved to the `AuthenticationMethod` entity. Upgrading with therefore require a careful database migration to ensure that no data is lost. On release, a migration script will be provided for this.
Is your feature request related to a problem? Please describe.
Currently Vendure allows authentication against its own
user
table, using a standard email/password authentication scheme.It is not uncommon for businesses to have existing user authentication systems which they may wish to integrate into Vendure.
examples:
Describe the solution you'd like
Since there are probably many differing workflows to support here, the best solution would be something maximally flexible, such as allowing an async function to be provided in the
VendureConfig.AuthOptions
object which is responsible for handling thelogin
&logout
mutations.Here's a sketch of how it might work:
The text was updated successfully, but these errors were encountered: