On Tue, Oct 8, 2013 at 3:09 PM, Mike Pawlowski <mpaw...@ca.ibm.com> wrote:
> Hi Ryan, > > Thanks a lot for following-up and providing the detailed responses. The > answers are very helpful. > > > *>> **I don't think I can answer everything.* > > Acknowledged. This is inherently due to the complex nature of the OAuth > 2.0 / SSO specification and host system implementation > details / custom authorization requirements. > > Also, Adam (from the CRE / w3 Connections teams) has reached out to me > offline and graciously provided me with > very valuable information, feedback & insight as well. > > > > *>> **First at a high level I am wondering if you are trying to avoid the > * > *>> typical OAuth dance where the user has to log in and grant access to > the app/gadget?* > > In this case, lets assume that our gadgets (Jazz) are trusted and perform > makeRequest operations > via OAuth 2.0 / SSO. > > We want to support two use cases: > > (a) Add our gadgets to our OpenSocial gadget container (e.g. Jazz) > (b) Add our gadgets to another tools OpenSocial gadget container (e.g. > JIRA). > > For case (a), the answer is yes. Ideally, we would like to avoid the > typical OAuth dance. > Our gadgets are trusted and the user has already authenticated with our > Authorization Server; since the page hosting our OpenSocial gadget > container is a > protected resource and the application serving the page already has a SSO > access token. > > For case (b), I suspect we want to explicitly support the OAuth dance; > since, we are at the mercy of > the host applications OpenSocial gadget container implementation (although > we control the server's > deployment and have the ability to inject adapters via plug-ins, so we may > be able to overcome various > limitations to some extent). > > To simply things from a gadget development standpoint, we decided (for the > time being) to > explicitly support the OAuth dance in the gadget in order to support both > case (a) & case (b) in order > to avoid any hacky or insecure solutions. > > > > *>> I could see this hindering the user experience if you have a gadget > asking a user to do the OAuth dance with itself.* > > Agree, this is a concern that would need to be addressed before our > release ships. > > For case (a), our current implementation so far opens the OAuth dialog > pop-up window and Shindig > quickly closes it via the response from the OAuth2CallbackServlet; since, > the user has already authenticated > with the Authorization Server. This event results in a dialog "flash" > which is irksome from a user experience perspective. > Shouldn't the user still have to "grant access" to the gadget even though they don't have to log in? > > > For case (a), Adam mentioned that his team successfully implemented a > custom gadget feature > that facilitates the OAuth dance via a hidden iframe. For case (b), they > fall back to using the oauthpopup feature if their > custom feature is not detected in the container (via hasFeature). This is > definitely a solution we are looking to explore as well. > > > > *>> Shindig has guice modules which are responsible for fetching and > storing access tokens (keyed on the gadget and the user). * > *>> If you could point Shindig at the place where the access tokens are > stored than Shindig could use those access tokens.* > *>> Essentially it might make sense to have a centralized store for > access tokens that both the application/container and the Shindig server > use.* > > e.g. > org.apache.shindig.gadgets.oauth2.persistence.sample.OAuth2PersistenceModule: > > This is a very good idea. > I'm going to bring this suggestion to our PMC / architects. > > > *>> What questions do you have about OAuth popup? There isn't really > much complex code in there. * > *>> The one tricky think to keep in mind is that the OAuth callback > servlets do interact with the JavaScript in that > >> feature. For example that is how the popup window is closed > automatically.* > > Yes, I see now that the pop-up window is closed via a successful response > from the OAuth2CallbackServlet. > i.e. org.apache.shindig.gadgets.servlet.OAuth2CallbackServlet.RESP_BODY > > One concern I have with this flow is that the gadget is informed via the > callback that > authentication was successful; but, has no way to know whether the second > part of the OAuth 2.0 > dance completely successfully (i.e. Shindig successfully exchanged the > authorization code with > the Authorization Server for the access token). Unless I'm missing > something, there is no > communication between Shindig (client) and the gadget (user-agent) in > order to notify the gadget > that it is safe to perform another makeRequest operation. Ideally, we > would like to automatically > perform another makeRequest once the OAuth pop-up dialog closes (like the > sample OAuth > gadgets provided by Shindig); however, it can result in infinite OAuth > pop-up windows being opened > if something goes awry during the token exchange (if gadget safeguards are > not put in place). > > Is this a valid concern? > As long as the gadget isn't kicking off the OAuth dance without user interaction you won't get stuck in an infinite loop. Generally the user has to click a link/button to start the OAuth dance. I do agree that there is no distinction between having to do the OAuth dance because there was an error or because it just hasn't been done before. > > After reading the OAuth 2.0 specification, it seems to be a problem with > the specification - not Shindig. > > > > *>> But I am guessing you should be able to enable logging for Shindig > the same way you would do for other apps > >> in the web container.* > > Yes, I figured it out. > In my Shindig development workspace, I configured my Tomcat server launch > to include the following > Java system property in the "VM arguments" section: > > -Djava.util.logging.config.file=<path>\Workspaces\Jazz\ShindigTrunk\Servers\shindig-project-config\logging.properties" > Yup I actually just had to do this yesterday as well ;) > > > -------------------------------------------------------------------- > logging.properties > -------------------------------------------------------------------- > handlers=java.util.logging.ConsoleHandler > java.util.logging.ConsoleHandler.level=ALL > java.util.logging.ConsoleHandler.formatter= > java.util.logging.SimpleFormatter > .level=INFO > > # *Shindig* gadgets > org.apache.shindig.gadgets.level=FINEST > -------------------------------------------------------------------- > > > > *>> There are a lot of them, as far as which ones are related to grant > types I am not sure. * > > Found them. > I am using a variation of the following handlers (copied and referenced in > their own module): > CodeAuthorizationResponseHandler > CodeGrantTypeHandler > (which are injected via Guice by this module: OAuth2HandlerModule) > > > Thanks, > > Mike > > > > [image: Inactive hide details for Ryan Baxter ---2013-10-02 07:41:17 > PM---Mike I will try to answer some of the questions the best I ca]Ryan > Baxter ---2013-10-02 07:41:17 PM---Mike I will try to answer some of the > questions the best I can, but I don't think I can answer every > > From: Ryan Baxter <rbaxte...@apache.org> > To: "dev@shindig.apache.org" <dev@shindig.apache.org>, > Date: 2013-10-02 07:41 PM > Subject: Re: Questions about configuring outbound SSO / OAuth 2.0 support > in Shindig to facilitate gadget makeRequest calls > ------------------------------ > > > > Mike I will try to answer some of the questions the best I can, but I > don't think I can answer everything. Hopefully I can get your going > in the right direction. First at a high level I am wondering if you > are trying to avoid the typical OAuth dance where the user has to log > in and grant access to the app/gadget? I could see this hindering the > user experience if you have a gadget asking a user to do the OAuth > dance with itself. > > On Tue, Oct 1, 2013 at 7:25 PM, Mike Pawlowski <mpaw...@ca.ibm.com> wrote: > > > > > > Hi, > > > > > --------------------------------------------------------------------------------------------------- > > Use Case > > > --------------------------------------------------------------------------------------------------- > > > > We are trying to integrate a Shindig application as a direct member in > our > > SSO group based on the > > OAuth 2.0 protocol (i.e. Assigned a client key and secret). > > Specifically, we want to be able to execute a makeRequest from a gadget > > against a protected > > resource located on member applications in the SSO group. > > > > > --------------------------------------------------------------------------------------------------- > > Problem > > > --------------------------------------------------------------------------------------------------- > > > > Unfortunately, I haven't had any success in configuring Shindig to work > > out-of-the-box with > > our SSO Authorization Server. Ostensibly, our Authorization Server does > not > > strictly conform to > > the OAuth 2.0 protocol (http://tools.ietf.org/html/rfc6749 ). > > > > We support a variant of the Authorization Code flow with an SSO twist. > > > > e.g. We use response and grant type values that differ from the > > specification: > > > > 4.1.1. Authorization Request > > response_type > > REQUIRED. Value MUST be set to "code". > > > > 4.1.3. Access Token Request > > grant_type > > REQUIRED. Value MUST be set to "authorization_code". > > > > > --------------------------------------------------------------------------------------------------- > > Questions > > > --------------------------------------------------------------------------------------------------- > > > > (Q 1) As a meta-question, what is the recommended way to configure > Shindig > > to facilitate gadget makeRequest calls to protected resources using SSO / > > OAuth 2.0? > If you are just looking to test OAuth with Shindig out of the box the > only thing you need to worry about configuring is the oauth.json and > oauth2.json files. For example if you want to test the > oauth2_google.xml gadget in the sample container in Shindig you would > have to go to the Google API Console register the gadget to get an API > key and secret and then add them to the oauth2.json file. > > > > I just want to validate whether we are taking the right approach by > making > > Shindig directly participate as a member our SSO group. > > I'm following the OAuth 2 examples shipped with Shindig > > (e.g. /gadgets/oauth2/oauth2_google.xml) > > > > On the surface, the easier alternative would be to get the access token > and > > pass it in as a parameter to the makeRequest call > > (essentially Shindig would strictly proxy the request to the protected > > resource rather than explicitly handle authorization). > > i.e. > > params[gadgets.io.RequestParameters.OAUTH_REQUEST_TOKEN] = "some-token"; > > (or "some-token" is provided as a value to some custom Authorization > > header) > > This is generally discouraged. All information related to OAuth is > kept on the server. When the gadget makes a request the requires > OAuth the proxy will add the access token to the request if it has > one. If it doesn't have one will send back the authorization URL for > the gadget to then use the oauth-popup feature to do the OAuth dance. > > > > > In our case, the OpenSocial gadget container is located on a page that is > > itself a protected resource. > > The user will already be authenticated with our Authorization Server and > > the server hosting the > > page / OpenSocial gadget container will already have the corresponding > > access token. > > Unfortunately, the server hosting the page is on a different domain than > > the Shindig server. > > As a result, securely passing the access token to the gadget container / > > gadget is very problematic. > > I'm not sure if there is API in the Common Container that we could > leverage > > or some other established > > procedure / method we could employ to get the access token securely... > > > Shindig has guice modules which are responsible for fetching and > storing access tokens (keyed on the gadget and the user). If you > could point Shindig at the place where the access tokens are stored > than Shindig could use those access tokens. Essentially it might make > sense to have a centralized store for access tokens that both the > application/container and the Shindig server use. > > > Is there another option (i.e. Third approach)? > > > > Also, I'm curious if you know if other Shindig consumers have similar SSO > > integration requirements and how they > > implemented their support with respect to gadget makeRequest calls. It > > would be a good point of reference. > > > > > > (Q 2) Is there any documentation or guidance or examples on configuring > > SSO / OAuth 2.0 support in Shindig and gadgets? > > > > I'm currently reverse engineering the Shindig source to figure out > things, > > relying on > > comments in the various configuration files and reading the relevant > > gadget / RFC specification > > > > e.g. > > > http://opensocial-resources.googlecode.com/svn/spec/2.5/Core-Gadget.xml#gadgets.io.makeRequest > > > > > http://opensocial-resources.googlecode.com/svn/spec/2.5/Core-Gadget.xml#OAuth > > > > http://tools.ietf.org/html/rfc6749 > > > > For example, I noticed that there appears to be a degree of magic being > > used in the "oauthpopup" gadget feature > > to handle the OAuth 2.0 user authentication and redirection flow - which > > isn't explained to a large degree. > > > This link might be helpful > > https://cwiki.apache.org/confluence/display/SHINDIG/OAuth+2.0+Service+Provider+Implementation+in+Apache+Shindig > > What questions do you have about OAuth popup? There isn't really much > complex code in there. The one tricky think to keep in mind is that > the OAuth callback servlets do interact with the JavaScript in that > feature. For example that is how the popup window is closed > automatically. > > > > > (Q 3) What are the OAuth 2.0 / SSO specific classes / configuration > files / > > etc I should be focusing on or be aware of? > > > > I'm just trying to get an inventory of all the Shindig files I need to > > modify or potentially be aware of (for debugging purposes) that would > > assist me > > in my integration task: > > > > e.g. Examples > > /gadgets/oauth2 > > > > e.g. Configuration files > > /WEB-INF/classes/config/oauth2.json > > shindig.properties > > > > e.g. Servlets > > > /src/main/java/org/apache/shindig/gadgets/servlet/OAuth2CallbackServlet.java > > > > e.g. Packages / Classes > > org.apache.shindig.gadgets.oauth2 > > > > e.g. JavaScript > > src/main/javascript/features/oauthpopup/oauthpopup.js > > > > Anything else? > > > I think that covers it. > > > > > (Q 4) How do I enable server logging in Shindig? > > > > I'd like to start by turning on all Shindig server logging across the > board > > and then progressively > > filtering it down by log level and then only by OAuth specific classes: > > e.g. > > > > if (OAuth2CallbackServlet.LOGGER.isLoggable(Level.FINE)) { > > OAuth2CallbackServlet.LOGGER.log(Level.FINE, " callback > exception " > > , t); > > } > > > > Is it just a matter of adding a log4j.properties file in a certain > > directory and configuring by class? > > e.g. > > log4j.logger.net.jazz.ajax.service/ProxyOperation=TRACE > > log4j.logger.net.jazz.ajax.service/AuthClient=TRACE > > > > Hmmm haven't done this one yet. But I am guessing you should be able > to enable logging for Shindig the same way you would do for other apps > in the web container. > > > > > (Q 5) How do I inject support for custom OAuth 2.0 grant types into > > Shindig? > > > > Assuming we are following the right approach defined in the "Use Case" > > section and (Q 1), there > > appears to be injection points for consumers to add support for custom > > grant types (which I *believe* is required in our case): > > (a) org.apache.shindig.gadgets.oauth2.handler.GrantRequestHandler > > (b) > > > org.apache.shindig.gadgets.oauth2.handler.AuthorizationEndpointResponseHandler > > > > Are there any other injection points that are relevant to the SSO / OAuth > > 2.0 integration task? > There are a lot of them, as far as which ones are related to grant > types I am not sure. At some level I am sure most of the OAuth > implementation is replaceable via Guice injection however there are > probably only a few key pieces that you probably want to replace. > There are several Guice modules for OAuth in the web.xml, that is > probably the best place to start. > > > Just to confirm, is this accomplished via Guice? > > Is this the best resource for learning how to use Guice: > > https://code.google.com/p/google-guice/ ? > That and a little bit of debugging ;) That is how I learned anyways. > > > > > > > Thanks in advance, > > > > Mike > > > > >