[Twisted-Python] twisted cred: why does avatarId need to be a str?

Laurens Van Houtven lvh at laurensvh.be
Fri Sep 10 13:01:41 EDT 2010


I'll give a very practical example of an example request + response, because
I'm not entirely sure I communicated that properly. The code we're
discussing is part of a TokenEndpoint, which is an IResource. Something (a
client, in OAuth terminology) makes a request that looks like this:

---
POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=password&client_id=s6BhdRkqt3&client_secret=47HDu8s&username=johndoe&password=A3ddj3w
---

And hopefully the code we're discussing answers with a request that looks
like this:

---
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
"access_token":"SlAV32hkKG",
"expires_in":3600,
 "refresh_token":"8xLOxBtZp8"
"scope": "tummies cookies parrots"
}
---

Where, as mentioned before, everything besides "access_token" is not always
required (but it must be possible to set them, because occasionally they are
required).

On Fri, Sep 10, 2010 at 2:34 AM, Glyph Lefkowitz <glyph at twistedmatrix.com>wrote:

> for any given cred implementation, there are two key questions:
>
>    1. What is the avatar interface?
>    2. What is the associated mind interface?
>
> If we're not talking about a system where the avatar interface (the one
> passed to 'login', the one that the realm must return something that gets
> implemented) is IResource, then that's the problem.  What *is* that
> interface that you're talking about?  Be very specific: what methods does it
> have and why?
>

Okay, to be specific: I believe the appropriate interface is IResource. This
is in line with t.web's general way of interacting with cred: you give me
credentials, I give you a protected IResource.


> It sounds like OAuth is very precisely implementing something that maps
> almost exactly onto the *checker* part of cred, but you're doing it by
> implementing a realm to allow applications to provide their own logic.  This
> might not be the wrong idea, but it needs to be spelled out very clearly.
>

Doing everything in the checker probably might make more sense. The reason I
originally thought to do this in the IRealm is that I figured credentials
checkers should just check credentials, and creating a new credential (the
access token) wasn't part of ICredentialsChecker's job (more like IRealm's
job). Apparently I was mistaken.


> As you describe it:
>
> token endpoints let you trade in some credentials that prove you're
> supposed to have access for a token that actually *gives* you that access
>
> In cred-ese, that would be "checkers let you trade in some credentials that
> prove you're supposed to have access for an <avatar ID, which you give to a
> Realm> that actually *gives* you that access".  As far as the OAuth response
> is concerned, it's like a checker.  Looking at the individual parts,
> assuming that the avatar interface for the purposes of this discussion is
> IResource, it breaks down like this in my mind:
>
>     - the access token (an ascii string, mandatory)
>
> Avatar ID.  (See, it's a str!)
>

Heh, okay; as long as there's a plausible way to get the other important
information (see rest of email) into the HTTP response, I'll believe you.

>     - the expiration time (optional)
>
> Implementation detail of the session.  Avatars are actually sessions, which
> expire: sometimes (as with POP) at the end of a connection, sometimes (as
> with nevow.guard's HTTP support) with a session timeout.
>

Right, but:
a) The avatar needs to know about this timeout, since the timeout
information needs to be able to make it into the HTTP response.
b) The expiration time is only known to the thing that creates the access
token (obviously). From the previous discussion, this is apparently
ICredentialsChecker.

c) (From (a, b)) The ICredentialsChecker needs to be able to communicate the
expiration to the avatar.
d) The ICredentialsChecker and IRealm can only communicate through the
avatarId.

Conclusion (from c,d): The expiration time needs to be in the avatarId?

>     - the refresh token (another ascii string, similar to the access token,
> optional)
>
>
> Implementation detail of the authentication protocol.  The client library
> and server library should be transparently refreshing this without telling
> either the client application code or server application code, right?
>

Sure, but we're still writing library code here.

If the avatar interface isn't actually IResource, but a new interface
IAccessToken, getting the refresh token later might be feasible. (It should
be a different interface, because in order to create a refresh token outside
of this entire cred cycle, I need to know about the thing it's refreshing --
so, the information in the response needs to be easily accessible and not
just an opaque IResource).

I agree entirely that clever client library code would abstract this mess
away from application code. However, right now this code still needs to
somehow be able to eventually produce HTTP responses that don't abstract
anything yet and just contain all the appropriate data, because that's just
what the OAuth spec says it needs to be able to do. There isn't any real
application code in the token endpoint; they're pretty similar for all OAuth
setups, and customization would typically happen through implementing the
appropriate ICredentialsChecker.

    - scope (an ascii string consisting of a set of space-separated words,
> optional)
>
>
> This part doesn't quite fit, but could be expressed in one of two ways: a
> modification to the avatar ID, or as some extra structure on the Mind that
> modifies what functionality the Realm bundles in to your avatar
> implementation (without changing the interface provided by that object, of
> course).
>

Unfortunately I don't believe this can be done through the mind. Again
working under the previous assumption that ICredentialsChecker and not the
IRealm is responsible for creating the access token, and scope is known to
the thing that makes the access token, the ICredentialsChecker knows about
the scope. Unfortunately the only way to pass stuff  between the
ICredentialsChecker and the IRealm is the avatar ID, so you don't have a
choice.


thanks for your infinite patience,
Laurens
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://twistedmatrix.com/pipermail/twisted-python/attachments/20100910/76080471/attachment.htm 


More information about the Twisted-Python mailing list