Hi, thanks for the response!,
comments below.

Les Hazlewood wrote:
Hi Jason,

I don't see any Jira issues related to oauth either.  Could you please
add one (or more if necessary) to ensure it is not lost?

sure


I'm assuming you're implementing an OauthRealm which acts as an OAuth
Consumer.  What is it that you're trying to do exactly?  Are you
trying to populate the initial set of roles and permissions based on
interaction with one or more Service Providers during login?
I'm no expert on OAuth, but as I understand it, a token/secret allows
you to interact with a Service Provider on behalf of the User, but
OAuth provides no ability in the protocol to discover what
roles/permissions are granted by the Service Provider.  I don't know
how, as listed in your example, you could maintain
(appuserid,token/secret,roles,permissiondata) since you don't know the
last 2 parts of that tuple.  Odds are high that I'm interpreting this
incorrectly, so please clarify ;)

you are correct, oauth allows a service provider to act on behalf of a user, and you are also correct in that there is no permission or role data associated, but I have seen extensions implemented that allow submission of role info with the initial request.
ref: http://fi.am/entry/building-a-website-api-with-django-part-3-oauth-in/



As to how to look up a ServiceProvider + token/key pair per user,
consider the following (language agnostic) class:

Token {
    String serviceProvider
    String value
    String key
    String type
}

The 'type' attribute would only ever be 'request' or 'access' since
those are the two types defined in the OAuth specification (better
yet, make that an Enum).  You could make this a boolean, but my gut
feeling would be to not do that in case the spec ever changes to add
another type.
The 'request' attribute is a boolean because there are only two types
of tokens in OAuth: a request token or an access token.  After access
is granted, you can just set that value to false.

I dont need this much myself, but it would be a good idea. I'm using oauth over xmpp, and I'm using an adapted version of the oauth reference implementation as the provider implementation. the XMPP spec for oauth insists that the initial dance/setup be done out of band via http so this suits. I actually found a potentially better library today (I thought I knew them all, but I only just discovered this today), It needed a minor tweak in the demo provider, but it works. internally its a bit odd, but still simpler than the reference impl. and there has been some effort to make the datastore extensible, but its consumer impl is still too tied to http for my immediate needs.
ref: http://code.google.com/p/dyuproject/

I'm using signpost as a consumer lib and I've built an xmpp module for it. I think I'm about the only person using xmpp and oauth so there isnt much useful out there.

The serviceprovider gets a request key via http then directs the user to a URL(of the main service that needs to have authority granted). Once there the user authorises the provider, and accepts whatever permissions need granting (app specific). Next a pin is given to the user which they take back to the provider (via xmpp). the provider via http uses the pin to exchange its existing request token/secret with an access token/secret pair.

I need a common store for both the oauth web app and my xmpp based server app so they can access common provider and user data, and I'd like to still deal with one user in my application, not lots.

Now, you _could_ have one or more Token instances each be a single
principal in the PrincipalCollection returned by your OauthRealm.
Then you could access these tokens anywhere in your application by
calling subject.getPrincipals().fromRealm("oauth");

not sure I like this, as users/principals have other properties so wouldnt this approach lead to 1 user effectively becoming many?

Note however that PrincipalCollections should be as lightweight as
possible since principals are often stored in the Session and
serialized as cookies in web apps.  But this might be ok/negligible
for your app though - YMMV.

A better performing approach would be to do as you suggested - store
the Tokens in a separate store.  I would probably key the lookups
based on your application unique user ID for very fast lookup.  You
could also store the Token in a map, keyed by serviceProvider:
Map<String,Token> tokens = getServiceProviderTokens(applicationUserId);
Token token = tokens.get(serviceProvider);
//call the Service Provider with the info in the returned Token.

I like your thinking but unfortunately I dont think this can work since the lookup has to occur on the oauthtoken/key first in order to discover the userid. After that the rest of my app can use the real application userid - before that all it knows are the token/secret and serviceproviderid's.


This logic would reside in your OauthRealm if you didn't need to
access the tokens any place other than the Realm.

yes - just want the realm to accept the oauth data and return an appropriate app specific Subject. I already have code to do the oauthy bits, and I'm using a spring remoting service exporter (over xmpp) for my serviceprovider->server transport. I initially thought I could use the shiro SecureRemoteInvocationExecutor but that ONLY works with the http exporter and I based mine on the hessian exporter which has no support for this and its very awkward to make it support. aop seems like a good option for me, but my app also talks to mobile devices with common interfaces, so annotations are out(I read in a shiro post that they have to be on interfaces not concrete impls so they dont suit, plus I just don't like annotations much). So I'm about to roll my own interceptor for this too. any hints greatfully accepted.

 Otherwise, you'd
probably have to put that logic in a Service/Manager of some sort for
access by the application elsewhere.  Then the OauthRealm could use
this service/manager if it needed the same data at some time later.
This approach is naturally more complex than just storing the Tokens
as Subject principals, but it would probably be a better performing
alternative.  YMMV depending on your app.

its difficult to come up with a performant solution here since for any single user there may be many tokens and permission sets, so if the app has a large number of users, just maintaining this list becomes a challenge. One alternate solution which is employed by the likes of yahoo is not to store this data at all, but to carry it all encrypted in the oauth signature.


Again, I'm no OAuth expert, but I hope this helped a little.  Please
feel free to continue contributing/brainstorming, and maybe we could
get some out-of-the-box support included in Shiro.  Also, please don't
forget the Jira issues, otherwise it will definitely get lost!

HTH,

Les

Thanks
Jason.




On Wed, Dec 9, 2009 at 10:32 PM, Jason Eacott <[email protected]> wrote:
hi all,
 I'm new to Shiro, and have discovered this thread relating to oauth:
http://www.mail-archive.com/[email protected]/msg00088.html

it hints that there are existing Jira issues related to this but I couldn't
find any.

Has anyone done anything with oauth and Shiro?
I would be very interested.

if not then perhaps someone might point me the the right direction?
 I'm not quite sure how such a realm in Shiro might best be implemented. The
problem is that oauth always needs both user and serviceprovider entities,
and each user has a unique token/secret pair for every service provider.
Each (token/secret)+serviceprovider association also has its own set of
permissions.
So with shiro what would be the best way to carry this forward?
perhaps a separate store containing
serviceprovidertoken ->to-> (appuserid,token/secret,roles, permissiondata)
with which to authenticate the user?, after which I could populate the
AuthorizationInfo using the appuserid, and permissions discovered here.

Has anyone any thoughts on the best way to use an LDAP directory to store
such data?

Thanks
Jason.


Reply via email to