Hello!
We are using the latest all in one docker setup and it’s working fine.
I’m just wondering regarding login. Is there a possibility to be able to let users authenticate against Microsoft Entra (aka Azure AD) some way?
I read somewhere that SAML is possible (but i dont find a documentation/howto). It would be great to have a Tutorial like this ones that covers the topic regarding specify7:
Hi @dfernandez ,
At this time, we only support identity providers (IdPs) that have an OpenID endpoints.
Specify 7.7 includes Single Sign-On (SSO) integrates Specify 7 with a campus or institutional identity providers. It supports all identity providers (IdPs) that have an OpenID endpoints.
SSO reduces the number of attack surfaces because users only log in once each day and only use one set of credentials. Reducing login to one set of credentials improves institutional security. When users have to use separate passwords for each app, they usually don’t.
For the most up-to-date SSO documentation,…
It looks like Azure AD provides an OpenID Connect endpoint that you can use to authenticate users and obtain identity information.
If you need help getting this configured in Specify, just let me know!
Hello @Specify ! Thank you for your reply
In fact, yes. How to configure this (so adding a idP) this mentioned specify_settings.py in Docker compose or elswhere? I dont find any information about this part. I’m using the “all-in-one” docker template.
Hi Dfernandez –
Thanks for your follow-up. Grant and our back end developer are both out this week, they may chirp in here, but likely it will be next week before we can try to help. Thanks for your patience.
Jim Beach.
Hey, you’ll need to override the settings file with the SSO information.
Here is an example from our GitHub repository https://github.com/specify/specify7/blob/34301626534618aeb4c9e831a12ca87f1eab4f88/specifyweb/settings/specify_settings.py#L90
Here is an example nmbe_settings.py file:
import os
DATABASE_NAME = os.environ['DATABASE_NAME']
DATABASE_HOST = os.environ['DATABASE_HOST']
DATABASE_PORT = os.environ.get('DATABASE_PORT', '')
MASTER_NAME = os.environ['MASTER_NAME']
MASTER_PASSWORD = os.environ['MASTER_PASSWORD']
DEPOSITORY_DIR = '/volumes/static-files/depository'
REPORT_RUNNER_HOST = os.getenv('REPORT_RUNNER_HOST', '')
REPORT_RUNNER_PORT = os.getenv('REPORT_RUNNER_PORT', '')
WEB_ATTACHMENT_URL = os.getenv('ASSET_SERVER_URL', None)
WEB_ATTACHMENT_KEY = os.getenv('ASSET_SERVER_KEY', None)
WEB_ATTACHMENT_COLLECTION = os.getenv('ASSET_SERVER_COLLECTION', None)
CELERY_BROKER_URL = os.getenv('CELERY_BROKER_URL', None)
CELERY_RESULT_BACKEND = os.getenv('CELERY_RESULT_BACKEND', None)
CELERY_TASK_DEFAULT_QUEUE = os.getenv('CELERY_TASK_QUEUE', DATABASE_NAME)
ANONYMOUS_USER = os.getenv('ANONYMOUS_USER', None)
OAUTH_LOGIN_PROVIDERS = {
'nmbe': {
'title': " NMBE",
'config': " https://login.microsoftonline.com/8605a91a-efbc-4eb5-84c9-0aed78380fa6/v2.0",
'scope': "openid email",
'client_id': "your-client-id",
'client_secret': "your-client-secret",
},
}
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
In you docker-compose.yml file, add this settings file in the volumes section so that it overwrites the local_settings.py file:
...
specify7:
restart: unless-stopped
image: specifyconsortium/specify7-service:v7
init: true
volumes:
- "specify6:/opt/Specify:ro"
- "static-files:/volumes/static-files"
- "nmbe_settings.py:/opt/specify7/settings/local_specify_settings.py:ro"
...
Hi @alec.white !
Thank you for this instruction/example. Im almost there. At login im getting an error now:
Blockquote
The redirect URI ‘http://myurl.mydomain.ch/accounts/oic_callback/ ’ specified in the request does not match the redirect URIs configured for the application ‘d008201f-ec04-46cb-873a-de5662b509da’. Make sure the redirect URI sent in the request matches
I configured the callbackurl as https://myurl.mydomain.ch/accounts/oic_callback/ (with https)
I call https://myurl.mydomain.ch for login in with the browser
Do im missing something? This piece here:
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
needs to be there or in nginx-config?
Just a little follow up. Specify does not send https as redirect uri in the oauth request atm:
So maybe i have something missing somewhere in the configuration.
Hi @alec.white , is there maybe a way to allow to configure/ovveride/force the redirect_uri protocol in the provider configuration? If im right, the composition of the callback_uri happens here: specify7/specifyweb/accounts/views.py at 0a47efcd66919958dad31e46bebdbc31b2ff436e · specify/specify7 · GitHub
OAUTH_LOGIN_PROVIDERS = {
'nmbe': {
'title': " NMBE",
'config': " https://login.microsoftonline.com/8605a91a-efbc-4eb5-84c9-0aed78380fa6/v2.0",
'scope': "openid email",
'client_id': "your-client-id",
'client_secret': "your-client-secret",
'callback_uri_proto': "https", #something like this?
},
}
I dont see a way to fix that otherwise. As mentioned
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
this does nothing in my case
Hey, I was able to look into the problem with the redirect_url not using https. I made a code change on a branch named sso-https
. I hoping that will work for you. If you are using docker, pull this image specifyconsortium/specify7-service:sso-https
. Try it with and without SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
in your config. Let me know if this fixes your issue and I’ll make sure to add the code to the next release.
Hello @alec.white !
Sorry for the late reply, i tested this branch and now i can confirm that i works (somehow). No matter if i add or not the
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
part. The callback uri is now with https. When i come back from microsoft online, i get following error:
{"exception": "KeyError", "message": "id_token", "data": "None", "traceback": "Traceback (most recent call last):\n File \"/opt/specify7/ve/lib/python3.8/site-packages/django/core/handlers/base.py\", line 181, in _get_response\n response = wrapped_callback(request, *callback_args, **callback_kwargs)\n File \"/opt/specify7/ve/lib/python3.8/site-packages/django/views/decorators/http.py\", line 40, in inner\n return func(request, *args, **kwargs)\n File \"/opt/specify7/specifyweb/accounts/views.py\", line 183, in oic_callback\n id_token = get_token.json()['id_token']\nKeyError: 'id_token'\n"}
It could be because the user is not existent in specify somehow yet? do i need to setup first in specify? I followed the guide here:
created a user withou password and send invitation link. Results in same error mentioned.
I believe that issue comes when your OAuth provider’s authorized redirect URIs are not setup to allow redirects to Specify. When I did a test setup with Google’s OAuth service, I needed to add https://sp7test.specifycloud.org/auth/complete/google-oauth2/
to the list of Authorized redirect URIs. Let me know if that doesn’t solve your problem. For you the redirect should be something like https://nmbe.specifycloud.org/auth/complete/azure-oauth2/
Well, the redirect uri i defined as https://www.mydomain.ch/accounts/oic_callback/ - then i get the mentioned error
if i call directly https://www.mydomain.ch/auth/complete/azure-oauth2/ i get a 404 … is there documented somewhere what the possible urls could be?
If i take a look here:
from django.urls import path
from specifyweb.permissions.permissions import skip_collection_access_check
from . import views
urlpatterns = [
# Login with Specify username and password:
path('legacy_login/', auth_views.LoginView.as_view(template_name='login.html')),
# OpenId Connect callback endpoint:
path('oic_callback/', views.oic_callback),
path(
'logout/',
skip_collection_access_check(auth_views.LogoutView.as_view(next_page='/accounts/login/'))
),
path(
'password_change/',
skip_collection_access_check(
auth_views.PasswordChangeView.as_view(
the https://www.mydomain.ch/accounts/oic_callback/ is the only that makes sense.
if i go to this endpoint: https://www.mydomain.ch/accounts/oic_providers/
i get back
in the logs i see following unspecific error:
2024-02-05T15:15:30.562964260Z [05/Feb/2024 15:15:30] [ERROR] [django.request:224] Internal Server Error: /accounts/oic_callback/
Could you run specify in debug mode so we could get more info?
In .env file, set SP7_DEBUG=true