Skip to content
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

Logging out the client from the identity provider #3104

Open
mgreiner79 opened this issue May 30, 2022 · 1 comment
Open

Logging out the client from the identity provider #3104

mgreiner79 opened this issue May 30, 2022 · 1 comment

Comments

@mgreiner79
Copy link

Question:

What is the recommended way of logging a user out from the identity provider using the allauth library?

Background

  • The project uses allauth for social authentication.
  • KeyCloak is the identity provider.
  • Keycloak uses the OpenID protocol
  • When using allauth with KeyCloak, KEYCLOAK_URL and KEYCLOAK_REALM are defined in the settings.py file.
  • To log in, allauth takes care of building the redirect url, something like https://{KEYCLOAK_URL}/auth/realms/{KEYCLOAK_REALM}/protocol/openid-connect/auth/?cleint_id=my_cleint&redirect_uri=https%3A%F2%F2my_domain.com
  • All is good. The user logs in and is redirected by to my site.

The problem

  • When the user logs out, they are only logged out of the django site, not at the identity provider
  • This means that when the next user (using the same browser) tries to log in, they are re-directed to the ID provider, and are automatically authenticated and re-directed back to the django site (because of cookies stored for the ID provider's domain).

What I hope would happen

  • When the user logs out of the django site, they should be redirected to the ID provider's logout url, and the redirected back to my site, by using a url like like https://{KEYCLOAK_URL}/auth/realms/{KEYCLOAK_REALM}/protocol/openid-connect/logout/?cleint_id=my_cleint&redirect_uri=https%3A%F2%F2my_domain.com (note the 'logout' path in the url)
  • This would cancel the users current session on the identity provider and require the next user to log in again.

How I have made it work

  • I have modified the allauth logout view and overwritten the get_redirect_url method in order to build the desired logout url
  • The problem is that, if the more than one authentication protocol were being used, my logout view would break.
  • My solution is rather hacky, and I am sure there is a better way, if one knows the allauth source code well enough.
@jharmon96
Copy link

jharmon96 commented Jun 8, 2022

Not sure how similar my solution is to yours, but just in case here is what I have done:

from allauth.socialaccount.models import SocialAccount, SocialToken, SocialApp
from allauth.account.adapter import DefaultAccountAdapter
from django.contrib.auth import logout as auth_logout
from django.conf import settings
import requests

class MyAccountAdapter(DefaultAccountAdapter):

    def get_logout_redirect_url(self, request):
        if request.user.is_authenticated:
            user = request.user
            if SocialToken.objects.filter(account__user=user).exists():
                social = SocialToken.objects.get(account__user=user)
                access_token=social.token
                refresh_token=social.token_secret
                social_app = SocialApp.objects.get(id=1)
                logout_request_data={"client_id": social_app.client_id, "refresh_token": refresh_token, "client_secret": social_app.secret}
                headers={"Authorization" : "Bearer "+access_token,"Content-Type" : "application/x-www-form-urlencoded"}
                result=requests.post(settings.ACCOUNT_LOGOUT_REDIRECT_URL,data=logout_request_data,headers=headers)
        auth_logout(request)
        return '/'

In my case there is only one oidc provider, so there's a bit of hardcoding. If you know the logout route of each provider enabled in your app you can improve this accordingly.

What it's doing is logging the user out of the oidc provider, if applicable, and then using auth_logout to logout from the app itself.

The return value, /, is the route to redirect to after logout.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants