netzbegruenung / keycloak-mfa-plugins

Keycloak Authentication Provider implementation to get a 2nd-factor authentication with a OTP/code/token send via SMS
Apache License 2.0
42 stars 9 forks source link

Not able to migrate users and use the SMS (will help to complete future pull request with config guide) #69

Closed tbaragao closed 2 months ago

tbaragao commented 4 months ago

Hey guys, first of all, thanks for keep the implementation and share this repository.

I'm working in a project that needs to replace the current Auth Service for Keycloak with SMS as MFA.

I'm trying to use your plugin, but even watching the Niko Kobler videos and reading the repository README. i'm facing a lot of doubts and problems to implement it.

Thinking on that, i'm forking the repository to update the README with all the instructions to implement it, and help eveyone that needs to have it in their Keycloak.

I'll start adding here some questions and explaining my steps.

Configuration Guide - Part 1

Errors with the configuration above

What i did to fix the settings

More questions with this basic settings

I've noticed that the created user got the following credentials image

I think, that was that allow the user login using the SMS 2FA.

But as mentionated at the very beggining, i'm migrating existent users to the Keycloak using the Keycloak Rest Api.

Tried to add this credential throw the api, and i'm getting this errror: image

How can i add the Mobile-number credential to the migrated users and allow them use the SMS Code flow?

Because if i follow the above steps and don't add the credential, when i trying to login, i'm getting the following error:

2024-03-09 10:48:25 2024-03-09 13:48:25,741 WARN [org.keycloak.services] (executor-thread-358) KC-SERVICES0013: Failed authentication: org.keycloak.authentication.AuthenticationFlowException: authenticator: mobile-number-authenticator 2024-03-09 10:48:25 at org.keycloak.authentication.DefaultAuthenticationFlow.processSingleFlowExecutionModel(DefaultAuthenticationFlow.java:432) 2024-03-09 10:48:25 at org.keycloak.authentication.DefaultAuthenticationFlow.processFlow(DefaultAuthenticationFlow.java:249) 2024-03-09 10:48:25 at org.keycloak.authentication.DefaultAuthenticationFlow.processSingleFlowExecutionModel(DefaultAuthenticationFlow.java:380) 2024-03-09 10:48:25 at org.keycloak.authentication.DefaultAuthenticationFlow.continueAuthenticationAfterSuccessfulAction(DefaultAuthenticationFlow.java:181) 2024-03-09 10:48:25 at org.keycloak.authentication.DefaultAuthenticationFlow.processAction(DefaultAuthenticationFlow.java:157) 2024-03-09 10:48:25 at org.keycloak.authentication.AuthenticationProcessor.authenticationAction(AuthenticationProcessor.java:988) 2024-03-09 10:48:25 at org.keycloak.services.resources.LoginActionsService.processFlow(LoginActionsService.java:362) 2024-03-09 10:48:25 at org.keycloak.services.resources.LoginActionsService.processAuthentication(LoginActionsService.java:333) 2024-03-09 10:48:25 at org.keycloak.services.resources.LoginActionsService.authenticate(LoginActionsService.java:325) 2024-03-09 10:48:25 at org.keycloak.services.resources.LoginActionsService.authenticateForm(LoginActionsService.java:390) 2024-03-09 10:48:25 at org.keycloak.services.resources.LoginActionsService$quarkusrestinvoker$authenticateForm_32b8e198ac3110abd1d5774e83a4cf87858129f4.invoke(Unknown Source) 2024-03-09 10:48:25 at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29) 2024-03-09 10:48:25 at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:141) 2024-03-09 10:48:25 at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:145) 2024-03-09 10:48:25 at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:576) 2024-03-09 10:48:25 at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513) 2024-03-09 10:48:25 at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538) 2024-03-09 10:48:25 at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29) 2024-03-09 10:48:25 at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29) 2024-03-09 10:48:25 at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) 2024-03-09 10:48:25 at java.base/java.lang.Thread.run(Thread.java:840)

Thanks in advanced, I know it's a lot of information, but i really need some help here to implement it.

melegiul commented 3 months ago

I'm not 100% sure. Maybe you could try to pack the SMS-Authenticator into a conditional subflow with condition "user configured - required" to pass that error. Hope that helps.

tbaragao commented 3 months ago

Hey @melegiul, i was able to identify how to set this up. I saw the current main branch is not the last one (that generatted the 23.0.7 jar). Have you some idea when the app-authenticator branch will be merged in the main?

dsputnikk commented 3 months ago

@tbaragao I have the same problem. I have mobile_number as an attribute and the latest jar from this repo. I take the exact same steps but after I put in username/pass I get a "Cannot login, credential setup required." - despite the fact that my user has a mobile_number field present and set.

I tried turning the Phone Validation toggle on as you said, but no luck.

Sure you didn't do anything else to fix it?

dsputnikk commented 3 months ago

@tbaragao in relation to your solution, would this not be easier to migrate your users?: https://github.com/daniel-frak/keycloak-user-migration?tab=readme-ov-file

tbaragao commented 3 months ago

Hey @dsputnikk, i've identified all the steps to have it working and now i'm working on over some guide to do a pull request here. The fact that the steps in the read me right now doesn't explain the steps and the real configuration. For example, fo me, that i'm using the User Profile enabled, i don't need to configure the mobile_number attribute, it's generated automatically.

I'm just wating the response from @melegiul about to close the branch app-authenticator that was that generate the current .jar versions.

dsputnikk commented 3 months ago

Hey @dsputnikk, i've identified all the steps to have it working and now i'm working on over some guide to do a pull request here. The fact that the steps in the read me right now doesn't explain the steps and the real configuration. For example, fo me, that i'm using the User Profile enabled, i don't need to configure the mobile_number attribute, it's generated automatically.

I'm just wating the response from @melegiul about to close the branch app-authenticator that was that generate the current .jar versions.

Would love to hear what you managed to accomplish.

I just got this fork wired up myself and successfully pulling users in via the legacy REST endpoint (which is reaching out to a legacy SQL app for credentials). It appears to work - but I'm a bit confused. On one the docs seem to imply that its just metadata that gets synced across

melegiul commented 3 months ago

Hey @melegiul, i was able to identify how to set this up. I saw the current main branch is not the last one (that generatted the 23.0.7 jar). Have you some idea when the app-authenticator branch will be merged in the main?

Unfortunately I can't say that for sure in the moment. We want some more improvements to be done: https://github.com/netzbegruenung/keycloak-mfa-plugins/pull/63#issuecomment-1816379363

But yes you are right. Latest Keycloak support up to 23 is on this branch at the moment.

svenseeberg commented 3 months ago

We're now working on KC 24 support :+1:

dsputnikk commented 3 months ago

Can't wait

melegiul commented 3 months ago

Hey @dsputnikk, i've identified all the steps to have it working and now i'm working on over some guide to do a pull request here. The fact that the steps in the read me right now doesn't explain the steps and the real configuration. For example, fo me, that i'm using the User Profile enabled, i don't need to configure the mobile_number attribute, it's generated automatically.

I'm just wating the response from @melegiul about to close the branch app-authenticator that was that generate the current .jar versions.

The app-authenticator is now merged into the main branch to better reflect the current state of the project. Sorry for the confusion.

And you are right. mobile_number is not a user attribute, it is a credential, which you can mange (delete, show) like any other credentials here /admin/master/console/#/realm-name/users/user-id/credentials. Changing and creating is not supported for now, but planned in the future.

I have also added some missing parts in the readme to make the setup more clear: https://github.com/netzbegruenung/keycloak-mfa-plugins/commit/e6b54f72fdd2d82425691451e90d931dc5f85460

Of course any pull request for further improvements are welcome anytime.

dsputnikk commented 3 months ago

I have sms configured and OTP app. Users with both have the choice of either/or.

Is there a way to force users without a OTP app setup to also configure the OTP method (like your force 2fa) if they don't have one?

svenseeberg commented 3 months ago

Is there a way to force users without a OTP app setup to also configure the OTP method (like your force 2fa) if they don't have one?

Forcing TOTP specifically is currently not supported, no. Please open a new issue for that. But I don't think that this feature would be highly important for us at least.

svenseeberg commented 3 months ago

@tbaragao is this issue solved for you with KC 24 support? If yes, we can close it.

tbaragao commented 3 months ago

@svenseeberg I'll validate it tomorrow and let you know.

melegiul commented 3 months ago

Is there a way to force users without a OTP app setup to also configure the OTP method (like your force 2fa) if they don't have one?

Forcing TOTP specifically is currently not supported, no. Please open a new issue for that. But I don't think that this feature would be highly important for us at least.

Actually you could try this plugin: https://github.com/netzbegruenung/keycloak-mfa-plugins/tree/main/enforce-mfa

The plugin enforces the users to set up at least one 2FA method. The choices available can be customized by your flow.

image

For example if you have WebAuthn and OTP, the users must choose between one of them if none is enabled.

image

tbaragao commented 2 months ago

@svenseeberg Validate it, and i've got this working. Very soon i'll push an PR with the guide. Thank you so much!

dsputnikk commented 2 months ago

Sorry to reopen ...

I'm still unclear @tbaragao - how did you get mobile-number populated as a credential?

.. or is it possible to have the sms-2fa plugin leverage an attribute instead of a credential? (I have an attribute that contains a mobile number already)