intelowlproject / IntelOwl

IntelOwl: manage your Threat Intelligence at scale
https://intelowlproject.github.io
GNU Affero General Public License v3.0
3.2k stars 400 forks source link

Add support for external authentication methods (LDAP, GSuite, ...) #121

Closed mlodic closed 1 year ago

mlodic commented 4 years ago

We should add support for some common authentication methods that could be leveraged to avoid the pain to create and manage new users directly in IntelOwl.

cvdsouza commented 3 years ago

Google OAuth2 :)

Rishabh-Kumar-07 commented 3 years ago

Hi! I was exploring the ways to authenticate through GSuite. OAuth2 appears to be a popular method to do so. Is there some specific case for which SAML is required or any of the method is fine ??

mlodic commented 3 years ago

We can work on OAuth2 that it is easier to test and manage I guess.

However we should keep in mind that we need the administrator to be able to apply a safelist/blocklist based on specific domains/emails, to keep control of which people can login or not.

mlodic commented 3 years ago

This is something of really high priority. WE are looking for people who are willing to work on that :)

eshaan7 commented 3 years ago

https://github.com/RealmTeam/django-rest-framework-social-oauth2 This package should solve all our requirements. (List of supported auth backends) .

We wouldn't need to do any heavy lifting ourselves. We can just provide a configuration/oauth_settings.py file that is to be configured by an user however they want.

Note: this may involve replacing the current token auth mechanism which wouldn't be so straight forward.

mlodic commented 1 year ago

about the merged PR, I think we should make some minor adjustments:

Could you please @devmrfitz do those minor fixes?

Also, I tried to use that new functionality from a local IntelOwl instance, and, after I logged in with my Google Account with Oauth2 mech I got the following error:

IntegrityError at /api/auth/google-callback

null value in column "user_id" violates not-null constraint

/usr/local/lib/python3.9/site-packages/durin/views.py, line 69, in get_token_obj
token = AuthToken.objects.get(user=request.user, client=client)

Does it work on your side?

drosetti commented 1 year ago

Does it work on your side?

To solve this problem is needed to create the account before login with Google.

Here two possible scenarios:

@devmrfitz I thought about the login mechanism and we should improve it allowing the users to login without a previous registration: in this way it will be more usable. We set up in the env the app id, in this way Google manages the allowed/disallowed users, because only people related to the App in the Google platform will be allowed to login in IntelOwl. We will need to create the users in the platform automatically, I suggest to take inspiration by the ldap integration and pay attention on the password selection. Inspecting the users via Django admin I noticed that the users created via ldap has a "No password set" value and not a random strong pwd, I think we should have something like that.

devmrfitz commented 1 year ago
* [ ]   Ouath docs should have been put in the "Authentication options" section.

Alright

* [ ]  I would like to leverage the Google logo instead of the word Google. I'd put it in the header where we have the "Log In" text in the right side so it is clear that this is an alternate way to login, and the user is able to choose it before entering the data in the login form. I would also add a little link to the documentation with a "i" (that stays for "info") at the top right of that button so people understand that they have to do some work before being able to use that feature
  ![image](https://user-images.githubusercontent.com/30625432/184932145-defe2488-80ac-40a5-9f6d-d42e7e908933.png)

Alright

* [ ]  button should be disabled if the environment variables are not set because obviously that option would not work (right now it raises 500 to me)

Hiding the button would require React to "know" the environment variable while rendering the page. But, the users are served with built files and we can't take the decision of hiding the button at compile time.

IntegrityError at /api/auth/google-callback

null value in column "user_id" violates not-null constraint

/usr/local/lib/python3.9/site-packages/durin/views.py, line 69, in get_token_obj
token = AuthToken.objects.get(user=request.user, client=client)

Does it work on your side?

It seems to be working at my end. Lemme re-verify

devmrfitz commented 1 year ago

Does it work on your side?

To solve this problem is needed to create the account before login with Google.

Here two possible scenarios:

* Create a superuser with Django via command line (it can be inserted the username without restrictions, but it's important the email is the same used on Google) -> Login with Google.

* Create a superuser via Django command line -> login in IntelOwl -> django admin -> create an user with the email used on Google -> superuser logout -> Login with Google with the user previously created via Django admin.

Yup. Basically, the user needs to already exist before Google Login can be used.

@devmrfitz I thought about the login mechanism and we should improve it allowing the users to login without a previous registration: in this way it will be more usable.

IntelOwl's current access model is that only pre-authorized people can login. Even in LDAP's case, only pre-authorized user's have their accounts in the LDAP server. However, if we allow account creation through Google OAuth, anyone with a Gmail ID would get access to it.

devmrfitz commented 1 year ago

image @mlodic Does this look good?

mlodic commented 1 year ago

IntelOwl's current access model is that only pre-authorized people can login. Even in LDAP's case, only pre-authorized user's have their accounts in the LDAP server.

LDAP integration does not work like that. If you enable LDAP integration correctly, once you push your credentials in the IntelOwl login page, and your user does not exist yet in the Django DB, the integration would create the user for you with "no password" set, like @drosetti said. First goal of this integration is to facilitate user management. We don't want the admins to create each user manually every time they want to add a new user. This is a pretty boring thing and brings people away from the project. The idea is that admins configure Google Oauth once and then they forget about user management at all.

However, if we allow account creation through Google OAuth, anyone with a Gmail ID would get access to it

That is true only if you configure Google Oauth like that. On the contrary, if you have a company-based Google Account, you can choose to enable access only for users in the domain of your company (example: honeynet.org). Anyway, both cases are 2 possible and legit use cases that, without this integration, are not handled. If there is someone who wants to provide free access to the plaftorm and want the users authenticate themselves automatically, Google Oauth would be great for that.

So, I strongly prefer to have Google Oauth to solve the issue of manual user creation. The alternative to that is to add a Registration page but I honestly think that it is overkill right now if we can just leverage external authentication

@mlodic Does this look good?

imo a lot better and clearer. Can you also add an informative link as mentioned before?

mlodic commented 1 year ago

Hiding the button would require React to "know" the environment variable while rendering the page. But, the users are served with built files and we can't take the decision of hiding the button at compile time.

ok but can we verify that in the backend once the button is clicked? Otherwise right now it would trigger a 500 error. The best thing could be to show a toast with something like "Google Oauth not configured. See documentation on how to configure it"

It seems to be working at my end. Lemme re-verify

It works only if the user was already inserted. In fact the user_id is missing. I think it could be enough to create a new user in Django DB once the authentication scheme is completed.

devmrfitz commented 1 year ago

LDAP integration does not work like that. If you enable LDAP integration correctly, once you push your credentials in the IntelOwl login page, and your user does not exist yet in the Django DB, the integration would create the user for you with "no password" set, like @drosetti said.

Got it. I just meant that only a person who has their account on the LDAP server can connect through it. And only the company's people will have those accounts. However, in Google OAuth, everyone with a Gmail accounts gets access.

On the contrary, if you have a company-based Google Account, you can choose to enable access only for users in the domain of your company (example: honeynet.org).

I don't think that's possible in OAuth. That's a GIS (Google Identity Services) feature.

So, I strongly prefer to have Google Oauth to solve the issue of manual user creation.

Alright

imo a lot better and clearer. Can you also add an informative link as mentioned before?

Sure. Thanks for the UX perspective :)

mlodic commented 1 year ago

Sure. Thanks for the UX perspective :)

thanks to you :)

I don't think that's possible in OAuth. That's a GIS (Google Identity Services) feature.

I said that because today, while trying to create a new GOOGLE_CLIENT_ID and secret, I noticed that Google asked me which of the 2 options I mentioned I would have chosen. I tried only the other one so, as a counter-proof, I'll try also this so practically we can prove that it works as intended. That would be really cool.

I just meant that only a person who has their account on the LDAP server can connect through it. And only the company's people will have those accounts.

Yeah that is true, I was talking about the account on the Django DB instead of the account on the LDAP server.

mlodic commented 1 year ago

for reference: https://support.google.com/cloud/answer/10311615#user-type&zippy=%2Cinternal%2Cexternal

mlodic commented 1 year ago

Ok I just tried it and that works. I set the Oauth type to "Internal" instead of "External" and I correctly logged with my company account certego.net while it did not work with my private gmail account. So yeah, that is really cool.

But yeah, still this appears though

IntegrityError at /api/auth/google-callback

null value in column "user_id" violates not-null constraint

/usr/local/lib/python3.9/site-packages/durin/views.py, line 69, in get_token_obj
token = AuthToken.objects.get(user=request.user, client=client)
devmrfitz commented 1 year ago

Ok I just tried it and that works. I set the Oauth type to "Internal" instead of "External" and I correctly logged with my company account certego.net while it did not work with my private gmail account. So yeah, that is really cool.

Yup, it's quite nice. Didn't know that.

Have allowed account creation through OAuth

mlodic commented 1 year ago

with the addition of Google OAuth2 I say that can finally close this old issue.

devmrfitz commented 1 year ago

with the addition of Google OAuth2 I say that can finally close this old issue.

Oh. Just realized that this was in GSoC 2021 as well