[
https://issues.apache.org/jira/browse/SHINDIG-290?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12609396#action_12609396
]
Brian Eaton commented on SHINDIG-290:
-------------------------------------
I've reviewed the code. Comments:
BasicOAuthTokenStore and BasicOAuthConsumerStore
- this is very similarly named to something in the gadgets side of the tree,
can we pick a better name for either or both?
OAuthTokenIdentityMapper
- Passing in OAuthMessage rather than just the consumer key and access token
would be useful here. That way if someone extends the protocol to include
additional information they have it available.
- throwing ServletException strikes me as a little weird. Do you need to think
through the errors this interface should throw a little more?
OAuthServletFilterTest
- you aren't actually verifying that the HTTP responses returned from the
filter have the proper data in them. For example, what test would catch the
problem if OAuthServlet.handleException suddenly stopped returning HTTP 401 and
started returning "HTTP 503 Your mother is a hedgehog"
OAuthServletFilter
- excellent documentation, thank you.
- Comment on case (1): this seems really weird. Are we trusting the gadget
security token, or the signed fetch data? They may be in conflict, so which
one do we trust?
- Comment on case (2) has typo, "allows containers to this OAuth token" should
be (I think) "allows containers to link this OAuth token"
- OAuthValidator validator; is this thread safe?
- OAuth errors should return additional human readable text in the
oauth_problem_advice field.
- (warning: my pet style peeve, feel free to ignore) Reviewing this code in a
text editor is a little annoying because a few functions are implemented far
away from where they are used. For example handleRequest calls
getOAuthMessageFromRequest. I search around in the file to find the
implementation of getOAuthMessageFromRequest, and discover it seven or eight
method declarations later. If methods are declared in roughly the order they
are used, it makes reading the code more linear.
- handleException
I'm not sure OAuthServlet.handleException will really do what you want for
all time. The contract for that function is really vague. You may want to add
a test or two so that if OAuthServlet.handleException changes, you notice and
can correct your code.
- getOAuthMessageFromRequest seems problematic, because it relies on
req.getRequestURL. Is that going to be reliable? For example, what happens if
there is a front-end in front of the social data server that modifies the URL?
e.g. social request arrives on https://www.example.com/social, but is resent to
http://internal.example.com:7777/social. The OAuth signature checks will fail
unless you pass in the right URL. I'm really not certain of the best way to
handle this, maybe what you've got (a protected function so that someone can
override) is as good as it is going to get.
- is allowUnauthenticated really the right name for the configuration option?
Or should it really be "oauth.allow-non-oauth-requests". For example, someone
may implement another servlet filter that uses HTTP basic auth for access
control in the event that OAuth is not available.
- getSecurityToken
The error handling here looks wrong.
1) You probably want to log the SecurityTokenException. As is the log
message discards useful information, e.g. you have no idea whether the security
token was expired, malformed, or something else.
2) You probably want to log the request the client was attempting, so you
have some notion of what kind of request caused the problem.
3) You probably don't want to ignore the error, you should probably abort
request processing. If someone sent a security token and it doesn't work, they
need to know about it!
- getRequestorId
Should you return id, or id.trim()?
- handleConsumerRequest
About this comment: // we're using the viewer as the principal
I can see that from reading the code. A comment explaining why would be
useful.
- handleExplicitIdentity
allowConsumerRequest: this seems like a very strange parameter, or maybe it
is just strangely named. Would a better name be "allowAuthnType", perhaps? Or
maybe it would be better if this logic was moved up a place or two in the call
stack. For example, the allowSecurityToken check could be implemented in
getSecurityToken, and the allowRequestorId check in getRequestorId.
- It's unclear to me why you are requiring an OAuth consumer signature to use
the gadget security token. Why? A gadget can make the same API calls using
only the security token, right? I'm sure there is some reasoning behind the
check, I just can't figure out what it is.
- all: you are throwing away some important authentication information in this
code. For example, at the end of the day you have lost the OAuth consumer
information, you have lost the gadget security token, and you are reduced to to
just a user identity. That's likely to pose a problem for some use cases. For
example, the user has some privileges that a server impersonating the user does
not have. You can't enforce that access control if you throw away the
information about delegation.
- I think you need to define a tighter API contract for the getUserPrincipal
method. If your code creates a Principal, what will the class of that
Principal be, and what methods will be available? As a concrete example:
someone doing an access check will want to know whether an OAuth token was for
read/write vs read-only access. How are they supposed to get that information
out of your Principal object? I'd suggest implementing a subclass of Principal
that has some additional methods like "getGadgetSecurityToken" and
"getOAuthRequest". They should return the information that you used to do the
authentication. getPrincipal().getName() is the bare minimum information you
need to provide, but there is no rule saying you have to throw away everything
else.
> Add OAuth and Gadget Token access control systems to API server
> ---------------------------------------------------------------
>
> Key: SHINDIG-290
> URL: https://issues.apache.org/jira/browse/SHINDIG-290
> Project: Shindig
> Issue Type: New Feature
> Components: RESTful API (Java)
> Reporter: David Primmer
> Attachments: rest_api_server_auth_system.png,
> rest_api_server_auth_system.svg, restful-oauth1.txt, restful-oauth2.patch
>
>
> The server should be able to get auth info from both the gadget token and an
> oauth access token and after inspecting them, figure out the attributes
> necessary to pass on to the backend. There may be complicated rules for
> attribute precedence depending on the context of the request. A servlet
> filter is assumed to be the implementation and its also assumed that this
> would not be a throw-away system, as few of these actually exist, it might as
> well be a decent one. Current social soken handling can also be moved to a
> servlet filter for parity.
> In addition, there should be a simple Access Management system that can store
> access control lists and potentially delegations that the API server can
> refer to for data access decisions. This Policy Decision Point should be of
> limited scope and it's assumed it will be based on the standard Java security
> libraries. Policy enforcement will still happen in the social api data
> service layer.
> And Identity provider / login mechanism and GUI for delegating permissions
> (needed for the OAuth three-legged flow) is the most "out of scope" for
> shindig and it should be developed as a very simple and separate system to
> take credentials, take a delegation decision and store it in the Access
> Managment system.
> (I write this rather elaborate feature request knowing that I have a diagram
> illustrating this.) ;-)
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.