I would like to write a WSGI middleware that will work with my flask application. Any examples on how I can do that ? I found one on their documentation, but it says that it is not the preferred way to do it, so wondering what is ?
I would like to write a function which encrypts the session information and sends it as a cookie on response. On request it decrypts the cookie, and passes it forward as a hash. Basically client side session management as an encrypted cookie.
Em.. have you read the Flask or Werkzeug docs? Flask allows passing cryptographycally signed session data via cookies. If you want some secure cookie-based session management of your own, check the SecureCookieSessionInterface.
Related
I am using client side sessions. The requirement is to redirect from 1 flask server which already have a user session data to another flask app on a different server and use the same client session information to make sure the user has already logged in if not send them back to the 1st server for authentication.
If possible i would like to keep using the client side sessions. If not any information regarding the alternative will be helpful.
Thank you
Normally there is 2 options.
First, client side authentication using token like JWT (Json Web Token), this approach authenticate every request using token included in header and no need additional server.
Second, server side approach with additional session store like Redis for multiple backends.
Where does Pyramid store the auth_tkt at rest? I'm trying to quantify how many open sessions my site currently has and I'm hoping I'm just blanking on what table it's being stored at.
auth_tkt is the default name of the cookie which is a parameter for Pyramid's AuthTktAuthenticationPolicy, which is stored in the visitor's web browser.
Pyramid has no database, but your app might have one. If so, then you'll need to trace through your application's code to find where you maintain server side sessions.
To extend on Steve's answer: auth_tkt is an authentication method which does not require a server-side session storage. It works by generating a cookie based on username and a server-side secret, so the cookie basically looks like this:
senatork:kuh87h887KHJKJH908uo
The client then sends the cookie and the server is able to validate the "claim" contained in the "ticket" by generating a new signature using the server-side secret and comparing it to the one contained in the cookie. Here's some more details in the documentation of the original Apache mod_auth_tkt (which Pyramid does not use, but it uses the same logic).
If you need a session storage for your app you'll need to implement it separately from auth_tkt authentication.
I'm trying to create a command line client for Jira, but I don't really want to store the username/password, and I don't want to have to put in my password with every single request.
Jira says they have a cookie based API, but it doesn't look like it works the way that I think it works.
Specifically, when using Python's requests library I can only re-use the cookie if I have a Session object that I think keeps a connection to Jira.
But if I try to say, make a requests.post request and requests.get requests to the REST URL, it fails with a 401 and tells me that I'm not authenticated. OTOH, if I create a Session, I can do
session.post(.../rest/auth/1/session)
print(session.get(.../rest/auth/1/session).status_code)
And I'll get the 200 that I expect.
I do notice that there's another cookie in the requests response headers:
atlassian.xsrf.token=SOMETHING|RANDOM|lout
but I didn't see anything about that in the documentation.
Is it possible to do this, or do I have to store the username/password if I want to break the connection in between requests?
You are correct, the session is required. From the documentation:
The client creates a new session for the user, via the JIRA REST API.
JIRA returns a session object, which has information about the session including the session cookie. The client stores this session object.
The client can now set the cookie in the header for all subsequent requests to the JIRA REST API.
In other words, the session is integral to the request, receipt and use of the cookie-based authentication token.
Also, the atlassian.xsrf.token would have been injected by atlassian to prevent cross-site forgery and hijacking of the session/cookie.
The way I see it, here are your simple-but-secure options:
For every invocation of your script, use the session to request-receive-retain the cookie (and then, once all API calls are complete, let everything get discarded)
Base64 encode your username and password, store it in a separate file (encrypted if you so choose), and have your script collect (and decrypt) it then place it in an authorization header. See Hiding a password in a python script (insecure obfuscation only).
If you follow the goal not to authorize every time you send a request to the API, you should send (POST) your authentication requests using the cookie-based authentication /rest/auth/1/session, not Basic Auth, to get the token. You will then use that obtained token subsequently in your further requests (in the Cookie header) to the API without a need to authorize every single request.
Watch out for the important missing piece in the API documentation: you should sent the username, NOT email, to authorize in a cookie-based manner. Even though both variants work for the Basic Auth, only user works for the cookie-based authentication.
I apologize in advance for asking a rather cryptic question. However, I did not understand it despite going through a lot of material. It would be great if you could shed some light on this.
What is the purpose of a request_loader in flask-login? How does it interact with the user_loader decorator?
If I am using a token based authentication system (I am planning on sending the token to my angularJS front end, storing the token there and sending that token in the authorization-token header), will I need a request_loader or will a user_loader (where I check the auth header and see if the user exists) suffice?
From the Flask-Login documentation:
Sometimes you want to login users without using cookies, such as using
header values or an api key passed as a query argument. In these cases,
you should use the request_loader callback. This callback should
behave the same as your user_loader callback, except that it accepts
the Flask request instead of a user_id.
So, to answer your question, they both serve the same function for Flask-Login. They are both used to load the user. request_loader, however, is appropriate for custom logins.
Here's a great tutorial I found that utilizes request_loader to take advantage of token based authentication (The post is not my own, I'm merely sharing the link): http://gouthamanbalaraman.com/blog/minimal-flask-login-example.html
I need to make this clear.
This is the reason why you shoud use request_loader with flask_login.
There will be a lot of #login_required from flask_login used in your api to guard the request access.
You need to make a request to pass the check of auth.
And there will be a lot of current_user imported from flask_login,
Your app need to use them to let the request act as the identity of the current_user.
There are two ways to achieve the above with flask_login.
Using user_loader makes the request to be OK for #login_required.
It is often used for UI logins from browser.
It will store session cookies to the browser and use them to auth later.
So you need to login only once and the session will keep for a time.
Using request_loader will also be OK with #login_required.
But it is often used with api_key or basic auth.
For example used by other apps to interact with your flask app.
There will be no session cookies,
so you need to provide the auth info every time you send request.
With both user_loader and request_loader,
now you got 2 ways of auth for the same api,
protected by #login_required,
and with current_user usable,
which is really smart.
To verify users with Flask-Login's session_id for frontend requests through Angular, you must set the withCredentials configuration flag to true.
That is, if you are using Angular's $http.post(url,data [,config]) or $http.get(url [,config]), make sure the config object contains the property withCredentials set to true. This will instruct the browser to use its cookies in the same way it would for a full-on page visit.
For example,
$http.post('/api/login',{username:'myusername',password:'mypassword'},{withCredentials:true})
will post the data {username:'myusername',password:'mypassword'} to your site/app's /api/login route and, if you're using Flask-Login and are logged in, Flask will know.
You can set this behavior for all $http service requests by setting
$httpProvider.defaults.withCredentials=true
somewhere in your app. Currently, I have that line of code in my app.config block, which seems appropriate to me:
var myApp = angular.module('myApp');
myApp.config(function ($httpProvider) {
$httpProvider.defaults.withCredentials = true;
});
(Since this post is about Flask, folks may want to send form data through Angular in such a way that it can be found in request.form, which has a similar solution, fyi.)
I'm looking for solution how to setup domain authorization with aiohttp.
There are several ldap librarys, but all of them blocks event loop, plus i don't have clear understanding about user authorization with aiohttp.
As i see i need session managment and store isLogdedIn=True in cookie file, check that cookie at every route -> redirect at login handler, and check key in every template? It seems very insecure, session could be stolen.
You may call synchronous LDAP library in thread pool (loop.run_in_executor()).
aiohttp itself doesn't contain abstractions for sessions and authentication but there are aiohttp_session and aiohttp_security libraries. I'm working on these but current status is alpha. You may try it as beta-tester :)