On Jul 15, 2014, at 2:50 PM, Silvano Nogueira Buback <silv...@corp.globo.com> wrote:
> @Rohit Yadav > I know OAuth2 is tricky and the protocol was designed for authorization, > not authentication. But Globo.com, like many companies, use OAuth2 for > authentication. So, SAML is not a option to me. I need to integrate with > internal tools at Globo, and these tools work only with OAuth2. > > @Sebastien > API are accessed by user, as today, using apikey and secretkey. OAuth is > only to UI. To me a UI only OAuth would defeat the purpose. Google GCE has OAuth for it's API usage. If you were to change it a the API level then you would have it in the UI. > > @David, > Thank you. I will look this lib. > > @Edukulla > I try to summarize your questions: > > * In the code below, you can see all parameters needed to configure OAuth > authentication with Google, Github and Globo. My idea is that they are > global options (there are more global options than I sent before). Other > providers may not work, this list is for the first plugin release. People > can help integrating more providers. > * Pay attention with the way to get user email. This is really tricky, > because this is not part of specification. But if all providers answer json > and have a key named "email", the implementation will work. Google, Github > and Globo.co already do this. > * ClientId and secret may store encrypted in Global Options, like others > password. > * As the number of global options increase, I create an option called > "oauth2.enable", if you want to enable plugin. Of course, > if all parameters are not set, doesn't matter if plugin is enabled or not. > * The idea is not to authorize resources, is only to authenticate. So, I > don't need to store access key. When user accesses > UI, he is redirected to oauth2 server, and if authorization was granted > before, oauth2 server will redirect user to cloudstack without asking for > permission. This works with all 3 providers. I need only to have access to > email when the session starts, and then cloudstack keeps its own session. > > The big problem is with domainid, that must be an global option. Other > problem happen with new accounts. May I create new user in an existed > account. The account name for new users are stored in global settings too. > At Globo.com we are discussing, but I guess if a user is not in cloudstack > they can't logged using oauth. Like happen in ldap. > > Bellow I put some code to show that OAuth is not different between these 3 > providers. > > I will start the development of this feature next week. So, I will > appreciate all comments to help me to understand problems. After I start I > will create the design document. > > > ------ BEGIN CODE ------- > # before run: pip install requests_oauthlib > import sys > # Credentials you get from registering a new application > app = sys.argv[1] > print "For app %s" % repr(app) > > redirect_uri = 'https://localhost:8000/' > > if app == 'globo': > client_id = 'XXX' > client_secret = 'XXX' > authorization_base_url = "XXX" > token_url = "XXX" > user_url = 'XXX' > scope = [] > elif app == 'github': > client_id = 'XXX' > client_secret = 'XXX' > authorization_base_url = "https://github.com/login/oauth/authorize" > token_url = "https://github.com/login/oauth/access_token" > user_url = 'https://api.github.com/user' > scope = ['user'] > elif app == 'google': > client_id = 'XXX' > client_secret = 'XXX' > authorization_base_url = "https://accounts.google.com/o/oauth2/auth" > token_url = "https://accounts.google.com/o/oauth2/token" > scope = [ > "https://www.googleapis.com/auth/userinfo.email", > "https://www.googleapis.com/auth/userinfo.profile" > ] > user_url = 'https://www.googleapis.com/oauth2/v1/userinfo' > else: > print "UNKNOW APP" > sys.exit(1) > > from requests_oauthlib import OAuth2Session > oauth2_session = OAuth2Session(client_id, scope=scope, > redirect_uri=redirect_uri) > > authorization_url, state = > oauth2_session.authorization_url(authorization_base_url) > print 'Please go here and authorize,', authorization_url > > # Get the authorization verifier code from the callback url > redirect_response = raw_input('Paste the full redirect URL here:') > > # Fetch the access token > oauth2_session.fetch_token(token_url, client_secret=client_secret, > authorization_response=redirect_response) > > # Fetch a protected resource, i.e. user profile > r = oauth2_session.get(user_url) > print r.json() > print "email=", r.json()['email'] > ------ END CODE ------- > > > > > > > On Tue, Jul 15, 2014 at 5:34 AM, David Nalley <da...@gnsa.us> wrote: > >> https://oltu.apache.org <-- maybe as a starting place. >> >> On Tue, Jul 15, 2014 at 3:25 AM, Sebastien Goasguen <run...@gmail.com> >> wrote: >>> Silvano, >>> >>> Seems to me you are doing it for browser based dashboard access only ? >>> >>> How about if I want to use the API straight up, how do you integrate an >> Oauth workflow there ? >>> >>> On Jul 15, 2014, at 1:35 AM, Santhosh Edukulla < >> santhosh.eduku...@citrix.com> wrote: >>> >>>> Hi Silvano, >>>> >>>> Few Notes: >>>> >>>> 1. We had implementation details mentioned i believe, but we didn't >> mentioned the design details and workflows. >>>> 2. We didn't mentioned whether it is 2 legged flow or 3 legged flow. >>>> 3. Not clear with this statement, "Once user is authorized by oauth2 >> server, javascript code reads parameters in url", >>>> 4. Whats the difference between "oauth2.credentials.url" and >> "oauth2.baseurl", the later is redirect uri? If yes, Where will have >> redirect uri hosted? >>>> 5. referring to the statement " When oauth2.baseurl, oauth2.client.id >> and oauth2.client.secret are not set (default), oauthRequestUrl returns >> empty response and OAuth2 >>>> authentication is turned off.", can we use a flag to denote whether to >> use oauth flow or not? If set to false, dont use it otherwise continue with >> default. >>>> 6. What about refresh token,i believe access token has limited life >> time? Any call back mechanism to update with latest token if it gets >> expired? >>>> 7. Details like clientid,clientsecret needs to be encrypted when stored >> and retrieved from global config? >>>> 8. How do we map the user logged in to roles and hierarchy inside CS? >> based on email mapping? >>>> 9. What is the significance of these two parameters mentioned? >>>> oauth2.credentials.parameter.email (defaults to "email") >>>> * oauth2.domainid >>>> 10. clientid and clientsecret key are based upon per tenant basis, so >> what if we want to oauth mechanism from multiple tenants at any stage? >>>> 11. Default values for clientid and clientsecret are loaded at which >> stage? during initial installation and for which tenant? >>>> 12. How do we verify the validity of clientid and clientsecret values? >> If they are revoked? possibility of revoke is there? >>>> 13. If we understand, it is only to authenticate a user through oauth >> flow, we dont need authorization part inside of cs? I mean, what do we mean >> by authorization from tenant once access key is granted? >>>> 14. If access key is not stored, how do we get refresh token? >>>> 15. What is the default sequence of authentication in case if oauth >> fails? and order in which a given authentication mechanism will be chosen? >>>> 16. Can we also show a ui, where user can enable\disable oauth setting >> for a given account? here, possibility of mismatch with emailid based upon >> current implementation and oauth retrieved emailid post authentication is >> there? how do we handle it? >>>> 17. Last, what is the significance of this feature, apart from >> authentication support from third party clients? >>>> >>>> >>>> Thanks! >>>> Santhosh >>>> ________________________________________ >>>> From: Silvano Nogueira Buback [silv...@corp.globo.com] >>>> Sent: Monday, July 14, 2014 4:59 PM >>>> To: dev@cloudstack.apache.org >>>> Subject: [PROPOSAL] OAuth2 Single SignOn Integration >>>> >>>> Hi gyus, >>>> >>>> I need to implement OAuth2 integration to provide single sign-on with >>>> others tools in my company. I can share this implementation with the >>>> community if you are interested. I suggest these changes in code: >>>> >>>> 1. Create a new javascript called oauth2.js. This javascript is >> responsible >>>> for calling the new command called oauthRequestUrl that reads the global >>>> option "oauth2.baseurl" and returns this url plus "/authorize" with >> oauth2 >>>> parameters. After receiving the answer, javascript redirects user to >> oauth2 >>>> server. >>>> 2. Once user is authorized by oauth2 server, javascript code reads >>>> parameters in url and call oauthAuthorizeToken command. This command >> asks >>>> the oauth2 server by the access token, and if everything is ok, calls >>>> "oauth2.credentials.url" about user email and finds this user in the >>>> database, like ldap implementation does and returns authentication data. >>>> 3. Javascript fills g_loginResponse with answer from command and user is >>>> logged in. >>>> >>>> What do you think about this approach? >>>> >>>> >>>> ---- More details ---- >>>> >>>> Alternative flows: >>>> >>>> * When the url has parameter direct=true, the login dialog is shown. >>>> * When oauth2.baseurl, oauth2.client.id and oauth2.client.secret are >> not >>>> set (default), oauthRequestUrl returns empty response and OAuth2 >>>> authentication is turned off. >>>> * If authorization token is invalid, user is redirected again to oauth2 >>>> server. >>>> >>>> >>>> Commands: >>>> * oauthRequestUrl >>>> * oauthAuthorizeToken >>>> >>>> >>>> Global Options: >>>> * oauth2.baseurl >>>> * oauth2.client.id >>>> * oauth2.client.secret >>>> * oauth2.credentials.url: defaults to "/oauth2/v2/userinfo" >>>> * oauth2.credentials.parameter.email (defaults to "email") >>>> * oauth2.domainid >>>> >>>> >>>> Restrictions: >>>> * Domain Id will be a global option >>>> * Users are always redirected to oauth2 server. Access tokens are not >>>> stored. >>>> * Before using Cloudstack, the administrator must insert user in an >> account. >>> >>