Integrate Django authentication with Enterprise Identity Provider PingFederate - python

We developed web apps in django framework. We have an enterprise Identity Provider which is PingFederate. The main home page (which is different from our site) from chrome browser and edge browser directly recognizes the user and logs them in all the internal websites. We are also on the same network share same domain. We also want to integrate SSO and want to authenticate our users directly with asking password. I researched every where and got to know the authentication is happening by kerbose authentication. Somehow the edge or chrome is sending some token or id or some TGT ticket to the Identity Provider then they will authenticate and send the username back to the client browser. Can any one please help me how to solve this.
Thanks in advance.

I solved this problem and wrote an article about it. Please feel free to see that article.
https://medium.com/#manishkumar.bobbili3/how-i-integrated-ping-identity-with-django-web-framework-for-single-sign-on-sso-9be21b953bc5

It sounds like you want to integrate with the PingFederate solution to use it as the identity provider and allow the users of your web apps to login through SSO. If that is the case, you would need to work with whoever responsible for PingFedereate if it is another team.
Checklist with the PingFederate Admin
You would need to know if you need to choose the directory will be used to log the users in.
Which user attributes you would need to get back in the SAML response.
Will you sign the SAML request using your app or not.
Will you start the SSO cycle from your app, which I believe you would, and you will be using SP initiated in this case.
Otherwise, it will be the other way around and will be using IDP Initiated.
SP Initiated - User will call the app URL first and then redirected
to Ping URL and be sent back to the app.
IDP Initiated - User will call PingFederate URL and will be sent to the app after authentication.
I will list the steps in here in case it is your team who is also responsible for PingFederate solution:
Changes in PingFederate as SP (service provider) connection
Create a new IDP (Identity Provider) Adapter for the login page if needed.
IDP adapter will be using a Password Credential Validator to do the authentication and also has the configuration for which HTML pages to present to the user.
Create the SP connection in Ping with the stuff in the check list.
The connection here will use the adapter in the step above to present the login page
Then check the user credentials and establish the SSO session if successful.
Assemble the SAML response with all the required attributes.
Sign the response and send it to the application endpoint configured inside the connection.
Changes in the web app as the service provider for the user
The application will need to send the SAML request to the endpoint of the new connection in Ping.
Wait for the response on the dedicated endpoint.
Verify the SAML response signature using the PingFederate server's public key.
Create the local app session and move on.
If you will be using OpenToken, this will change to have another interaction of Adapter-to-Adapter. Just reply with that if this is the case.

Related

Best way to log a user out of several, owned websites?

I have several apps that connect to a central OAuth2 server (this is the only login method). When a user hits Log out, I want him to be logged out of all the apps and the OAuth server.
All the apps are Django at the moment but that might change, so I'm looking for the most cross-framework way to do it. I must also keep in mind that all the apps might handle sessions differently (some server-side, some client-side).
All logouts must be handled by POST requests as the good practice recommends.
The strategy I have in mind:
On the app, the user clicks on Log out
This Log out link points towards the logout page on the OAuth server, on which a POST request to /logout is issued immediately (or after a countdown).
The session is killed on the OAuth server and the user is logged out of it.
A ?next=... parameter redirects the user back to app A.
The app pulls the user status from OAuth server (server- or client-side) : if logged out from the OAuth server, then logout from the app also.
New apps would just have to implement this pulling mecanism along with the logout link pointing towards the OAuth server logout page, so there's nothing to configure in the OAuth server for new apps.
Do I miss something?
you may want to follow this draft, https://openid.net/specs/openid-connect-session-1_0.html

External login with Oauth2

I'm working on a Django application with users through Django's auth, on the other side there is an Oauth2.0 server that already has all users and their permissions registered. My goal now is to integrate the Django app with the Oauth2.0 server so we won't have to administrate the users ourselves. This would make it so the when the users want to log into our app they are redirected to the Oauth2.0 login site and then redirected to the home of our app once they login successfully.
I think I understand how Oauth2.0 works but I have a couple of questions I couldn't find anywhere else.
Is the scenario I'm describing possible? As in the users would no longer have to be registered in our app and a 3rd party Auth server would provide access to our app or not.
Once I get the access token after the user login where is it safe to keep the access token? I was thinking I could save to AT as a session variable so as to keep the end user's session linked to his account which is external to our Django app.
Every time the user makes a request I would check the AT I'm keeping, if the verification is OK our app responds with the view, otherwise the user is redirected to the login. Is this flow correct or am I not understanding how this integration would work?
What would happen in the case the user is given more permissions but I hold an old token? How do I handle these cases?
I would suggest using a third-party application, like django-allauth. You can simply disable creating local accounts, and enable a single custom social provider that interacts with your OAuth2.0 authorization server.
As noted here, the process of creating your own custom OAuth provider isn't documented, but shouldn't be too difficult.
Once I get the access token after the user login where is it safe to keep the access token?
Allauth will store the access token in the database. If you want to put it in the session too, you can, but there's no point unless you want the client to make requests to the resource server directly.
Every time the user makes a request I would check the AT I'm keeping, if the verification is OK our app responds with the view, otherwise the user is redirected to the login. Is this flow correct or am I not understanding how this integration would work?
That's fine. If your authorization server has no way to invalidate issued access tokens, though, you can just assume that the access token is good up until the expiration date.
What would happen in the case the user is given more permissions but I hold an old token? How do I handle these cases?
Just use the access token normally. If the resource server indicates that it's invalid, prompt the user to log in again. You will get a new access token for that user that reflects their current permissions.

Django rest Framework : encrypt response data

I am using Django rest Framework to build a REST API for one of my clients. The app provides some sensitive information such as passwords when the client asks for it through an API call.
Now, only authorized clients can access to the app and besides that, only authorized IP can connect.
But what if someone was listening in the middle of that connection ? He would see all the datas in clear.
Is there a way to encrypt those info, maybe with a password, and then decrypt it when it arrives ? (the client would have to update his app, but it's not a problem).
I was thinking maybe to create an "EncryptedResponse" instead of "Response" in my django app.
Thanks
If you don't have one already, purchase an SSL certificate and configure your site to load the API over HTTPS. That way the connection between the authorized client and your application would be encrypted which will prevent a man in the middle attack that you're describing.
If you're not going to load the API over HTTPS, then the authentication token, or API key, or whatever you're using to authenticate the client can also be intercepted.
However, if you're looking to stick to the encrypting the data route, I've found this guide that looks like it should help you be able do what you need to do:
http://gpiot.com/blog/encrypted-fields-pythondjango-keyczar/

API registration and authentication service

I'm working on an API registration and authentication service application using python. Developers will be able to register their application (domain name of the application) and a random API key will be generated for the registered application.
Next, the registered application will send the API key to the API service with each API request. API server will authenticate the domain of the incoming request with the passed API key to confirm that the request is valid. I'm using Forwarded Host to validated the domain name of the API request, however it doesn't work as in some cases (when the opened page is the first page), Forward Host comes blank.
Are there a better approach to authenticate the request or any changes required in the API registration process to reliably authenticate the request? Some pointers will be helpful.
Using Authorization proxy
Samples are "3scale.net", offering free tier, other commercial solutions exist too.
Open source solution I am aware of is ApiAxle, which is much simpler, but still very useful.
The proxy takes care of managing access keys and forwards request back to real application only in case, it is really to be served.
Using Authorization service
Another solution is to have some internal service evaluating set of client provided keys (providerid, appid, accesskey, ...) are authrized or not. For this purpose, you have to:
set up authorization service
modify your code by adding 2-3 lines at the top of each call calling the authentication service.
Sample code for 3scale is here: https://github.com/3scale/3scale_ws_api_for_python
Conclusions
Authentication proxy makes the application simple and not bothering about who is asking. This can be advantage until your application needs to know who is asking.
Authentication service requires changing your code.

Multiple backend servers accessible from a Flask server

I want to have a front-end server where my clients can connect, and depending on the client, be redirected (transparently) to another Flask application that will handle the specific client needs (eg. there can be different applications).
I also want to be able to add / remove / restart those backend clients whenever I want without killing the main server for the other clients.
I'd like the clients to:
not detect that there are other servers in the backend (the URL should be the same host)
not have to reenter their credentials when they are redirected to the other process
What would be the best approach?
The front-end server that you describe is essentially what is known as a reverse proxy.
The reverse proxy receives requests from clients and forwards them to a second line of internal servers that clients cannot reach directly. Typically the decision of which internal server to forward a request to is made based on some aspect of the request URL. For example, you can assign a different sub-domain to each internal application.
After the reverse proxy receives a response from the internal server it forwards it on to the client as if it was its own response. The existence of internal servers is not revealed to the client.
Solving authentication is simple, as long as all your internal servers share the same authentication mechanism and user database. Each request will come with authentication information. This could for example be a session cookie that was set by the login request, direct user credentials or some type of authentication token. In all cases you can validate logins in the same way in all your applications.
Nginx is a popular web server that works well as a reverse proxy.
Sounds like you want a single sign-on setup for a collection of service endpoints with a single entry point.
I would consider deploying all my services as Flask applications with no knowledge of how they are to be architected. All they know is all requests for resources need some kind of credentials associated with them. The manner you pass those credentials can vary. You can use something like the FAS Flask Auth Plugin to handle authentication. Or you can do something simpler like package the credentials provided to your entry service in the HTTP headers of the subsequent requests to other services. Flask.request.headers in your subsequent services will give you access to the right headers to pass to your authentication service.
There are a lot of ways you can go when it comes to details, but I think this general architecture should work for you.

Categories