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

REST authentication #45

Open
Jiloc opened this issue Sep 5, 2017 · 4 comments
Open

REST authentication #45

Jiloc opened this issue Sep 5, 2017 · 4 comments

Comments

@Jiloc
Copy link

Jiloc commented Sep 5, 2017

Is REST authentication supported or are there any plans to support it?

https://apereo.github.io/cas/5.1.x/installation/Rest-Authentication.html

@manelclos
Copy link
Collaborator

Hi @Jiloc, as stated on the webpage linked:

This documentation describes how to delegate and submit authentication requests to a remote REST endpoint. It has nothing to do with the native CAS REST API ...

So this has nothing to do with the CAS Server itself. I mean, the functionality can be created on its own project. Like I'm using REMOTE_USER to authenticate users, so the users are already authenticated when they reach the CAS Server code. I know this is not delegation, but you can easily write a backend that will do what you want.

Hope this helps!

@Jiloc
Copy link
Author

Jiloc commented Mar 1, 2018

Hi @manelclos,
Thank you for the suggestion! I actually did it by overriding mama_cas_views.LoginView in my own project. Anyway I still think that it would be very useful feature to introduce in this project.

@manelclos
Copy link
Collaborator

@Jiloc are the changes online or can you share them?

@Jiloc
Copy link
Author

Jiloc commented Mar 1, 2018

They are not online, but I will share it here. Anyway I find my adaptation too custom to be used as is.

class LoginRestView(mama_cas_views.LoginView):
    def get_form_kwargs(self):
        """
        Django >= 1.11 supports a request sent to the authenticator
        so we grab that here and pass it along to the form so it can be
        handed off to the authenticators.
        """
        kwargs = super(LoginRestView, self).get_form_kwargs()
        if 'HTTP_AUTHORIZATION' in self.request.META:
            authmeth, auth = self.request.META['HTTP_AUTHORIZATION'].split(' ', 1)
            if authmeth.lower() == 'basic':
                auth = base64.b64decode(auth).decode('utf-8')
                username, password = auth.split(':', 1)
                kwargs['data'] = {
                    'username': username,
                    'password': password
                }
        return kwargs

    def post(self, request, *args, **kwargs):
        return super(LoginRestView, self).post(request, *args, **kwargs)

    @method_decorator(ensure_csrf_cookie)
    def get(self, request, *args, **kwargs):
        """
        (2.1) As a credential requestor, /login accepts three optional
        parameters:
        1. ``service``: the identifier of the application the client is
           accessing. We assume this identifier to be a URL.
        2. ``renew``: requires a client to present credentials
           regardless of any existing single sign-on session.
        3. ``gateway``: causes the client to not be prompted for
           credentials. If a single sign-on session exists the user
           will be logged in and forwarded to the specified service.
           Otherwise, the user remains logged out and is forwarded to
           the specified service.
        """
        form = self.get_form()
        if form.is_valid():
            return self.form_valid(form)
        service = request.GET.get('service')
        renew = to_bool(request.GET.get('renew'))
        gateway = to_bool(request.GET.get('gateway'))
        if renew:
            logger.debug("Renew request received by credential requestor")
        elif gateway and service:
            logger.debug("Gateway request received by credential requestor")
            if is_authenticated(request.user):
                st = ServiceTicket.objects.create_ticket(
                    service=service, user=request.user)
                if self.warn_user():
                    return redirect('cas_warn', params={
                        'service': service, 'ticket': st.ticket})
                return redirect(service, params={'ticket': st.ticket})
            else:
                return redirect(service)
        elif is_authenticated(request.user):
            if service:
                logger.debug(
                    "Service ticket request received by credential requestor")
                st = ServiceTicket.objects.create_ticket(
                    service=service, user=request.user)
                if self.warn_user():
                    return redirect('cas_warn', params={
                        'service': service, 'ticket': st.ticket})
                return redirect(service, params={'ticket': st.ticket})
            else:
                return HttpResponse(
                    json.dumps({'message': 'Ok'}),
                    content_type="application/json")
        res = HttpResponse(status=401)
        res['WWW-Authenticate'] = 'Basic'
        return res

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