Moodle: Allowing dual authentication for same account (manual and oidc) - oauth-2.0

Iam using Moodle 10+ and I have done a manual enrolment for an user and also try using 0365 integration (oidc ) for the same user. Integration is done successfully and also syncing as expected. Using Active Directory sync user is matched and 0365 record is created successfully.
Now the problem is that it appears that every user can have only one authentication enabled. I wish users can either use manual authentication or Oidc to log in to their account.
Anyone has successfully implemented two authentication for a same account?
It’s throwing error when logged in using oidc for a same user who’s auth field in mdl_usr is set to manual. If I change to oidc he can’t login using manual.
Is there any solution for this?
Thanks in advance

You can only have one authentication method per user.
https://docs.moodle.org/311/en/Authentication_FAQ#Can_a_user_have_more_than_one_authentication_method.3F
With manual authentication, the password is stored in Moodle.
With OAuth2, the password is stored on the remote server.
So you can't mix them.

Related

How to add the notion of "accounts" to Keycloak?

How do I best configure Keycloak so that a user needs to have an account for a client to be able to login into that client?
I have to replace a proprietory SSO-Impl. It deals with users, roles and clients much like Keycloak. However, it also knows about accounts. A user is only allowed to login to a client if he has an account for that client.
In Keycloak, if a user simply exists in a realm he may login to a client of that realm. Nothing else is needed. So no "account" is needed. In the old application, he needs an account as well.
What functionality in Keycloak is best suited to overcome this difference?
I have one idea:
Create a client-role in each client namend "HasAccount" and assign it to users. Then, restrict access if that role is missing.
This is discussed here: "Restrict client access in a single realm with keycloak"
It has at least two drawbacks:
It mixes authentication and authorization in the legacy app. I can understand that. But creating a role was already a workaround. That is why I described my initial problem here.
I have clients in 3+ languages/technologies. Adding functionality there seems like more work than in Keycloak.
Last remark:
Before you ask "This is not single sign on" anymore. It is only for administrative purposes. The admin can allow users to login into a client or not by creating an account or not. The user does not have to login a second time. If he is logged in in App A and has an account for App B, accessing App B works without logging in there.
A user is only allowed to login to a client if he has an account for that client. is really not a task for Identity Provider (IdP). It provides only identity and not authorization.
Of course you can ignore that and implement authorization as well. See: User attribute based web service access control by Keycloak
From the design perspective I would add auth reverse proxy in front of legacy app (but it isn't a best solution for SPA apps). Auth proxy will provide authentication via OIDC protocol and also authorization. Legacy apps may keep own OIDC authentication - it will be seamless auth from the user perspective, because SSO will be used.
Account entity - you can use group entity in the Keycloak instead of original account.

How can i add google OAuth2 to authenticate an angular node application which uses wso2 identity manager as authentication provider?

We are currently working on an Angular node application which uses WSO2 Api Manager and Identity Server . The current mode of login is done through emails which gets saved as WSO2 Carbon users . We need to allow users to login using their google or facebook accounts using OAuth2. I have implemented the code for fetching access token,refresh token on login through google on click of a button from my app . But How can i link it to save this user as a user in our application's identity server . I found the below link which helps in the process: https://docs.wso2.com/display/IS570/Logging+in+to+an+Application+Using+Google#50629d9a6ddf4769ae2d8953c5a25645 .
Can anyone suggest me whether this one would help ?
I would like to know how the google account user details will be saved as a user in our identity manager ?
Is it possible ? If possible, what all data will i get from google ?
I assume that you have already done the configurations for the communication between your application and the WSO2 Identity Server according to the description in the question.
From the description, I'm not certain that you have done the configurations to federate the login to Google. Follow the below steps if you already haven't done so.
Generate OAuth client ID from the google developer console.
Configure a federated authenticator in WSO2 IS with google authenticator using the generated client id and secret values.
Add newly created IDP as an option to the first step of your application.
More information can be found in here. From Google, you can get email and default profile attributes of the user. Reference.
Follow the same steps for Facebook login as well. More information available here.
Now the federated login is configured. Now you need to enable JIT provisioning for the configured Identity Providers above to save the user in the Identity Server when the user is logged in with those social login options. More information available in here. You have a few modes to create the user in the Identity Server.

Is authentication services capable to provide reset password and email verification and store user credentials

My use case is something like this.
I'm developing a rest api and single page web application.
But I don't want to store my user credentials (email, password) with me.
I want to store it in more secure place. From that place I need to verify credentials and issue tokens, as well as first time user register with the system that user's email ID should be verified and also If an user forgot his password there should be a way to reset it as well.
Finally in my node.js back-end I need to protect my routes from unauthorized accesses.
Do I can achieve all this things using a authentication service provider.
I go through the firebase docs and found It is little bit harder to implement my what I want using the firebase.
Is authentication services capable to provide reset password and email verification and store user credentials.
Or it just a token generator only?
If you are asking if Firebase Auth provides the ability to generate tokens for verified email/pass credentials it securely stores with email verification and password reset, the answer is yes. Learn more from their official documentation: https://firebase.google.com/docs/auth/web/password-auth
They also provide the ability to issue session cookies better suited for a Node.js server side managed sessions: https://firebase.google.com/docs/auth/admin/manage-cookies
You don't need to store the credentials. Firebase Auth will store them for you using industry best practices.

SPA App Azure B2C Authentication with MSAL. Keep user logged in

I have a SPA App (VueJS) which uses Azure B2C with MSAL to authenticate users. Authentication works just fine.
But what does not work is, that the user is not kept logged in.
As long as i use the app, everything works just fine. But when i start my app the next day i have to relogin (or just reselect the account I want to use), but I would like to have the same user experience like for example the azure portal. I can revisit the portal after one week and do not have to relogin.
How can i achieve this behavior with MSAL? Is this even possible with this library? The library uses the implicit flow.
Is there another library i can use where this works?
Generally, browser-based applications shouldn't keep users logged in, since activity, such as a password change or reset, at the identity provider can invalidate a persistent session and should force an interactive login.
You should consider the "keep me signed in (KMSI)" capability that has been enabled for custom policies.
Before the answer...
I think you'll likely need to expand on what's happening by looking at a network tracing tool. Also, as the other answer said, KMSI will help but likely isn't the only problem here. I recommend looking if the cookie is being set (check below), your app is successfully getting ID, Access tokens, and check this state in subsequent auth requests.
Basics
SSO with MSAL.js is absolutely possible and should occur without much configuration. For some background in browser-based apps implementing authentication, achieving SSO is a factor of cookies/sessions rather than tokens/token management.
How this works
When your single page app redirects the user to the Azure AD B2C sign in page and the end user successfully signs in, Azure AD will set a cookie in the browser of that end user. Then, when your app wants to get an ID token or Access token for the user (assuming the existing one from the initial sign in is expired), MSAL is able to launch a silent i-frame in the background, redirect to the Azure AD site with special query parameters (prompt=none), and utilize the cookie that was set earlier.

Design for Facebook authentication in an iOS app that also accesses a secured web service

Goal:
Allow a user to authentication with Facebook into an iOS application which requires access to a protected web service that I'm running.
Assumptions:
There is a native authentication (and registration) system in place for those users that opt not to use Facebook for sign in.
Details:
Assume we want to offer the option for a user to sign in with Facebook without creating a separate account/credential for our system.
Because we support our own native auth mechanism (username and password) we have our own user IDs and issue an authentication token that is used for subsequent interactions after the initial credential validation.
I'm surprised that Facebook doesn't have best practices for this in their developer documentation. All the existing documentation is either assuming you are building FB auth into a website, or a standalone mobile app with no service that requires authentication.
Here's my initial thoughts on how this would be designed but want validation on whether it's correct.
Client pops the Facebook iOS Login
UI User signs in with Facebook credentials and gets access token
iOS App passes access token to our server
Our server talks to FB graph API using access token to (a) validate the token and (b) get the FB user ID for that access token.
e.g. Our server would call https://graph.facebook.com/me/?access_token=XYZ which would return profile info in a JSON object
Assuming it's valid, our server extracts the User ID from the JSON object and checks whether the user already has an account. If so, we issue our own auth ticket to client to use for that session. If user doesn't have an account, we create a new one with the Facebook User ID, assign our own unique UserID and issue our auth ticket.
Client then passes auth ticket back on subsequent interactions that need authentication.
This seems like the right approach to me but not sure if I'm missing something insanely basic and going down the wrong (complicated) path.
I just dealt with this myself, and here's the part that bit me:
In your step 5... It's possible for a user to register for an account with you entirely separate from their Facebook ID, right? Then some other time they log in with Facebook.... And you just created them a second account and lost their first one.
There needs to be a way to be logged in to your web service, then log in to facebook, and capture the association between the facebook ID and the local account.
Apart from that, your plan sounds solid.
Update: Facebook has added a doc outlining such a scenario HERE
Use https to transmit the auth token to your server, as stated by Facebook
Sharing of Access Tokens
Our Data Policies explicitly prohibit any sharing of an Access Token
for your app with any other app. However, we do allow developers to
share Tokens between a native implementation and a server
implementation of the same App (ie. using the same App ID) as long as
the transfer takes place using HTTPS.
One problem I can see with this strategy, is that somebody can give you an access token obtained for a different facebook app. As far as I know, there's no way to verify that the access token is for your application, so you'll just go on and use it.
It doesn't sound very harmful, though. Generally people/apps try to protect the access tokens, rather than sharing them.
One possible exploit of this would be, for somebody to create their own site or mobile app, obtain access tokens for their users and try to authenticate them, using your API. If this succeeds (the user is has a facebook account in your site), the malicious site will be able to use your API impersonating the user.
It's a bit of a long shot, but I think it could work.
Edit: It looks like there is a way to validate the access token after all. See the answer by #Daaniel on question Get application id from user access token (or verify the source application for a token).
your solution totally works.
Maybe an alternative: why not just get the email on the client from the initial social service request and send to your web service? The web service could just store the email, and maybe a social_provider as well. I understand that your web service will not be able to validate where the email came from, but isn't there a high-trust relationship between your web service and your client? If there is, seems like you can depend on the email coming from the right place. Someone please let me know what obvious thing I'm missing that makes the email-based approach silly...

Resources