Can anyone explain me steps using openid library which is mentioned here.
I have import all package of janrain openid in my programe but I cant understand actual flow of code.
The process should basically follow this plan:
Add an OpenID login field somewhere on your site. When an OpenID is entered in that field and the form is submitted, it should make a request to the your site which includes that OpenID URL.
First, the application should instantiate a Consumer with a session for per-user state and store for shared state. using the store of choice.
Next, the application should call the 'begin' method on the Consumer instance. This method takes the OpenID URL. The begin method returns an AuthRequest object.
Next, the application should call the redirectURL method on the AuthRequest object. The parameter return_to is the URL that the OpenID server will send the user back to after attempting to verify his or her identity. The realm parameter is the URL (or URL pattern) that identifies your web site to the user when he or she is authorizing it. Send a redirect to the resulting URL to the user's browser.
That's the first half of the authentication process. The second half of the process is done after the user's OpenID Provider sends the user's browser a redirect back to your site to complete their login.
When that happens, the user will contact your site at the URL given as the return_to URL to the redirectURL call made above. The request will have several query parameters added to the URL by the OpenID provider as the information necessary to finish the request.
Get an Consumer instance with the same session and store as before and call its complete method, passing in all the received query arguments.
There are multiple possible return types possible from that method. These indicate the whether or not the login was successful, and include any additional information appropriate for their type.
web.py includes a webopenid module that implements a complete, if basic, OpenID authentication system using the Janrain. Using the included host class, you can add OpenID-backed authentication to your project. To actually pull interesting data from the OpenID provider, though, you'll need to add AX and SReg request/response handling.
Related
Im trying to make an IOS app with a frontend coded in swift and the back in python using django's rest api.
I have a tab bar controller set up with two tabs, one ultimately connected to a HomeViewController. I have used firebaseAuth, in which I would normally use a firebase function that looked roughly like this
if firebase.Auth.currentUser != nil {
let vc = HomeViewController()
present(vc, animated:True)
}
However, to the best of my knowledge, django's rest api does not have a function of doing so, and so I have been stuck for a few hours now trying to figure this out.
Currently, I am planning on using the cached access token, retrieved on registration/login and sending a get request which returns the users information. (username and email). Then creating a function to decode the data which returns a boolean.
I plan on making a struct
struct AuthenticatedUser: Codable, Hashable {
let username: String
let email: String
}
If it does not confirm to the appropriate struct, the json decoder will fail. (This would be because the get request returned an error as the token was deleted. (In the process of logging out, i would delete the users tokens).
Finally, I will end up with something like this
if decodeData == false {
let vc = HomeViewController()
present(vc, animated:True)
}
Im sure this would work, but even as someone new to programming I can tell that this code seems longwinded, messy and most likely considered as bad code.
I was wondering if anyone had any improvement/new methods (preferably new methods) on combatting this problem.
Any help will be much appreciated!
Well, first your app does not strictly need to know a priori if the current user (which is some data stored persistently within the app) is signed-in in order to access protected user resources successfully (eventually).
The mechanism required in order to make this work, can be entirely embedded transparently into the "client network code", and your views and other parts of your app which perform "protected data access" do not need to know anything about the login scheme, or whether the user is registered or signed-in.
What is signed-in anyway?
What is registered?
What is a user?
Assuming you are using the more common login schemes (OpenID Connect or an custom scheme based in OAuth) which is based on user authentication, user consent and a bearer token, these questions can be answered as follows:
A user which is a struct containing some data about a real user is the identity which has been successfully authenticated. This information is available after user authentication and authorization which usually are the first two steps in the "register user" flow. This can happen on a third party identity provider, but can also be included in your domain server.
Once you have an authenticated user, the app registers this user in our domain database as part of the registration flow. That is, after this step, your user is registered, and that means, it can access the services provided by your domain server.
A user also can "unregister" and its private data and especially, the "user" record on the domain server will be deleted or marked "unregistered".
The processes running on the front end for this, can run on the device or anywhere, for example a web application or a desk top application.
Now, what should be immediately become clear is, that given a certain app on a certain device and just by querying local state, an app never can determine a priori if a user is registered or not, even if the app has a user info.
Now, suppose an app has a "current user" info, and that the user has been registered, but it is not yet "signed-in".
Signing in means, that the app receives a refresh token and an access token. The access token is the key to access protected user resources. When doing this, no user info is required, the access token is implicitly associated to this user.
The refresh token acts as a key to get a new access token, whose expiration time is much longer, possibly quite long, so that it literally never expires (not recommended).
The expiration duration of an access token is usually in the minutes. So, it is quite common that the access token expires all the time.
The access token will be required when accessing a protected resource, so it will be needed for every protected access.
When it is expired, the server sends a very specific unambiguous status code. So, your client code can act accordingly, which means:
push the request on a queue
use the refresh token and ask for a new access token on a certain refresh-token endpoint
Retry the request with the renewed access token
This mechanism is completely transparent to the higher level code and can be implemented quite deeply in the client network code.
Now, in the event that the refresh token is expired too, you again get an unambiguously status code from the refresh-token endpoint.
In this case, it is clear what to do:
Require the user to sign-in again
Step one returns a are refresh token and also access token
Retry the request.
It is clear, that this requires user interaction and will interrupt the current active flow. It should also be obvious, that an app can also not determine a priory if the refresh token has been expired.
Ideally, this "sign-in-again" flow can be pushed on top of any other flow which happens to access a protected resource. Alternatively, just let the refresh-token request fail without opening a sign-in flow, showing a clear error message hinting that the user needs to sign-in again.
The consequences of this is, that you have to try (or just can try!) to access a protected resource in order to find out whether a user is signed in or even registered.
This all has to be implemented in the client network code. Good luck! ;)
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 to set up Django to use OAuth2 to authenticate users for a service that I'm running, but I'm having a bit of difficulty understanding how the tokens are passed around.
I've been working my way through this tutorial: https://django-oauth-toolkit.readthedocs.org/en/0.7.0/tutorial/tutorial_01.html. I've been able to get a server up and running as the OAuth provider, and it seems to be working as it should. I'm able to log in to it and set up an application. The difficulty I'm having is figuring out how the various tokens are passed around.
Suppose that my OAuth provider is sitting on one server - let's call this Provider.com - and my service that I'm wanting authenticated is on service.com. When a user first tries to make a request to the service, they first need to authenticate against the Provider. So they click on a login button which directs them to Provider.com. They enter their credentials. If everything is set up correctly on the server, they should be presented with a prompt that gives them a chance to allow or deny Service.com from accessing their account on Provider.com. Supposing that they click Allow, they are then redirected to Service.com, and are given a token. On future calls to Service.com, they pass in the token, and are, in theory, able to make authenticated calls.
The problem I'm having understanding is this: At what point do the Provider and the Service communicate? If a call comes in to the Service, how does it know that the authentication token passed in with the call is valid? There's know way it could know that a particular token is valid unless: A) it recognizes that same token from a previous call which was also authenticated or B) it talks to the OAuth 2 provider and verifies the authenticity of the token.
A diagram like the one found here shows the process in the browser:
At the end of this, it has the Client App sending the authentication code, client id, and client secret to the OAuth2 provider. In the previously mentioned tutorial, it isn't really clear how this is actually done. In the tutorial, the provider and the service are on the same machine, and it would appear that they also share the same database.
This this brings about my question: How does one host a Django-based OAuth provider on a separate server than the resource/service being accessed? Is this possible?
From this other post, it indicates that this might not be possible: https://stackoverflow.com/a/26656538/1096385 Is that indeed the case, at least with the existing Django OAuth2 provider framework?
It depends on the oauth2 flow you're using. It seems like you're using authentication code.
In that case:
service.com sends the browser to provider.com for user authentication (uri contains service.com client_id and redirect_uri)
User authenticates on provider.com, then the browser is redirected to service.com's redirect_uri with a ?code parameter.
On your server side, handle this code parameter and ask for a token with it.
See https://aaronparecki.com/articles/2012/07/29/1/oauth2-simplified#web-server-apps
This post is a followup to How to do OAuth-requiring operations in a GAE cron job?, where I realized I'm mis-using the #oauth_required decorator from OAuth2DecoratorFromClientSecrets.
As described by the OAuth 2.0 explained presentation, Oauth 2.0 solves the problem of:
Building a service...
... accessed by a user...
... and accessing the user's data from a third party.
That's what #oauth_required abstracts, and it does it well (currently my app "works": if I trigger the refresh page, I'm being asked to authorize access to my youtube data to my app, and the rest follows). But that's not what I want! My app does something simpler, which is creating a youtube playlist every day with my credentials and without any user input. So to compare to the above 3-tier negociation, I want:
A service
... accessed by users
... but only accessing "server-owned" YouTube playlist data. I don't want any access to the user's YouTube data, I just want to modify a playlist I (i.e. me / a userid persisted by the server) own.
But I still need help to do that; here is my current state:
After a few searches I learned that what I want to do is called Offline Access (emphasis mine, which is almost exactly my use case):
"In some cases, your application may need to access a Google API when the user is not present. Examples of this include backup services and applications that make blogger posts exactly at 8am on Monday morning. This style of access is called offline, and web server applications may request offline access from a user. The normal and default style of access is called online."...
→ So I should keep doing what I'm doing right now, keep requesting access to my YouTube account, but do it using the type_access=offline flag to get a token, and persist/use it for subsequent requests.
The Offline Access and Using a Refresh Token sections make total sense, but stay at a general HTTP level. Being still a newbie, I don't see how to integrate those principles into my Python code, and I didn't find any sample Python code around....
→ Could anyone help me with one Python example illustrating how and where to use this flag?
... and in particular, after studying oauth2client.appengine.OAuth2Decorator.oauth_required, I'm still not sure if I can bend it to my case, or if I should do my own thing.
→ What do you think?
Thanks for your time; if needed I'm also hanging out on irc://irc.freenode.net/#appengine as ronj.
Offline access is the default when retrieving tokens; you may have noticed this in the OAuth dialog that comes up:
Perform these operations when I'm not using the application
When your user accepts the OAuth dialog in a method decorated with decorator.oauth_required the credentials for that user will be stored in the datastore, including the refresh token.
Once you have one of these credentials objects, you can use it so authorize an HTTP object for calling APIS:
import httplib2
http = credentials.authorize(httplib2.Http())
and once authorized, it will do all the work for you. So if the access_token is expired, the first API response will be a 401 and so the credentials object will use the refresh_token to get a new access_token and make the request again.
If you know the user ID, you can retrieve the credentials from the datastore as described in How to do OAuth-requiring operations in a GAE Task Queue?:
from oauth2client.appengine import CredentialsModel
from oauth2client.appengine import StorageByKeyName
credentials = StorageByKeyName(
CredentialsModel, user_id, 'credentials').get()
Note/Gotcha:
If a user has already authorized your client ID, the subsequent times you perform OAuth for these users they will not see the OAuth dialog and you won't be given a refresh token. A refresh token can only be given if they go through the OAuth dialog, but since the user had already authorized your client ID, the spec assumes you would already have a refresh token around.
This often comes up when developers are testing OAuth, since they will go through the flow multiple times with a test account and after accepting the 2nd, 3rd, 4th, ... times, they never see the refresh token. A simple way around this is to use approval_prompt=force as an argument to the OAuth2Decorator constructor. This will force the OAuth dialog to appear every time you perform OAuth for a user.
However, this will not cause the dialog to show up every time a request is served for a given user; this would be a TERRIBLE user experience. Instead, the SACSID cookie from the request can be used (by the client library and some App Engine libraries) to determine who the current user is. Once the the library knows that current user, it can get your existing stored token/credentials for that user from the datastore and no jarring dialog will be needed.
I'm trying to implement openid login with Django and having some trouble. The library I'm trying to use now is Django-openid-auth. I haven't found any django+openid libraries that have much documentation. How can I actually go about using this as a login and store the information I need for my app based on the users that come in from openid? How does this store the information shared from the openid provider and does this library already store it?
The OpenID identity verification process most commonly uses the
following steps:
The user enters their OpenID into a field on the consumer'ssite, and hits a login button.
The consumer site discovers the user's OpenID provider using
the Yadis protocol.
The consumer site sends the browser a redirect to the OpenID
provider. This is the authentication request as described in
the OpenID specification.
The OpenID provider's site sends the browser a redirect back to
the consumer site. This redirect contains the provider's
response to the authentication request.
your web app needs to keep track of:
-the user's identity URL and the list of endpoints discovered for
that URL
-State of relationships with servers, i.e. shared secrets
(associations) with servers and nonces seen on signed messages.
This information should persist from one session to the next
and should not be bound to a particular user-agent.
hope this helps:D