How to wrap Plone authentication around a third-party servlet? - python

We're using Plone to serve up some third-party middle-ware.
Unfortunately the middle-ware has a particular servlet that gets invoked from a Java applet and doesn't do any kind of authentication. I would like to firewall this off and somehow wrap authentication around it, preferably using the existing session that users will have on Plone.
My first idea was to configure nginx (which we're using as the reverse proxy) to check the cookie and only proxy if the user has a valid session (along the lines of this example). However, how to check the session ID against Plone, since it's all stored in the Zope database?
Alternatively we could have a Plone python script that basically passes everything along to the back-end after authenticating, but I'm not sure how to do that.
Any suggestions? Or alternative ideas?

Plone uses a auth_tkt session cookie; any system that supports such session cookies and that is configured with the same secret as Plone can validate the cookies.
Unfortunately, I haven't been able to locate a nginx implementation of auth_tkt; the standard originates with the Apache mod_auth_tkt module, so if Apache is an option you could use that. See Plone & CGI single-sign-on using mod_auth_tkt for details on how to configure such a setup.

You can write your own Plone custom add-on which provides a browser view doing the session check for you inside Plone process. How to involve this from Nginx is a mystery for me.
http://collective-docs.readthedocs.org/en/latest/views/browserviews.html
Checking if the authentication credentials are valid
http://collective-docs.readthedocs.org/en/latest/sessions/login.html?highlight=login#extracting-credentials
More about Plone authentication and cookies
http://collective-docs.readthedocs.org/en/latest/sessions/cookies.html?highlight=cookies#default-plone-cookies

Related

How to implement native browser based OpenID Connect authentication in Python?

I am writing a console application in Python, which has to communicate with a network service using OpenID Connect based authentication.
The users of the tool usually already are logged in using their favorite browser.
How can I open/ call the native browser from Python in a way, that I can return the access token?
Opening a http server, which gets a request via redirect URI does not work due to the configured personal firewall for most of the users by IT.
The webbrowser.open seems to provide no way to return data.
https://learn.microsoft.com/en-us/windows/uwp/security/web-authentication-broker seems to be no working solution for my kind of application, due to not being a Windows application registered in the Microsoft Store, but an in-house tool.
You may assume that all users use recent Windows clients.
A console app uses desktop OAuth according to RFC8252 and these are the login return options from a browser:
Loopback
Private URI scheme
The latter may work for your use case, where the redirect URI has this form. The scheme is registered for the current user and this does not require admin privileges:
x-mycompany-myapp:/callback
You can run my Desktop Code Sample to see how this looks. You can test whether this works for users via a web page like this.
I'm no expert on Python but there are Python online tutorials available on this topic.

How do you make a Redirect URI for a Slack App?

I'm trying to create a Slack App (see here), but I'm having incredible difficulty with how to create a Redirect URI.
Slack states the following:
You must specify at least one redirect URL for OAuth to work. If you
pass a URL in an OAuth request, it must (at least partially) match one
of the URLs you enter here. Learn more
I have a rudimentary understanding of a Redirect URI conceptually, but I have no idea how to go about actually getting this Redirect URI that Slack requires.
I've successfully used all of Slacks Integrations with Python including Real Time Messaging, but setting up a Redirect URI seems to require a special server or a website.
As already mentioned in the comments you will need a publicly reachable webserver to host your script for installing the Slack app. So the redirect URL is the URL to your installation script.
Basically any webserver or script hosting service that runs your favorite script flavor (e.g. PHP or Python) will work. See also this answer on how the OAUTH process can be implemented.
The redirect URL works without SSL, but for security reasons SSL is strongly recommended. Also many other features of Slack requires you to run SSL on your webserver (e.g. Interactive Buttons)
Another option is to run a webserver on your local machine (e.g. WAMP for windows) and open it to the Internet through a secure tunnel (e.g. ngrok). For developing and testing this is actually the better alternative, since you can test and fix your Slack app locally without having to deploy every change on a public server.
However for running a public Slack app (e.g. one that is listed on the Slack App Directory) I would strongly recommend to put the production version of your App on a public webserver.
If you're just trying to get it up so that you can authorize another workspace you can always use 'http://localhost' after authorizing it will try to redirect you there and you wont be able to see anything useful, but the authorization should still have taken place I believe.
of course if you're looking for the api code, you will have to pull it directly from the browser url. ... it's very manual.

Where to store web authentication session in PySide?

I'm building a little application in Python. I use PySide for the GUI and Django to read data from my web application.
Everything works well, but I have a login access, like dropbox application.
I want to store this informations on the current machine (like a session, I don't want to login every time I open the application).
Now my question is, what is the safest way to do this? Environment variables?
Usually when you have an API that you're exposing in your app to the outer world (even your own desktop/mobile app), you'll design this API to be stateless, as part of the REST architecture. So your app should always include an HTTP header or any other method of carrying an authentication token that will let your API identify the user.
You only log in once, and when the log-in procedure is successful you should get an authentication token from your API, and then you will store this token somewhere safe.
You can also look into implementing OAuth2 for the authentication.

maintaining user authentication if i have some web pages on mod_python and some on mod_wsgi

I have a web application written in raw python and hosted on apache using mod_python. I am building another web application which is django based and will be hosted on same server using mod_wsgi.
Now, the scenerio is such that user will login from the web page which is using mod_python and a link will send him to my application which will be using mod_wsgi. My question is how can I maintain session? I need the same authentication to work for my application.
Thanks in advance.
If you're using django with mod_wsgi and a raw python page which only serve a link to django application, you don't need to maintain session on both page. When user click on first link and reach the django application, just check session there.
Django have session_db which use memcache. More information can be found here:
Django Sessions
SSO across web applications is poorly supported. One thing you can look at is:
http://www.openfusion.com.au/labs/mod_auth_tkt/
What you can do is really going to depend though on what authentication database you are currently using in the mod_python application and how you are remembering that someone is logged in. If you can provide that information, may be able to suggest other things.
Conceptually: store a cookie using your raw python web page that you process in a "welcome" view or custom middleware class in Django, and insert them into the sessions db. This is basically what hungnv suggests.
The most ridiculous way to do this would be to figure out how Django deals with sessions and session cookies, insert the correct row into Django's session database from your raw python app, and then custom-set the session cookie using Django's auth functions.

WSGI/Django: pass username back to Apache for access log

My Django app, deployed in mod_wsgi under Apache using Django's standard WSGIHandler, authenticates users via form login on the Django side. So to Apache, the user is anonymous. This makes the Apache access log less useful.
Is there a way to pass the username back through the WSGI wrapper to Apache after handling the request, so that it appears in the Apache access log?
(Versions: Django 1.1.1, mod_wsgi 2.5, Apache 2.2.9)
You can only do it if using embedded mode and only if you use a separate package called apswigpy, which provides a Python binding for original Apache request object. The mod_wsgi package provides an optional mechanism for allowing original Apache request object to be passed as Python CObject reference in WSGI environment. You use that in conjunction with apswigpy something like:
from apache.httpd import request_rec
r = request_rec(environ['apache.request_rec'])
r.user = user
At least I think that will setup the appropriate information which access logging can then use.
You should really take this discussion over to the mod_wsgi mailing list.
You could use mod_auth_tkt. An auth_tkt is a signed cookie with the user id that Apache can understand. Your web application would have to set the cookie when the user logs in and out. Apache can derive a REMOTE_USER from the cookie, pass it to your web app or a non-Django web application running on the same server, include it in logs, whatever.
This probably isn't what you're expecting, but you could use the username in your URL scheme. That way the user will be in the path section of your apache logs.
You'd need to modify your authentication so that auth-required responses are obvious in the apache logs, otherwise when viewing the logs you may attribute unauthenticated requests to authenticated users. E.g. return a temporary redirect to the login page if the request isn't authenticated.
Correct me if I'm wrong, but what's stopping you from creating some custom middleware that sets a cookie equal to the display name of the current user logged in. This middleware will run on every view, so even though technically the user could spoof his username to display whatever he wants it to display, it'll just be reset anyway and it's not like its a security risk because the username itself is just for log purposes, not at all related to the actual user logged in. This seems like a simple enough solution, and then Apache log can access cookies so that gives you easiest access. I know some people wouldn't like the idea of a given user spoofing his own username, but i think this is the most trivial solution that gets the job done. Especially, in my case, when it's an iPhone app and the user doesn't have any direct access to a javascript console or the cookies itself.
for latest (Django 2.x, Apache 2.4) Tested
source https://www.django-rest-framework.org/api-guide/authentication/#apache-mod_wsgi-specific-configuration
you need to add WSGIPassAuthorization on in either server config, virtual host, directory or .htaccess

Categories