字幕表 動画を再生する 英語字幕をプリント RYAN BOYD: Hello, everyone. I hope you're all here for the OAuth 2 session. How's your day been going thus far? AUDIENCE: [INTERPOSING VOICES]. RYAN BOYD: Good, good, awesome. My name is Ryan Boyd, and I am a developer advocate here at Google. OAuth 2 isn't really my day job. It's just a passion of mine. Normally, by the day, I'm working on our cloud data services like Google BigQuery, but OAuth 2 has been a passion of mine since I started in Google at about 2006. I was working on our proprietary authorization protocols, AuthSub and ClientLogin, and I realized how painful doing authorization for our APIs was for developers. And frankly, I think most developers spend about 80% of their time dealing with authorization, and then the other 20% of the time dealing with the actual APIs that they were using, and that's kind of sad. And it was especially problematic because, back then, there were these proprietary protocols across many different API providers, so if you learned how to interact with Google's APIs using ClientLogin or AuthSub, and you went over to Yahoo, you might have to use BBAuth. You went to other providers, you have to use other protocols, and this is really painful. So I'm super happy that we've standardized on OAuth for authorization. We had OAuth 1, and that was still a little bit of painful for developers to use. At least, it was standard across many providers, and now we're at OAuth 2. The draft is nearly complete, any day now, I think. And with OAuth 2, things got a lot easier for developers, and we'll show you how it works. OAuth 2 is such a passion of mine that I actually recently released a book, a few months ago, with O'Reilly, talking about OAuth 2. It's a very short book, but gives you a good introduction in about '90 pages, I believe. So in order to understand OAuth, we first need to understand a variety of different terms. I went sailing last weekend, sailing school, and sailing is all about terminology. There's way too many terms even for me to remember. Hopefully, OAuth will be a little bit better than that, but there are various terms. So we're going to introduce a couple terms up front here, and then throughout the talk, we'll give you some additional terms that are little bit less important, but are nonetheless things that are essential to understand OAuth. So the first term is authorization. Sorry, authentication. See, even I'm mixing these two up. All right, pause here a second. Authentication. Authentication is about verifying the identity of a user, knowing the user is who they say they are. When you go and visit a website, and it asks you to login, you type a user name and password, that website verifies that you've typed the right password for that account, and thus has authenticated you. It's validated your identity. But after it authenticates you, it needs to figure out what resources you should have access to, and that's what authorization is all about, making sure that you have access to your data and only your data, or the very least only appropriate data. So if you went and logged into your email account, and you had access to your colleague Tom's email, this would be a bad thing. So that's what authorization is all about, making sure that you have access to only the right information. Questions for you. How many of you ever shared a password with an application, a third party app, so it can access your data on something like Google or Twitter or Facebook? Raise your hands. All right, some of you are just being shy here, because I'm pretty sure everyone in this audience has done that at some point in time, and this is obviously very bad for the security of you. And it's also very bad for the security of users as, after all, you guys are developers. You have plenty of users. You should never be asking them for their passwords for any of the major account holders. So you have an opportunity. You have an opportunity, as developers, to eliminate the need for users to reveal the passwords to your application. At the same time, you have an opportunity to restrict the level of data available to your application to only what your application needs in order to make a good experience for your users. And then you have an opportunity to allow the users to revoke access to your app when your application no longer needs access to their data. This is your opportunity, but it's important to understand. I believe that you have an obligation to your users, an obligation to help keep your users safe. And so you have an opportunity, but also a responsibility here. A few more questions for you. Sorry, that was what OAuth 2 for authorization is all about. Now, we'll get into a few more questions. Do you use the same user name and password for multiple sites? How many of you do that? Tell you a little story here. Of course, everyone does this. I think it was like a week or two ago when some major website, which I won't name, managed to get a lot of their passwords leaked out onto the web. And I didn't know about this, and I looked over at one of my colleagues, and he was looking really sad. And I'm like, Sean, why are you looking really sad today? And he told me that now that his password was leaked out there on the web, he has to go change his password, not only on this site, but on dozens of other sites around the web, and he didn't even know what those sites were. So he was basically thinking, you know what, I had some free time this evening. No longer do I have any free time that evening, or maybe even the next couple days. So he was really sad about this, and you don't want to be in the position of being sad. And as developers, you don't want to make your users sad, or have a risk of making your users sad. Another question. How many keystrokes do you type when you sign up for a new account? Call out some answers. AUDIENCE: [INAUDIBLE]. RYAN BOYD: All right, all over the board. Some of you have much longer passwords than others, I guess. I think I type about 50 characters. I have a relatively short name even if I do use longer passwords. 50+ characters. My first name, my last name, my email address, password once, password confirm. That's a lot of characters to type when you sign up for new account. What if you could drop that down into two mouse clicks instead of 50 plus characters typed on the keyboard? So again, you have some opportunities. You have an opportunity to minimize the number of passwords your users need to remember. You an opportunity to discourage reuse of passwords. And then you have an opportunity to optimize the sign up flows for your application to get users on board faster. If you get users on board faster in your application, then you get more and more users, and hopefully, you become wealthy with the next IPO. And this is what OAuth 2.0 for login is about. And I use that term because that's the term we use in our documentation. Externally, you'll see this as OpenID Connect or OAuth 2 for Authentication. All sorts of different terms, but they all mean the same thing. So our agenda, we talked about some terminology. Next we're going to go into authorization and go through how you do authorization in a variety of different environments, whether you're in a pure JavaScript environment on the browser, or whether you're doing a server-side environment with server-side code, or whether you're doing a mobile environment, or even some newer things with service accounts. And then we're going to get into authentication, and lastly, end up with a set of resources that will hopefully be very valuable to you, including a link to the slides so you don't need to be furiously taking notes. All right, so OAuth 2 for Authorization. Google has 35+ APIs which are enabled for OAuth 2 authorization. Now, I say 35+. I've had these slides for a bit. I tried to count this morning. There is probably many more than this, but at least 35 APIs that Google has that you can use OAuth 2 to get authorization for, and this is everything from Calendar and Contacts to things like YouTube and Google+. All the Google APIs, when they require authorization, support OAuth 2. And not only do we have 35 APIs at Google, there are hundreds of other APIs around the web, which use OAuth for authorization. Many of them are still an OAuth 1, but I'm sure they'll be upgrading soon to OAuth 2. Now, your goal when working with OAuth is to get access to a user's data in one of these APIs. In order to accomplish that goal, you need to get a token. This is what a token looks like. Well, not really, but this is a image to represent an access token. OAuth 2 works off the concept of access tokens, and all the various OAuth flows that we're going to show you here today, your goal is to acquire one of these access tokens. And this access token if then used to access an API on behalf the user. So in each of the flows, we're going to show you how to get an access token. And then a little bit later in the presentation, we're going to actually show you how to use that access token to access the API, but trust me, once you have this access token, you're all set. All right, so to get started, the first thing that you need to do to get started with OAuth is to register your application. You can visit the Google APIs console, and you can register your application, and this will give you all the information that you need to get started with OAuth, in particular ClientID and also some other information. So you can access that now on the new developers.google.com site, developers.goggle.com/console, and you can register your app. So let's get into it. Let's get to the pure JavaScript flow. If you're developing client-side applications that require only the browser, how many of you work mostly in JavaScript? OK, handful of you. For those people that like the server-side code, we're going to come up with some other things here later. But the most simplistic flow is this pure JavaScript flow, and it works something like this. I'm going to go through a diagram here, and then I'm going to go into the actual code in one of our client libraries. And then I assume, because you guys are in a session on OAuth 2, that you want to know how it works underneath the cover, so I'm going to go into the raw protocol as well. So the first thing that we have here, and it's a little bit small, but we have this fake app called Taskman, and Taskman displays your tasks from your Google Tasks. And Taskman says to the user we need access to your Google Tasks and gives you a button to click on and say go to Google to grant authorization. Pops open a window that looks something like this, where Google says that Taskman is requesting access to your Google Tasks, and you're given the option to allow it or deny it. If you allow it, it's going to redirect you back to the Taskman application. And you're going to notice here, at the top right, we have an access token, and this access token is in the hash fragment of the URL. What that means is this access token is sent only through the web browser and doesn't actually get sent back to the web server where the Taskman application is coming from. It's only in the web browser. And then in JavaScript code, we use that access token to call the Google Tasks API servers. And I believe Google Tasks now supports cores, but you could also use JSONP and that sort of thing. All right, so let's show you how it works. I'm going to give you a quick demo with the real code, and in this case, the slide deck is my Taskman application. So I'm going to say let's see it in action, and it's going to pop open-- this is actually a pop up window, but since I'm in presentation view, it looks like I replaced the window. But I'll hit Allow Access, and in there are my Google Tasks. My Google Tasks have been printed out right in this presentation. The beauty of using HTML5 for your presentations so you can embed this stuff right in there. So this had access, using JavaScript, to my Google Tasks. This was done using the JavaScript client library, and the JavaScript client library to do this sort of thing is just a handful of lines of code. First off, some configuration. You can see the client_ID. The client_ID is a value that we've acquired from the Google APIs console. And then we see the scope. The scope in OAuth is basically a string. In Google's terms, we put this in a URI, and this URI basically says that my application's looking for access to Google Tasks. You can specify more than one scope, and I'll show you how that works later, but for now, we're asking for Google tasks. And then there's a callback handler there, and that callback handler has access to the actual access token. And we just do a quick JavaScript alert here, and thus, we've reached our goal, and we have an access token. Here's how it works in JavaScript under the covers, like I said. The client library really does a lot of this for you, but you're in a session on OAuth, you probably want to see what's happening under the covers. So here, you're defining a client_ID, the base of Google's URLs for OAuth provider. The redirect URI. The redirect URI's simply the application's URL. Then the scope, the tasks API again, and then we're just building up, concatenating a string to really ugly, tacky way, but concatenating a string together to build up this URL. Then we're opening up a popup window to this URL. Here's what that URL looks like. And that results in a screen that looks like this. The user hits Allow. The user's redirected back to the application. And you can see that hash fragment there, and in that hash fragment is an access token. This is the token that allows you to access the API on behalf of the user. And then there's also a token_type=bearer. Basically what this means, they're called bearer tokens, and bearer tokens-- all you need to do to get access to the user's data on behalf of a user is to present one of these bearer tokens. And OAuth 2 really adds this simplification. Most of OAuth 2 does not require cryptographic signatures, but it assumes that your API calls are being made over SSL, so it's OK to pass this bearer token in the actual HTTP request. And then we have expires_in=3600. It's 3,600 seconds or 60 minutes. And we reached our goal. We have this access token. So questions that you might have. We are going to have a Q&A period at the end. You can come up to the microphones at the end, but I'm going to predict a couple questions here that you might have for this particular flow. And the first is how do you get the token back from the popup window back to the application? So there's HTML5 postmessage is one great way to do it. If you're looking to support some older web browsers, you can use window.opener in JavaScript to pass it back. I've used both of them. Both work, but if you're supporting just modern web browsers, the HTML5 postmessage is probably the best way to go. How do you get another access token? Well, you saw that that access token expired in 3,600 seconds. So in 3,600 seconds, you're going to need to get another access token, and you can do this by running the exact same flow over again. So you do the exact same thing, and only this time around, the user's not going to be prompted for access to their data because the user's already granted access to their data. And this does do the popup window and all. You can actually do it without the pop up window. There is a way to do that with OAuth, at least Google's OAuth provider, and you can ask me about that later if you have any questions on that. But it makes the user experience a little bit easier. And then what happens if the user's not logged in? If the user's not logged into their Google account at the time they go through this OAuth flow, they will be prompted to log in. So we kind of assume that, most times, the user is logged into their Google account, and so the user will have to log in if they're not. So you use the client-side flow if you're looking for simplicity. You'll see the diagram here soon. It's a little bit more complex to use some of the other flows. If you like to do coding in JavaScript, you only need to access when the user is logged into Google. And there's some more information about our JavaScript library at a session that already happened, but you should be to catch it on YouTube. "Building Web Applications that use Google APIs and the JavaScript Client for Google APIs." A very descriptive session title. All right, the vast majority of you seem to not raise your hand when I asked you if you code mostly in JavaScript, so I'm assuming you're looking for server-side code. I'm going to show the server-side code in Python here. This is using our Python library. We have, I think, nine client libraries that all support OAuth 2, so you can use it in a variety of different languages. I'm just using Python for this demo here. And we'll start off with one of these diagrams, step by step. The first step looks the same. The user experience here is the same. The user gets prompted and said, hey, this application needs access to Google Tasks. They go over to Google, and they get this screen. It looks very similar. The only difference here is the line at the bottom that says it needs access when you're not at your keyboard. So in this case, for the server-side flow, we're getting access to user's data even when the user's not actively logged into their account. The user approves, then it redirects to the application with this authorization code. The authorization code, you notice, is passed in a query parameter, not in the hash fragment, and the authorization code is sort of intermediate code that's used to eventually get an access token. Because it's passed in the query parameter, though, it is passed to the back end web server of the Taskman applications. So the Taskman application gets that code, and then calls over to the OAuth provider and exchanges that code for an access token, which is then uses to call the API. So slightly more complex than the previous flow, but it has this added benefit of giving you the ability to get offline access to the users data. So let's step through it in Python. A bunch of configuration stuff up front. So you can see here, we have a client_ID, and we have a scope. You saw those before. We additionally have this client_secret. This client_secret also comes from the API's console. When you register your application, we give you a client_secret, and then you can use this client_secret with the web server flow here. You might wonder why do I have a client_secret here, and I didn't have a client_secret in the previous example in JavaScript. The client_secret just adds an additional level of security. It basically authenticates your app when your app is talking to the OAuth provider. And security is all about adding these additional layers, and we think it's important to add additional layers when you're getting higher levels of access. So in this case, you're getting access while the user's offline, so there's a little bit more security here. And then you basically just generate a URL and redirect the user over to the URL. This is exact same as you saw with the JavaScript flow. The URL will look something like this. The only two parameters that are different in that URL are the response type of code instead of Token and then the access type of Offline, saying you really do want offline access to a user's data. You could also do the authorization code flow, or the server to server flow, without offline access, but most people are using it because they need offline. Here's our approval prompt screen in a real screen shot here. Perform these operations when I'm not using the application. And then the user is redirected back to the application, and you can see that authorization code as a query parameter. Then the server exchanges that authorization code for an access token. It's really just one method call here. The flow step2_exchange, passing in the request parameters, which includes that authorization code. And we're getting back a credentials object, and that credentials object has the access token in it. And we've reached our goal. We have an access token. You guys excited we have an access token? All right. We also, additionally, have one other bit of data. We have a refresh token. This refresh token used to get access later. If we need access after the 60 minutes, we can use this refresh token to get access. And we'll show you how that works here shortly, but first, I want to show you the raw protocol of what's happening underneath the covers for when you're using this Python code. It's basically just and HTTPS post to Google's OAuth provider, and passing those five lines there, we have the grant type of authorization code, the code itself, and then the client_secret. The client_secret, again, authenticates your application to the OAuth provider. And Google returns a nice little bob of JSON, looks something like this, and again you have that access token and also the refresh token. So when you want to take that access token and use it, normally you would have validity for 60 minutes here. But when that's up, and you need another access token, you use that refresh token. So what code do you have to do exchange that refresh token for an access token? There's not much here. Really just one line of comment because the client library actually does this for you. The client library automatically will exchange your refresh token to get a new access token as is needed. But again, you probably want to know what the client library's doing under the covers, and it's really a simple HTTPS post again. And this post is saying, here, I have this refresh token. Here's my client_secret grant type refresh token, and again, getting back a new access token. You can do this either when the token already has expired and you know it does not work, or you could do it as soon as you get a failure, or you could do it in advance. You could say, hey, this expires in 3,600 seconds. I'm going to start a timer and automatically refresh in less than 3,600 seconds. Our client libraries, I think most of them actually do this refresh in advance for you. It keeps track of the time. Some of them may actually wait until it gets a failure. The difference in performance isn't huge, but the client libraries will handle this for you. So again, questions that you might have at this point? When do these refresh tokens expire? Does anyone want to guess? AUDIENCE: [INAUDIBLE]. RYAN BOYD: Correct. The refresh tokens never expire unless the user revokes access, and some people might not call that expiration. But a user can revoke access, going to their Google accounts and managing the list of APIs they've authorized. And thus your refresh token will no longer be valid, and you'll have to start the user over in the normal flow. Where do you store these refresh tokens? You typically store these refresh tokens in your database alongside your user account. So you get one refresh token for every grant of a particular scope. If you do a grant of multiple scopes, which we'll see here shortly, you'll still get one refresh token for those multiple APIs, and you store those in your user database. Now, those refresh tokens in themselves aren't really that valuable, so it's OK to just store it in your user database. But when combined with the client_secret, they are very valuable. So you want to keep your client_secret in a secure key store or something like that on your server and make sure to limit access to that client_secret because combine the client_secret with a refresh token, and you get a new access token for any of you users. So I want to show you one other thing here. The code before wasn't that challenging, but we can even make it easier. So this is showing you the decorator flow, or decorator handler, in the Python library. When running on App Engine, we can just define a few variables up top, and then just add this decorator to our web methods and basically say, hey, OAuth is required for this method, and then we'll handle the entire flow for you. Really, you can basically, if you ignore indentation here and such, and formatting, you could do this in two lines of code. You can add OAuth support to your App Engine app in Python using this decorator method. So if you want to be lazy, go for that mechanism. There's also a OAuth Aware is another decorator that allows you to be a little bit more handle the experience, but combine these together, if makes it really easy to implement OAuth. So you're looking to your long lived access to a user data. Pretty much, if you want long lived access to a user data, you have to use the server-side flow. You also use the server-side flow if you need access when the user isn't at their keyboard or you need to call the API from server-side code. And reminder, I showed this in Python, but there's a bunch of different languages that we have support for, or you can write your own code. So you have these tokens we've reached our goal with both the client-side JavaScript flow and with the server-side flown, and you have this access token. Now, how do you use the access token to access an API? It's pretty simple. There's two different ways. There's the preferred way, which is using an HTTP header that looks something like this. You make an HTTP request, you have an authorization header, you're saying authorization bearer, and you're putting that access token there. That is definitely the much preferred way, and it is preferred because authorization headers are very rarely logged in a web server log, very rarely logged by a proxy server, very rarely cached, et cetera, et cetera. So you want to use the HTTP header whenever possible. Now, if you're trying to do JSONP, or trying to do quick debugging, you may want a different way to do this, and you can use a query parameter and pass in the access token as a query parameter in the URL here. So fairly simple either way you do it. It's really just passing that bearer token in plain text. But like I said, that plain text then gets wrapped in SSL to make sure that this is all secure. And if you want to have access to multiple APIs at once, you could just do that by specifying your scope in a space delimited list. So the space delimited list looks like this. In this case, we're accessing two separate APIs, and we've just specified both scopes separated by a space, and you use that any time it asks you for your scope field. And then the user will be presented with both APIs. You can access a bunch of different APIs it once. The user has presented it as an all or nothing decision, so they have a choice to allow access to your application for all of those or none of those. They can't be selective. How many of you are developers that build mobile applications? Wow, a lot. I would think you'd be in the Android session. Is there some bad session going on right now on the Android track? Anyway, so mobile authorization, it typically is what I've heard it as the biggest challenge for developers when working with authorization. It's very difficult to work with authorization, and mobile apps typically-- because there's not really a prescriptive way to do it. You have some decisions to make and some trade offs to make. OAuth 2 got a lot better in giving some more choice of how to do this than OAuth 1, and the spec actually talks a little bit about mobile apps, which is helpful. But in the end, they're really three different ways that you can get access on a mobile application, or for a native mobile application by OAuth. The first, which is what you see here, is an embedded web view. This is a cross platform way that you can get access to a user's data from a native mobile device, and basically, you embed a web view, which is the OAuth authorization page, very similar to the URLs that we saw earlier in the other flows, and the user gets to allow or deny access here. Now, there's some great benefits to this, considered by some, which is the user experience. You get to see the OAuth authorization page in the full screen. There's not too much context switching. But there's also some drawbacks, and the drawbacks are in two areas. One, in the user experience again, and the drawback with the user experience is that the user often times is logged in on their main web browser to their Google account. But since the embedded web view uses a different cookie store, they're not actually logged in here, so they're asked to type in their user name and password again. But that also leads to a security concern because we're not seeing the standard browser Chrome here. We're not seeing the normal indicators that this is an SSL enabled website and the certificate's been validated and things like that, so there's some security concerns. The next way, which is also cross platform, is to use the system web browser. Because the user is often already logged in, this will just require them to essentially do one tap to say Allow Access, and that's the benefit. The drawbacks are, in the UX, it is the standard browser, there's some context switching. The user doesn't look like they're still in your application, and then the other drawback is it's difficult to communicate the access token or authorization code back from the system web browser back to the application depending on the environment. There are some security concerns there that you can ask me later about. So then the third way. The third way is super exciting. It works only on Android. And it was just announced and doesn't quite work just yet, but very soon in the coming weeks, and it is the GoogleAuthUtil mechanism. This is part of the Google Play services that we just announced, and this allows you to create a much more superior user experience for your authorization screen, which looks something like this. This is Google handling it all for you. So Google is basically-- you make a very simple API call in your Android app. Google displays this screen. The user hits Allow Access. Your application gets an access token. You don't have to deal with the communication between a web browser and your application. We handle it all for you, and it's a little more secure because you're also registering your Android application. Specifically, registering a signature of your application as it exists on the Play store, and that is creating a client ID for you. So when a user sees your application in their account manager, and they're looking at the Google accounts page, they will see your specific Android application and the data that they've granted access to in your application. It's a pretty small snippet of code here. The first thing you need to do is figure out what account the user would like to grant access from. This is in email address format. So there's a way to do that where you can get a list of the various accounts for the user. You can also have us render the UI. There's another call you can make to us render the UI, but after you determine what account you want the user to grant access to, you then just determine your scope like before. And this one line of code that says GoogleAuthUtil.authenticate, passing in the context you render out the email address and the scope. Makes it so much easier. So if you're doing cross platform mechanisms, you might still have to use the other ways that I showed you here, but if you're developing your application on Android, I would definitely suggest looking at this. And we have our goal. App-based Authorization. So app-based authorization is something different. What we've seen here before is how you get access to a user's data and access data belonging to that user on behalf of them. They're granting you that access as an application. But what if your application needs access to its own data? What if your application needs access to data that belongs to the application and is kind of for all the users of your application? So think of something like Google Cloud Storage, where you can store arbitrary binary files and all, like let's say your application transcodes a bunch of videos, or something like that, and you want to store the output somewhere. Google Cloud Storage will allow you to do that, and you can upload all these files, but really, it's your application's data. It's not data belonging to any individual end user, and in that case, there's a separate OAuth flow which doesn't involve the user at all. It looks something like this. You have your app server. Your app server makes a signed request over to Google OAuth servers, and this signed request basically says I'm looking for this particular scope, and I'm identifying myself here, based on this signature, and give me an access token. And then your access token is used to access the API. So there's no user involved here. There's no web browser involved here. It's just another different way that you can use the OAuth 2 technology. The sad part is this reintroduces signed requests. How many of you liked signatures in OAuth 1? There's a few people. Even the author of the OAuth 2 spec really wants signatures to be used every day with OAuth 2, but in this case here, we do actually add signatures. And we add signatures back in, again, because of the security through layers. You're getting access to, potentially, the data that belongs to a bunch of different users, or your entire application's data, so you want to add another layer of security. And this other layer of security here is the signature. So when you register your application, you get a key. You use this key to make signed requests over to Google, but again, when you're actually accessing the API, every time you're accessing the API, all you're doing is the same thing you're doing with all the other flows, and that is passing this access token. Here's how it's done in Python. You first load in your private key that comes from that APIs console, and then there's a very simple request here that you're passing in. Here's your service account, which again, you get from the APIs console. Here's the scope of data that you're looking for access to, and then what that's doing in this authorize method is, essentially, calling the OAuth provider with that signed request and giving you an access token back. Now, I'd recommend, if you're using this at all, please, please, use our client libraries. Also please, please, make sure your time on your server is synced to an NTP server because that tends to be the biggest issue developers have when working with cryptographic signatures. But anyway, it's pretty easy. You can then access cloud storage on behalf of your application rather than on behalf of any individual user. So OAuth w for Login, or OAuth 2 for Authentication or OpenID Connect. This is really the next version OpenID. So OpenID had OpenID version 2. Still rather complicated to use. I've worked with hundreds of developers to implement OpenID 2 in their applications, including some folks I'm seeing in this room here today, and it can be challenging at times. OAuth 2 for Login builds on top of the standard OAuth flows to give you identity or login or authentication just the same as you would get access to a user's data. So this is really important. Let's show you how it works. First of all the traditional sign-in form. The traditional sign-in form is where you're typing your 50+ characters, but you want to eliminate that down to two mouse clicks. So we'll see how that works here. I basically click the button that says sign up with Google. It pops open and says my slide deck is requesting permission to view basic information about my account and view my email address. I'm going to say Allow Access, and then the application has my name, my email address, my profile photo, my Google+ profile, and public information such as my sex, date of birth, and things like that. Very powerful. Makes it a lot easier for users to onboard and use your application. So you can make it faster to onboard users. You can securely get a unique stable identifier for the user's account, so this is really important. A lot of times, people use an identifier that's their email address. Developers seem to love the email address as a unique identifier. Users change their email addresses all the time. This is not really a good plan, so in this case, you get a unique stable identifier that's just a number that represents that user on Google, and you can use that in your database. You can also personalize your site to make your application a little bit more friendly and inviting to your users. So here's how it works. You first of all specify a scope that is one of these two values or both. So the userinfo.profile gives you this unique ID, name, profile photo, a bunch of information. And then there's a separate userinfo.email scope, which gives you access to the user's email address. Now, there's the occasional geek in the audience that says, well, what if I don't want the application to have access to my email address? And my response is usually, well, pretty much every application on the web will want to have your email address. And those applications do it already for an email address and password based system, so this is no different. And applications need this information in order to hook up with the rest of their system. So most developers will end up specifying both of these, and then they can request access by generating a URL that looks very similar to what we saw, both with the client-side flow and the server-side flow. In this case, we are using the client-side flow. We just have our client ID, we have these scopes, the multiple scopes delineated by a space, and the redirect URI, which is our application's URL. There's one other way that you can do this, and this was announced just recently, in the last day or so, as part of the history API. You can use our branded button for a sign-in button as part of Google+, and that basically just allows you to get the redirect and to handle the popup and all automatically for you, and then get a access token in JavaScript. And again, we've reached our goal. So there's this other step with authentication, the step that you don't have to take with authorization, and this step is verifying the token. So you call this TokenInfo API, and basically, what your goal is here is to make sure that this token was actually issued to your application. It's called an audience check, so your verifying that that audience ID there matches the client ID of your application, and it's really important that you do that. It's really important that you make sure that this token was actually issued to your application and not some other application, and I can't stress that enough. But I won't go into details from a security prospective as to why it's important, but do it. And so when you call this TokenInfo API, you get that audience, you verify that audience matches your client ID. And then you can also get this unique stable identify, the user ID, from there. But if you want to get some additional information, you can then call the UserInfo API, which is, again, just a REST-based API that you pass in the access token, and it returns a JSON responds with a bunch of information about the user. So there are a variety of tools that you'll want to use as you're exploring and learning OAuth. The first is the OAuth 2 Playground. The OAuth 2 Playground is a really helpful application that helps you learn both the client-side and the server-side flows, and it goes through step-by-step, explaining what's happening as you access your data. And you can use this with both Google APIs, but you can also use it with third party APIs as long as they comply with the latest version of the OAuth 2 draft spec. And it's a really helpful tool built by a couple of my colleagues. And then there's also a demo that does the exact same thing with OAuth 2 for Login of Authentication or OpenID Connect, whatever you want to call it. And it goes step-by-step through, so you should check that out as well. All right, everyone, so I've gone through in showing you how to do OAuth both for a client-side flow, as well as a server-side flow. I've talked about how to do it on mobile applications. I've talked about how to use OAuth for identity and logging users into your site. I just want to remind you all that you guys have an obligation to help keep your users secure and to make for a great experience for your users, and I believe that the OAuth technologies really help you do that. In the latest version of OAuth 2, hopefully you've seen here, with the exception of a little bit as cryptographic signature work there, is much easier than the previous versions of OAuth. So I encourage you all to check it out a little bit more. And here are the various resources, which I will leave up while I open this up for Q&A. And feel free to come to the mics here if you have any questions. AUDIENCE: The ID that comes back in the audience check, is that the same as the other unique IDs? RYAN BOYD: Yes. The ID that comes back in the audience check for the user, you're saying? AUDIENCE: Yeah. RYAN BOYD: Yeah, that's the same ID as would come back via the UserInfo API as well. Is that your question? AUDIENCE: Yeah. RYAN BOYD: Cool. AUDIENCE: Hi. Question on the Android flow. The util thing that you mentioned, is that part of Jelly Bean, or is that part of another-- RYAN BOYD: Sorry. Yeah, I missed that part. Yes, it is part of what's called Google Play services, which is distributed along with the Play store. It will be available in FroYo on up, so pretty much most of the devices that are out there. And I've been told in the coming weeks is when it'll be available, but you can check out the URL there for the documentation and learn how it works today and then actually deploy your app in a few weeks once it's available. AUDIENCE: And will this kind of popup a native authorization screen and bypass the entire web? Because it interacts with the Android account manager, I imagine. RYAN BOYD: Yeah, sorry if I didn't make that clear, but it does popup the native authorization screen that looks something like this. AUDIENCE: Because there is currently a native authorization OAuth 2 screen that you can use, I think, from Honeycomb and upwards. But it doesn't look like this. RYAN BOYD: Yeah, so there's the account manager version of the native screen. There's a few issues, and those issues are that you specify your OAuth 2 scope is like OAuth 2, colon, and then a string. And that's often how it's presented to a user, so it's kind of a bad user experience. And then the second thing is that that token is issued and assigned basically to that Android device as opposed to being assigned to your individual application, so when a user goes to manage and revoke access, it gets a little confusing. So we often did not recommend that you use that because of those limitations. Now, with the Google Play services and the GoogleAuthUtil, we can confidently say that's the best way to do it. AUDIENCE: And this will be FroYo and upwards, in a native way, 100%? RYAN BOYD: Correct. AUDIENCE: OK, thanks. RYAN BOYD: Thank you. AUDIENCE: Hi, question. RYAN BOYD: Actually, sorry. OK, go ahead, and we'll take him next. AUDIENCE: OK, we have multiple devices. The same client ID as is in the same user data. Won't they get the same access token, or will they get the different access tokens? Will they be all valid access tokens approximately at the same time? RYAN BOYD: The access tokens are valid for an hour, and the access tokens will be different access tokens if you issued them in multiple calls. The refresh tokens are the long lived the ones, and you only get a refresh token, typically, the first time that you do the authorization, where a user hits the Approve button. On the Android side-- are you asking on the Android side or-- AUDIENCE: No, no, basically I have two devices, same client ID accesses the same user data. Right? RYAN BOYD: But when you say devices are-- AUDIENCE: Two devices, say mobile phone and my desktop application. Right? And they're doing it like approximately the same time, might be slightly apart. RYAN BOYD: You should not get the same access tokens. They should be different access-- AUDIENCE: Different, but my previous access token, would it still be valid for my, say-- RYAN BOYD: Yes. AUDIENCE: So it's possible to have multiple access tokens? RYAN BOYD: It is possible to have multiple outstanding access tokens that are valid, but when a user revokes access, it will revoke access to the refresh token and all outstanding access tokens. AUDIENCE: OK, thank you. AUDIENCE: I noticed the refresh token is longer than normal tokens, so do you save the scope inside the refresh token, or in the server-side? So you must save the scope somewhere. RYAN BOYD: Yes. With that refresh token, we associate the scope on [INAUDIBLE] provider that that refresh token is valid for. AUDIENCE: So basically, the refresh token, you have some copy, something to value the server-side so make it a longer. So because refresh tokens can live forever. RYAN BOYD: Yes, the refresh token can be valid forever until the user revokes access. If the user goes through multiple authorization flows for your application with different scopes, you'll get multiple refresh tokens. But if you just asked for access to a bunch of different APIs at once, you'll still have one refresh token for those bunch of different APIs. And we store all that information server-side. AUDIENCE: OK, so it will live forever in the server-side basically? RYAN BOYD: Correct. AUDIENCE: OK, thanks. AUDIENCE: I kind of have a continuation from the question before last. So talking only about Android devices using GoogleAuthUtil, if you had the same app and the same Google account on multiple Android devices and access was allowed, say, on a phone or whatever, would they have to allow access again on the tablet, or could you just use the refresh token there? RYAN BOYD: So this is a good plug for the session which is coming up next in the Android track, which I should have announced. There is a session specifically on this coming up next on "Accessing Web APIs from Android Devices." [INAUDIBLE] there would know the answer to that question. I don't know the answer. This is just late breaking technology. I haven't actually had a chance to use it. We just got it working a couple days ago, I think. So yeah, definitely ask them at the next session or hunt me down later, and I can find out the answer for you. AUDIENCE: All right, thanks. AUDIENCE: I've introduced [INAUDIBLE] mentioned in [INAUDIBLE]. They are based in Google, but let's say, if I'm an enterprise, and I already have directory that is on premise, how do I use this with the workflow? RYAN BOYD: So you've an on premise directory, like say an LDAP or active directory environment, and you're trying to-- What are you trying to do, though? Like you're trying to grant access to corporate data or what? AUDIENCE: I want to take all my line of business applications and run them in Google Cloud. RYAN BOYD: OK, and you're trying to make sure the identity is communicated back? I mean, one way to do that is, for instance, with Google Apps. With Google Apps, you can have a SAML provider, and that SAML provider is basically a service that runs behind your firewall on your corporate network that associates users with your directory, and then you're the one that's actually authenticating those users. So when the user goes over through an OAuth flow to Google, it will basically delegate then to your SAML provider, so it'll basically say, hey, Google doesn't know how to log this user in. Let's go to the corporate directory, and the corporate directory will handle logging the user in and then doing the normal OAuth flow. So you can kind of bridge between the internet and traditional on premise environments doing something like that. AUDIENCE: OK, thanks. AUDIENCE: How does a two-part authentication play into this? RYAN BOYD: So two-part authentication is basically a way, for those of you who aren't familiar with it, to add an additional layer of security to your account. So basically, instead of just your user name and password, which is something you'd know, the second part is something that you have in your possession. So in order to login to My Accounts, I need to actually use my mobile device. It gives me a code that I then enter into my Google account when I go to login, and then combined with my password and that code, I'm able to login. It does play well with OAuth in that, if the user is not logged into their browser, the user will be asked to login. And when the user is asked to log in, if they haven't used that browser, they'll be asked to prove their second authentication factor at the time that they login before any sort of OAuth grant is going to be issued. There's no way to, say, force that or something like that, to add an additional layer of security right now. We supported some things like that with OpenID 2. It's called paid provider off-policy extension. I'm not aware of, currently, a way to do that with OAuth 2, but I would imagine that's something that will come down the line with more enterprise use cases. AUDIENCE: Thank you. AUDIENCE: Hi, actually the question I have is kind of related. In an enterprise environment, if I have an application that needs to access a user's data, is there a way I can do that without forcing the user to go through the whole flow and say, yeah, OK, I'm going to login now, and I'm going to authorize the application? RYAN BOYD: So we have another mechanism. The service account stuff that I showed you to do app-based authentication, where the application is authenticating and then authorizing access to data-- that flow could also be used if there was, say, a pre-authorization of data. So if an application was previously authorized to access, say, all the user's Google Calendars in an organization, there's a way, when you make that signed request. So the application makes a signed request to the OAuth provider that says I need this scope. There's a way to say I need this scope for this particular user, and then use that for this user-based authorization. And provided that the user has previously granted access, which in the Google Apps world, happens in the Google Apps control panel or by installing an app from the Google Apps Marketplace, then an access token will be issued for that particular user, and the application can then access it. It's not something I've tried out. It's something we've launched just recently, and I haven't heard many users that have tried it out. So if you try it out, and you have any problems, definitely let us know, but that should work for you. AUDIENCE: Brilliant, thanks. AUDIENCE: Is there an OAuth 2.0 for Login hybrid with authentication and authorization as well? RYAN BOYD: Yeah. So just the same as we added multiple scopes for authentication there, we added the user profile scope as well as the email scope. You can add a bunch of other scopes as well. You can ask for calendar or contacts or YouTube, put that all in together into one request, and then it works the same as the OAuth 1 hybrid that I believe you're referring to. AUDIENCE: OK, and one other question. Can you match up the claimed identities from OpenID with the ID you get back from OAuth 2.0 for Login? RYAN BOYD: For Google Apps accounts, yes. For Google Apps accounts, the identity remains constant between the different applications, and I believe the identity is the same thing. The user ID that you see with OAuth 2 is the same thing as the ID number that's included in the OpenID 2. For regular Google consumer accounts, the OpenID 2 identifiers are what's called realm obfuscated. What that means is as you go across the various different applications around the web with OpenID 2, those applications are getting different identifiers for you as a user where those applications can't correlate the information together. With OAuth 2, that's not the case. We no longer realm obfuscate it, primarily because every application asks for email address anyway. The realm obfuscation is kind of pointless in some ways. So the IDs will be different. We do have a feature request, which I personally filed. When you call that UserInfo API or maybe even the TokenInfo API to provide you the old realm obfuscated ID for you to use, then, to match the two up. It's not there yet. I'm hoping-- I was told this quarter, which ends in a couple days. I don't think it's going to make it in the next couple days. They're busy at I/O, but hopefully in the near future, we have something like that. AUDIENCE: In the meantime, can you just use the Gmail address? RYAN BOYD: Yeah, so you can use the email address as long as you made sure, with OpenID 2, to validate the attribute exchange signature. There's some issues with some applications which never validated that signature. So as long as you're sure you validated that signature when acquiring the email address, then you also have a is_verified value when you get the email address from OAuth 2. If that's verified, and you validate your signature, you can be fairly comfortable in matching those two up. It's still not as secure as the user ID, but it gets you there mostly. AUDIENCE: When you said earlier that users change their email address all the time, you don't mean that one, then. Right? RYAN BOYD: I don't mean what? AUDIENCE: You don't mean that particular address? RYAN BOYD: No. I mean, they can. People get married or whatever. You can change your address at Google, Google Apps accounts, they can change their address. So there's going to be some failure rate. It's much better to map up over those IDs, but until we give you that ability, then that's your only choice. AUDIENCE: Thanks. AUDIENCE: So will the user ID be changed when the user change password? RYAN BOYD: The user ID change when the user changes their password? No. The user ID remains constant. Look like I have one more. AUDIENCE: Yeah, so if you do the server-side approach for the OAuth, do you have to ask them multiple times on different device for permissions? RYAN BOYD: I do not believe so. I believe that we associate that with the client ID, as long as you registered your devices and your web applications all in the same APIs console project. I don't believe that it will prompt you again. But if you're talking about on, like, an Android device or something like that, I would definitely ask the folks in the next session to be sure of that. All right, well, so there's a lot of people still left in the room. Thank you. Hopefully you're here for me still, and not the next session, but anyone that asked any questions, I do have a couple copies of my book. So the first people to get up here without injuring yourselves, I'll give you a couple copies of my book. Thank you.
B1 中級 Google I/O 2012 - OAuth 2.0 for Identity and Data Access ! 108 3 Steven Chen に公開 2013 年 03 月 15 日 シェア シェア 保存 報告 動画の中の単語