got complete access to a user’s account • Users couldn’t revoke access except by changing their password • Compromised apps exposed the user’s password
• Making sure the person who is trying to enter into your application is the same person who they claim to be • Usually involves storing and managing passwords
obtain an access token • Authorization Code Flow: web apps, native apps • Device Flow: browserless or input-constrained devices • Password: not really OAuth, only for first-party apps • Refresh Token: getting a new access token when it expires
where the client cannot keep strings confidential. • Javascript clients: "view source" • Native apps: can decompile and see strings • No secret is used for these clients, only the ID
your client expects to receive an authorization code • client_id=CLIENT_ID - The client ID you received when you first created the application • redirect_uri=REDIRECT_URI - Indicates the URL to return the user to after authorization is complete, such as https://example-app.com/callback • scope=photos - A space-separated string indicating which parts of the user's account you wish to access • state=1234zyx - A random string generated by your application, which you'll verify later
the application with an authorization code https://example.com/auth?error=access_denied The user is redirected back to the application with an error code If User Denies
indicates that this request contains an authorization code • code=CODE_FROM_QUERY - Include the authorization code from the query string of this request • redirect_uri=REDIRECT_URI - This must match the redirect_uri used in the original request • client_id=CLIENT_ID - The client ID you received when you first created the application • client_secret=CLIENT_SECRET - Since this request is made from server-side code, the secret is included
"refresh_token":"64d049f8b21191e12522d5d96d5641af5e8" } The server replies with an access token and expiration time or if there was an error: {"error":"invalid_request"}
accounts.google.com Yes No Allow Example App to access your public profile and contacts? example-app.com/callback Loading… Direct the user to the authorization server response_type=code &redirect_uri=example-app.com/callback &state=00000 User signs in Authorization server redirects back to the app code=XYZ123&state=00000 Exchange authorization code for an access token
your client expects to receive an access token • client_id=CLIENT_ID - The client ID you received when you first created the application • redirect_uri=REDIRECT_URI - Indicates the URI to return the user to after authorization is complete, such as https://example-app.com/callback • scope=photos - A space-separated string indicating which parts of the user's account you wish to access • state=1234zyx - A random string generated by your application, which you'll verify later
"code verifier", a random string 43-128 characters long. • Compute the SHA256 hash of the code verifier, call that the code challenge • Include code_challenge=XXXXXX and code_challenge_method=S256 in the initial authorization request • Send the code verifier when exchanging the authorization code for an access token • (For clients that can't support SHA256, include the plaintext verifier as the challenge, and set the method to "plain")
characters long ipSBt30y48l401NGbLjo026cqwsRQzR5KI40AuLAdZ8 The challenge is the SHA256 hash of the verifier string base64url(sha256(code_verifier)) Generate the Code Challenge
the application with an authorization code example://auth?error=access_denied The user is redirected back to the application with an error code If User Denies
make a POST request: • grant_type=authorization_code - indicates that this request contains an authorization code • code=CODE_FROM_QUERY - Include the authorization code from the query string of this request • redirect_uri=REDIRECT_URI - This must match the redirect_uri used in the original request • client_id=CLIENT_ID - The client ID you received when you first created the application • code_verifier=VERIFIER_STRING - The plaintext code verifier initially created
"refresh_token":"64d049f8b2119a12522d5dd96d5641af5e8" } The server compares the code_verifier with the code_challenge that was in the request when it generated the authorization code, and responds with an access token.
grant_type=password& username=USERNAME& password=PASSWORD& client_id=CLIENT_ID& client_secret=CLIENT_SECRET The user’s credentials are sent directly! Not a good idea for third party apps!
https://api.authorization-server.com/token grant_type=client_credentials& client_id=CLIENT_ID& client_secret=CLIENT_SECRET No user context in the request, so the access token can only be used to access the application’s resources
Request a Device Code { "device_code": "NGU5OWFiNjQ5YmQwNGY3YTdmZTEyNzQ3YzQ1YSA", "user_code": "BDWD-HQPK", "verification_uri": "https://example.com/device", "interval": 5, "expires_in": 1800 } The server responds with a new device code and user code, as well as the URL the user should visit to enter the code.
for the user to enter the code and authorize the application, the device polls the token endpoint. { "access_token": "RsT5OjbzRn430zqMLgV3Ia", "expires_in": 3600, "refresh_token": "b7aab35e97298a060e0ede5b43ed1f70a8" }
OAuth 2.0 • ID Token • /userinfo – for getting more information about the user • Standard set of scopes • openid • profile • email • address • phone • offline_access
HAiOjE1MjQ1OTg1MTAsImp0aSI6IklELklfNUc4RzhWdXowMHJvYl9aSzlja3J0T0pseVdwNzh xMU5naGV2QlJ6dkEiLCJhbXIiOlsicHdkIl0sImlkcCI6IjAwb2NxM2J3aTFoTnpRT3B5MGg3I iwibm9uY2UiOiJhYmMiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJwYWRtYS5nb3ZpbmRhcmFqYWx 1QG9rdGEuY29tIiwiZ2l2ZW5fbmFtZSI6IlBhZG1hIiwibWlkZGxlX25hbWUiOiJLcmlzaG5hI iwiZmFtaWx5X25hbWUiOiJHb3ZpbmRhcmFqYWx1Iiwiem9uZWluZm8iOiJBbWVyaWNhL0xvc19 BbmdlbGVzIiwidXBkYXRlZF9hdCI6MTUyNDU5NDM2MSwiYXV0aF90aW1lIjoxNTI0NTk0OTA3f Q.HvMYW8XbdCf1BWZfHQ1odaAYJjZqKkh1NUkHW0clk6J7pYunn8jllbIp0IhSjcCn6PBIlZPr rE0dkuyjvdHjVI8ALQNwtM7FnIs9H6gCH0oONx4EL4KEf4d_w46qeqsCwMClvNoaE3c2I5kONu JUlaefbnr6Al_y9z5mvLyDynf9IjrOyTPoIrgk9V46l28Aulp4dJhqBtZfpYyVbKrXawHSO5Fv KTDMPBhQgxt0_6PKG7sSkhbMeBicIc35SJJaXt81KSfkYDUp5s1UQ74ATHrtLe7HMU1yp_Kajg YUKxMXO5NiXpeNEHzarAOWzLHblrQcgkpuJbY3KM1HHg&state=xyz1234 The user is redirected back to the redirect_uri with an ID token
right auth server? • audience (aud) – is the token intended for my application? • expiry time (exp) – has the current time already passed the exp time? • issued at time (iat) – is the current time too far from the issued time? • nonce - does it match to the nonce passed in the request? Validating the Claims
to get new access tokens • Requested along with the id_token or access token in the initial step • Usually requires scope: offline_access • Usually not issued to Javascript apps
URLs can have a custom scheme (example://redirect) • When an authorization request is made, the server verifies that the redirect URL in the request matches one that is registered to that client ID Redirect URL Registration 93
Defining Scopes 108 • Read / Write • Restrict access to sensitive information • e.g. private repos on GitHub • By functionality • e.g. Google Drive, YouTube, Gmail • Billable resources
Presenting Scopes to the User 109 • Provide clear and straightforward information • Provide enough detail so the user knows what the application can access • Don't provide too much detail that they are overwhelmed and just click "ok"