A batteries included HTTP/1.1 client in OCaml

oauth2

+6457 -17
+2 -1
lib/auth.ml
··· 421 421 Log.err (fun m -> m "Failed to apply HTTP message signature: %s" 422 422 (Signature.sign_error_to_string e)); 423 423 headers) 424 - | _ -> headers 424 + | _ -> headers 425 +
+6 -2
lib/auth.mli
··· 10 10 - {b Basic}: {{:https://datatracker.ietf.org/doc/html/rfc7617}RFC 7617} - Base64 username:password 11 11 - {b Bearer}: {{:https://datatracker.ietf.org/doc/html/rfc6750}RFC 6750} - OAuth 2.0 tokens 12 12 - {b Digest}: {{:https://datatracker.ietf.org/doc/html/rfc7616}RFC 7616} - Challenge-response with MD5/SHA-256 13 + - {b Signature}: {{:https://datatracker.ietf.org/doc/html/rfc9421}RFC 9421} - HTTP Message Signatures 14 + 15 + For OAuth 2.0 with automatic token refresh, see the [requests.oauth] subpackage. 13 16 14 17 {2 Security} 15 18 ··· 55 58 The signature covers selected headers and derived values like 56 59 the method, path, and authority. 57 60 58 - Use {!Signature.config} to create the configuration: 61 + Use {!val:Signature.config} to create the configuration: 59 62 {[ 60 63 let key = Signature.Key.ed25519 ~priv:... ~pub:... in 61 64 let config = Signature.config ~key ~keyid:"my-key" () in ··· 212 215 the appropriate headers per RFC 9421. 213 216 214 217 If [auth] is not Signature authentication, returns [headers] unchanged. 215 - If signature computation fails, logs an error and returns [headers] unchanged. *) 218 + If signature computation fails, logs an error and returns [headers] unchanged. *) 219 +
+37
lib/error.ml
··· 60 60 | Invalid_url of { url: string; reason: string } 61 61 | Invalid_request of { reason: string } 62 62 63 + (* OAuth 2.0 errors - per RFC 6749 Section 5.2 *) 64 + | Oauth_error of { error_code: string; description: string option; uri: string option } 65 + (** OAuth 2.0 error response from authorization server. 66 + Per {{:https://datatracker.ietf.org/doc/html/rfc6749#section-5.2}RFC 6749 Section 5.2}. *) 67 + | Token_refresh_failed of { reason: string } 68 + (** Token refresh operation failed. *) 69 + | Token_expired 70 + (** Access token has expired and no refresh token is available. *) 71 + 63 72 (** {1 URL and Credential Sanitization} 64 73 65 74 Per Recommendation #20: Remove sensitive info from error messages *) ··· 167 176 | Invalid_request { reason } -> 168 177 Format.fprintf ppf "Invalid request: %s" reason 169 178 179 + | Oauth_error { error_code; description; uri } -> 180 + Format.fprintf ppf "OAuth error: %s" error_code; 181 + Option.iter (fun desc -> Format.fprintf ppf " - %s" desc) description; 182 + Option.iter (fun u -> Format.fprintf ppf " (see: %s)" u) uri 183 + 184 + | Token_refresh_failed { reason } -> 185 + Format.fprintf ppf "Token refresh failed: %s" reason 186 + 187 + | Token_expired -> 188 + Format.fprintf ppf "Access token expired and no refresh token available" 189 + 170 190 (** {1 Eio.Exn Integration} 171 191 172 192 Following the pattern from ocaml-conpool for structured Eio exceptions *) ··· 246 266 | Json_encode_error _ -> true 247 267 | _ -> false 248 268 269 + let is_oauth_error = function 270 + | Oauth_error _ -> true 271 + | Token_refresh_failed _ -> true 272 + | Token_expired -> true 273 + | _ -> false 274 + 249 275 (** {1 Error Extraction} 250 276 251 277 Extract error from Eio.Io exception *) ··· 327 353 328 354 let tcp_connect_failedf ~host ~port fmt = 329 355 Printf.ksprintf (fun reason -> err (Tcp_connect_failed { host; port; reason })) fmt 356 + 357 + (** {1 OAuth Error Constructors} *) 358 + 359 + let oauth_error ~error_code ?description ?uri () = 360 + err (Oauth_error { error_code; description; uri }) 361 + 362 + let token_refresh_failed ~reason = 363 + err (Token_refresh_failed { reason }) 364 + 365 + let token_expired () = 366 + err Token_expired
+24
lib/error.mli
··· 83 83 | Invalid_url of { url: string; reason: string } 84 84 | Invalid_request of { reason: string } 85 85 86 + (* OAuth 2.0 errors - per RFC 6749 Section 5.2 *) 87 + | Oauth_error of { error_code: string; description: string option; uri: string option } 88 + (** OAuth 2.0 error response from authorization server. 89 + Per {{:https://datatracker.ietf.org/doc/html/rfc6749#section-5.2}RFC 6749 Section 5.2}. *) 90 + | Token_refresh_failed of { reason: string } 91 + (** Token refresh operation failed. *) 92 + | Token_expired 93 + (** Access token has expired and no refresh token is available. *) 94 + 86 95 (** {1 Eio.Exn Integration} *) 87 96 88 97 (** Extension of [Eio.Exn.err] for Requests errors *) ··· 146 155 147 156 (** Returns [true] if the error is a JSON parsing or encoding error *) 148 157 val is_json_error : error -> bool 158 + 159 + (** Returns [true] if the error is an OAuth-related error 160 + (Oauth_error, Token_refresh_failed, Token_expired) *) 161 + val is_oauth_error : error -> bool 149 162 150 163 (** {1 Error Extraction} *) 151 164 ··· 239 252 240 253 val tcp_connect_failedf : host:string -> port:int -> ('a, unit, string, exn) format4 -> 'a 241 254 (** Create a [Tcp_connect_failed] exception with a format string *) 255 + 256 + (** {1 OAuth Error Constructors} *) 257 + 258 + val oauth_error : error_code:string -> ?description:string -> ?uri:string -> unit -> exn 259 + (** Create an [Oauth_error] exception *) 260 + 261 + val token_refresh_failed : reason:string -> exn 262 + (** Create a [Token_refresh_failed] exception *) 263 + 264 + val token_expired : unit -> exn 265 + (** Create a [Token_expired] exception *)
+17
lib/oauth/dune
··· 1 + (library 2 + (name requests_oauth) 3 + (public_name requests.oauth) 4 + (libraries 5 + requests 6 + base64 7 + digestif 8 + eio 9 + eqaf 10 + jsont 11 + jsont.bytesrw 12 + logs 13 + mirage-crypto-rng 14 + ptime 15 + ptime.clock.os 16 + uri) 17 + (preprocess no_preprocessing))
+357
lib/oauth/oauth.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 + SPDX-License-Identifier: ISC 4 + ---------------------------------------------------------------------------*) 5 + 6 + (** RFC 6749 OAuth 2.0 Authorization Framework. *) 7 + 8 + let src = Logs.Src.create "requests.oauth" ~doc:"OAuth 2.0" 9 + module Log = (val Logs.src_log src : Logs.LOG) 10 + 11 + (** {1 Client Configuration} *) 12 + 13 + type config = { 14 + client_id : string; 15 + client_secret : string option; 16 + token_endpoint : string; 17 + authorization_endpoint : string option; 18 + redirect_uri : string option; 19 + scopes : string list; 20 + } 21 + 22 + let make_config ~client_id ?client_secret ~token_endpoint 23 + ?authorization_endpoint ?redirect_uri ?(scopes = []) () = 24 + { client_id; client_secret; token_endpoint; 25 + authorization_endpoint; redirect_uri; scopes } 26 + 27 + (** {1 Token Types} *) 28 + 29 + type token = { 30 + access_token : string; 31 + token_type : string; 32 + expires_at : Ptime.t option; 33 + refresh_token : string option; 34 + scope : string option; 35 + } 36 + 37 + let get_access_token t = t.access_token 38 + let get_refresh_token t = t.refresh_token 39 + 40 + let now () = Ptime_clock.now () 41 + 42 + let is_expired token = 43 + match token.expires_at with 44 + | None -> false 45 + | Some expires_at -> not (Ptime.is_later expires_at ~than:(now ())) 46 + 47 + let expires_within span token = 48 + match token.expires_at with 49 + | None -> false 50 + | Some expires_at -> 51 + match Ptime.sub_span expires_at span with 52 + | None -> true (* Overflow, assume expiring *) 53 + | Some threshold -> not (Ptime.is_later threshold ~than:(now ())) 54 + 55 + (** {1 Error Types} *) 56 + 57 + type error_code = 58 + | Invalid_request 59 + | Invalid_client 60 + | Invalid_grant 61 + | Unauthorized_client 62 + | Unsupported_grant_type 63 + | Invalid_scope 64 + | Unknown_error of string 65 + 66 + type error = { 67 + code : error_code; 68 + description : string option; 69 + uri : string option; 70 + } 71 + 72 + let error_code_of_string = function 73 + | "invalid_request" -> Invalid_request 74 + | "invalid_client" -> Invalid_client 75 + | "invalid_grant" -> Invalid_grant 76 + | "unauthorized_client" -> Unauthorized_client 77 + | "unsupported_grant_type" -> Unsupported_grant_type 78 + | "invalid_scope" -> Invalid_scope 79 + | s -> Unknown_error s 80 + 81 + let error_code_to_string = function 82 + | Invalid_request -> "invalid_request" 83 + | Invalid_client -> "invalid_client" 84 + | Invalid_grant -> "invalid_grant" 85 + | Unauthorized_client -> "unauthorized_client" 86 + | Unsupported_grant_type -> "unsupported_grant_type" 87 + | Invalid_scope -> "invalid_scope" 88 + | Unknown_error s -> s 89 + 90 + let pp_error ppf err = 91 + Format.fprintf ppf "OAuth error: %s" (error_code_to_string err.code); 92 + Option.iter (fun desc -> Format.fprintf ppf " - %s" desc) err.description; 93 + Option.iter (fun uri -> Format.fprintf ppf " (see: %s)" uri) err.uri 94 + 95 + (** {1 PKCE Support} *) 96 + 97 + type pkce_method = Plain | S256 98 + 99 + type pkce = { 100 + verifier : string; 101 + challenge : string; 102 + method_ : pkce_method; 103 + } 104 + 105 + let pkce_method_to_string = function 106 + | Plain -> "plain" 107 + | S256 -> "S256" 108 + 109 + (** URL-safe base64 encoding without padding per RFC 7636 Appendix A *) 110 + let base64_url_encode_no_padding s = 111 + Base64.encode_exn s 112 + |> String.map (function '+' -> '-' | '/' -> '_' | c -> c) 113 + |> String.to_seq 114 + |> Seq.filter (fun c -> c <> '=') 115 + |> String.of_seq 116 + 117 + let generate_verifier () = 118 + Mirage_crypto_rng.generate 32 |> base64_url_encode_no_padding 119 + 120 + let compute_challenge ~method_ verifier = 121 + match method_ with 122 + | Plain -> verifier 123 + | S256 -> 124 + Digestif.SHA256.digest_string verifier 125 + |> Digestif.SHA256.to_raw_string 126 + |> base64_url_encode_no_padding 127 + 128 + let generate_pkce ?(method_ = S256) () = 129 + let verifier = generate_verifier () in 130 + let challenge = compute_challenge ~method_ verifier in 131 + { verifier; challenge; method_ } 132 + 133 + (** {1 State Parameter} *) 134 + 135 + let generate_state () = 136 + Mirage_crypto_rng.generate 16 |> base64_url_encode_no_padding 137 + 138 + let validate_state ~expected ~received = 139 + Eqaf.equal expected received 140 + 141 + (** {1 Authorization URL} *) 142 + 143 + let add_opt_param key opt params = 144 + Option.fold ~none:params ~some:(fun v -> (key, v) :: params) opt 145 + 146 + let authorization_url ~config ~state ?pkce ?(extra_params = []) () = 147 + match config.authorization_endpoint with 148 + | None -> 149 + invalid_arg "authorization_endpoint is required for authorization URL" 150 + | Some endpoint -> 151 + let params = 152 + [ ("response_type", "code"); 153 + ("client_id", config.client_id); 154 + ("state", state) ] 155 + |> add_opt_param "redirect_uri" config.redirect_uri 156 + |> (fun params -> 157 + match config.scopes with 158 + | [] -> params 159 + | scopes -> ("scope", String.concat " " scopes) :: params) 160 + |> (fun params -> 161 + match pkce with 162 + | None -> params 163 + | Some p -> 164 + ("code_challenge", p.challenge) 165 + :: ("code_challenge_method", pkce_method_to_string p.method_) 166 + :: params) 167 + |> List.rev_append extra_params 168 + in 169 + let uri = Uri.of_string endpoint in 170 + let params_list = List.map (fun (k, v) -> (k, [v])) params in 171 + Uri.to_string (Uri.add_query_params uri params_list) 172 + 173 + (** {1 JSON Codecs} *) 174 + 175 + let string_option = Jsont.(some string) 176 + let int_option = Jsont.(some int) 177 + 178 + (** Token response JSON codec *) 179 + let token_response_jsont = 180 + let make access_token token_type expires_in refresh_token scope = 181 + let received_at = now () in 182 + let expires_at = 183 + Option.bind expires_in (fun secs -> 184 + Ptime.add_span received_at (Ptime.Span.of_int_s secs)) 185 + in 186 + { access_token; token_type; expires_at; refresh_token; scope } 187 + in 188 + Jsont.Object.map ~kind:"token_response" make 189 + |> Jsont.Object.mem "access_token" Jsont.string ~enc:(fun t -> t.access_token) 190 + |> Jsont.Object.mem "token_type" Jsont.string ~enc:(fun t -> t.token_type) 191 + |> Jsont.Object.mem "expires_in" int_option ~dec_absent:None 192 + ~enc:(fun _ -> None) (* Don't encode expires_in, it's derived *) 193 + |> Jsont.Object.mem "refresh_token" string_option ~dec_absent:None 194 + ~enc:(fun t -> t.refresh_token) 195 + |> Jsont.Object.mem "scope" string_option ~dec_absent:None 196 + ~enc:(fun t -> t.scope) 197 + |> Jsont.Object.finish 198 + 199 + let error_code_jsont = 200 + Jsont.string 201 + |> Jsont.map ~dec:error_code_of_string ~enc:error_code_to_string 202 + 203 + let error_jsont = 204 + let make code description uri = { code; description; uri } in 205 + Jsont.Object.map ~kind:"oauth_error" make 206 + |> Jsont.Object.mem "error" error_code_jsont ~enc:(fun e -> e.code) 207 + |> Jsont.Object.mem "error_description" string_option ~dec_absent:None 208 + ~enc:(fun e -> e.description) 209 + |> Jsont.Object.mem "error_uri" string_option ~dec_absent:None 210 + ~enc:(fun e -> e.uri) 211 + |> Jsont.Object.finish 212 + 213 + (** {1 Token Operations} *) 214 + 215 + let parse_token_response ~status ~body = 216 + Log.debug (fun m -> m "Token response status=%d" status); 217 + if status >= 200 && status < 300 then 218 + match Jsont_bytesrw.decode_string' token_response_jsont body with 219 + | Ok token -> 220 + Log.info (fun m -> m "Received access token (type=%s)" token.token_type); 221 + Ok token 222 + | Error e -> 223 + Log.err (fun m -> m "Failed to parse token response: %s" 224 + (Jsont.Error.to_string e)); 225 + Error { 226 + code = Invalid_request; 227 + description = Some ("Failed to parse token response: " ^ 228 + Jsont.Error.to_string e); 229 + uri = None; 230 + } 231 + else 232 + match Jsont_bytesrw.decode_string' error_jsont body with 233 + | Ok err -> 234 + Log.warn (fun m -> m "OAuth error: %a" pp_error err); 235 + Error err 236 + | Error e -> 237 + Log.err (fun m -> m "Failed to parse error response: %s (status=%d)" 238 + (Jsont.Error.to_string e) status); 239 + Error { 240 + code = Unknown_error "parse_error"; 241 + description = Some (Printf.sprintf "HTTP %d: %s" status body); 242 + uri = None; 243 + } 244 + 245 + let add_client_auth config headers body_params = 246 + match config.client_secret with 247 + | Some secret -> 248 + let headers = Requests.Headers.basic 249 + ~username:config.client_id 250 + ~password:secret 251 + headers 252 + in 253 + (headers, body_params) 254 + | None -> 255 + let body_params = ("client_id", config.client_id) :: body_params in 256 + (headers, body_params) 257 + 258 + let token_request session config ~grant_type ~params = 259 + let headers = Requests.Headers.empty in 260 + let body_params = ("grant_type", grant_type) :: params in 261 + let body_params = 262 + match config.scopes with 263 + | [] -> body_params 264 + | scopes -> ("scope", String.concat " " scopes) :: body_params 265 + in 266 + let headers, body_params = add_client_auth config headers body_params in 267 + Log.debug (fun m -> m "Token request to %s: grant_type=%s" 268 + config.token_endpoint grant_type); 269 + let body = Requests.Body.form body_params in 270 + let response = Requests.post session ~headers ~body config.token_endpoint in 271 + let status = Requests.Response.status_code response in 272 + let body = Requests.Response.text response in 273 + parse_token_response ~status ~body 274 + 275 + let client_credentials session config = 276 + Log.info (fun m -> m "Performing client credentials grant"); 277 + token_request session config ~grant_type:"client_credentials" ~params:[] 278 + 279 + let password_grant session config ~username ~password = 280 + Log.info (fun m -> m "Performing password credentials grant for user: %s" username); 281 + let params = [("username", username); ("password", password)] in 282 + token_request session config ~grant_type:"password" ~params 283 + 284 + let exchange_code session config ~code ?pkce_verifier () = 285 + Log.info (fun m -> m "Exchanging authorization code for tokens"); 286 + let params = 287 + [("code", code)] 288 + |> add_opt_param "redirect_uri" config.redirect_uri 289 + |> add_opt_param "code_verifier" pkce_verifier 290 + in 291 + token_request session config ~grant_type:"authorization_code" ~params 292 + 293 + let refresh session config ~refresh_token = 294 + Log.info (fun m -> m "Refreshing access token"); 295 + let params = [("refresh_token", refresh_token)] in 296 + token_request session config ~grant_type:"refresh_token" ~params 297 + 298 + (** {1 Managed Token State} *) 299 + 300 + type t = { 301 + session : Requests.t; 302 + config : config; 303 + mutable token : token; 304 + mutex : Eio.Mutex.t; 305 + on_refresh : (token -> unit) option; 306 + } 307 + 308 + let default_leeway = Ptime.Span.of_int_s 30 309 + 310 + let create session config token ?on_refresh () = 311 + { session; config; token; mutex = Eio.Mutex.create (); on_refresh } 312 + 313 + let force_refresh t = 314 + Eio.Mutex.use_rw ~protect:true t.mutex (fun () -> 315 + match t.token.refresh_token with 316 + | None -> 317 + Log.warn (fun m -> m "Cannot refresh: no refresh token available"); 318 + Error { 319 + code = Invalid_grant; 320 + description = Some "No refresh token available"; 321 + uri = None; 322 + } 323 + | Some refresh_token -> 324 + match refresh t.session t.config ~refresh_token with 325 + | Ok new_token -> 326 + (* Preserve refresh token if new response doesn't include one *) 327 + let new_token = 328 + if new_token.refresh_token = None then 329 + { new_token with refresh_token = Some refresh_token } 330 + else 331 + new_token 332 + in 333 + t.token <- new_token; 334 + Option.iter (fun f -> f new_token) t.on_refresh; 335 + Ok new_token 336 + | Error e -> 337 + Log.err (fun m -> m "Token refresh failed: %a" pp_error e); 338 + Error e) 339 + 340 + let check_and_refresh t = 341 + if expires_within default_leeway t.token then begin 342 + Log.debug (fun m -> m "Token needs refresh, refreshing..."); 343 + match force_refresh t with 344 + | Ok _ -> () 345 + | Error e -> Log.warn (fun m -> m "Auto-refresh failed: %a" pp_error e) 346 + end 347 + 348 + let get_token t = 349 + check_and_refresh t; 350 + t.token 351 + 352 + let get_access_token_managed t = 353 + (get_token t).access_token 354 + 355 + let with_client_credentials session config ?on_refresh () = 356 + client_credentials session config 357 + |> Result.map (fun token -> create session config token ?on_refresh ())
+284
lib/oauth/oauth.mli
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 + SPDX-License-Identifier: ISC 4 + ---------------------------------------------------------------------------*) 5 + 6 + (** RFC 6749 OAuth 2.0 Authorization Framework. 7 + 8 + This module implements the OAuth 2.0 authorization framework as specified in 9 + {{:https://datatracker.ietf.org/doc/html/rfc6749}RFC 6749}. 10 + 11 + {2 Supported Grant Types} 12 + - {{:https://datatracker.ietf.org/doc/html/rfc6749#section-4.1}Authorization Code} (Section 4.1) 13 + - {{:https://datatracker.ietf.org/doc/html/rfc6749#section-4.3}Resource Owner Password Credentials} (Section 4.3) 14 + - {{:https://datatracker.ietf.org/doc/html/rfc6749#section-4.4}Client Credentials} (Section 4.4) 15 + 16 + The Implicit Grant (Section 4.2) is intentionally not supported as it is 17 + deprecated per {{:https://datatracker.ietf.org/doc/html/rfc8996}RFC 8996}. 18 + 19 + {2 PKCE Support} 20 + 21 + This module supports Proof Key for Code Exchange (PKCE) per 22 + {{:https://datatracker.ietf.org/doc/html/rfc7636}RFC 7636} to protect 23 + against authorization code interception attacks, especially for public clients. 24 + 25 + {2 Usage Example} 26 + 27 + {[ 28 + (* Client credentials grant *) 29 + let config = Oauth.make_config 30 + ~client_id:"my-client" 31 + ~client_secret:"my-secret" 32 + ~token_endpoint:"https://auth.example.com/token" 33 + () in 34 + match Oauth.client_credentials session config with 35 + | Ok token -> Printf.printf "Got token: %s\n" (Oauth.get_access_token token) 36 + | Error e -> Printf.printf "Error: %a\n" Oauth.pp_error e 37 + 38 + (* Authorization code flow with PKCE *) 39 + let pkce = Oauth.generate_pkce () in 40 + let state = Oauth.generate_state () in 41 + let auth_url = Oauth.authorization_url ~config ~state ~pkce () in 42 + (* ... redirect user to auth_url, receive code ... *) 43 + match Oauth.exchange_code session config ~code ~pkce_verifier:pkce.verifier () with 44 + | Ok token -> ... 45 + | Error e -> ... 46 + ]} 47 + 48 + {2 References} 49 + {ul 50 + {- {{:https://datatracker.ietf.org/doc/html/rfc6749}RFC 6749} - OAuth 2.0 Authorization Framework} 51 + {- {{:https://datatracker.ietf.org/doc/html/rfc7636}RFC 7636} - PKCE (Proof Key for Code Exchange)} 52 + {- {{:https://datatracker.ietf.org/doc/html/rfc6750}RFC 6750} - Bearer Token Usage} 53 + {- {{:https://datatracker.ietf.org/doc/html/rfc8996}RFC 8996} - Deprecates Implicit Grant}} *) 54 + 55 + (** {1 Client Configuration} *) 56 + 57 + (** OAuth 2.0 client configuration. 58 + 59 + Per {{:https://datatracker.ietf.org/doc/html/rfc6749#section-2}RFC 6749 Section 2}, 60 + clients are identified by a client ID and optionally authenticated with a client secret. *) 61 + type config = { 62 + client_id : string; 63 + (** The client identifier issued during registration. 64 + Per {{:https://datatracker.ietf.org/doc/html/rfc6749#section-2.2}Section 2.2}. *) 65 + 66 + client_secret : string option; 67 + (** The client secret for confidential clients. [None] for public clients. 68 + Per {{:https://datatracker.ietf.org/doc/html/rfc6749#section-2.3.1}Section 2.3.1}. *) 69 + 70 + token_endpoint : string; 71 + (** The authorization server's token endpoint URL. 72 + Per {{:https://datatracker.ietf.org/doc/html/rfc6749#section-3.2}Section 3.2}. *) 73 + 74 + authorization_endpoint : string option; 75 + (** The authorization server's authorization endpoint URL. 76 + Required for Authorization Code grant. 77 + Per {{:https://datatracker.ietf.org/doc/html/rfc6749#section-3.1}Section 3.1}. *) 78 + 79 + redirect_uri : string option; 80 + (** The client's redirection endpoint for Authorization Code grant. 81 + Per {{:https://datatracker.ietf.org/doc/html/rfc6749#section-3.1.2}Section 3.1.2}. *) 82 + 83 + scopes : string list; 84 + (** The requested access token scope. 85 + Per {{:https://datatracker.ietf.org/doc/html/rfc6749#section-3.3}Section 3.3}. *) 86 + } 87 + 88 + val make_config : 89 + client_id:string -> 90 + ?client_secret:string -> 91 + token_endpoint:string -> 92 + ?authorization_endpoint:string -> 93 + ?redirect_uri:string -> 94 + ?scopes:string list -> 95 + unit -> 96 + config 97 + (** [make_config ~client_id ~token_endpoint ...] creates an OAuth client configuration. *) 98 + 99 + (** {1 Token Types} *) 100 + 101 + (** Token response from the authorization server. 102 + Per {{:https://datatracker.ietf.org/doc/html/rfc6749#section-5.1}Section 5.1}. *) 103 + type token = { 104 + access_token : string; 105 + (** The access token issued by the authorization server. *) 106 + 107 + token_type : string; 108 + (** The type of the token, typically "Bearer". *) 109 + 110 + expires_at : Ptime.t option; 111 + (** When the token expires. [None] if no expiry was provided. *) 112 + 113 + refresh_token : string option; 114 + (** The refresh token for obtaining new access tokens. *) 115 + 116 + scope : string option; 117 + (** The scope of the access token. *) 118 + } 119 + 120 + val get_access_token : token -> string 121 + (** [get_access_token token] returns the access token string. *) 122 + 123 + val get_refresh_token : token -> string option 124 + (** [get_refresh_token token] returns the refresh token if present. *) 125 + 126 + val is_expired : token -> bool 127 + (** [is_expired token] returns [true] if the token has expired. 128 + Returns [false] if the token has no expiry information. *) 129 + 130 + val expires_within : Ptime.Span.t -> token -> bool 131 + (** [expires_within span token] returns [true] if the token expires within [span]. 132 + Returns [false] if the token has no expiry information. *) 133 + 134 + (** {1 Error Types} *) 135 + 136 + (** OAuth 2.0 error codes per RFC 6749 Section 5.2. *) 137 + type error_code = 138 + | Invalid_request 139 + | Invalid_client 140 + | Invalid_grant 141 + | Unauthorized_client 142 + | Unsupported_grant_type 143 + | Invalid_scope 144 + | Unknown_error of string 145 + 146 + (** OAuth error response. *) 147 + type error = { 148 + code : error_code; 149 + description : string option; 150 + uri : string option; 151 + } 152 + 153 + val pp_error : Format.formatter -> error -> unit 154 + (** Pretty printer for OAuth errors. *) 155 + 156 + val error_code_to_string : error_code -> string 157 + (** [error_code_to_string code] returns the RFC 6749 string representation. *) 158 + 159 + (** {1 PKCE Support} 160 + 161 + Per {{:https://datatracker.ietf.org/doc/html/rfc7636}RFC 7636}. *) 162 + 163 + (** PKCE challenge method. *) 164 + type pkce_method = 165 + | Plain (** code_challenge = code_verifier (not recommended) *) 166 + | S256 (** code_challenge = BASE64URL(SHA256(code_verifier)) *) 167 + 168 + (** PKCE state for authorization code flow. *) 169 + type pkce = { 170 + verifier : string; 171 + (** The code verifier (43-128 URL-safe characters). *) 172 + 173 + challenge : string; 174 + (** The code challenge derived from the verifier. *) 175 + 176 + method_ : pkce_method; 177 + (** The challenge derivation method. *) 178 + } 179 + 180 + val generate_pkce : ?method_:pkce_method -> unit -> pkce 181 + (** [generate_pkce ()] generates PKCE verifier and challenge. 182 + Default method is [S256]. *) 183 + 184 + val pkce_method_to_string : pkce_method -> string 185 + (** Returns "plain" or "S256". *) 186 + 187 + (** {1 State Parameter} *) 188 + 189 + val generate_state : unit -> string 190 + (** [generate_state ()] generates a cryptographically random state value 191 + for CSRF protection per RFC 6749 Section 10.12. *) 192 + 193 + val validate_state : expected:string -> received:string -> bool 194 + (** [validate_state ~expected ~received] performs constant-time comparison. *) 195 + 196 + (** {1 Authorization URL} *) 197 + 198 + val authorization_url : 199 + config:config -> 200 + state:string -> 201 + ?pkce:pkce -> 202 + ?extra_params:(string * string) list -> 203 + unit -> 204 + string 205 + (** [authorization_url ~config ~state ()] builds the authorization URL. 206 + 207 + @raise Invalid_argument if [authorization_endpoint] is not configured. *) 208 + 209 + (** {1 Token Operations} 210 + 211 + These functions use a {!Requests.t} session to make HTTP calls. *) 212 + 213 + val client_credentials : 214 + Requests.t -> 215 + config -> 216 + (token, error) result 217 + (** [client_credentials session config] performs the client credentials grant. 218 + Per {{:https://datatracker.ietf.org/doc/html/rfc6749#section-4.4}Section 4.4}. *) 219 + 220 + val password_grant : 221 + Requests.t -> 222 + config -> 223 + username:string -> 224 + password:string -> 225 + (token, error) result 226 + (** [password_grant session config ~username ~password] performs the resource owner 227 + password credentials grant. 228 + 229 + Per {{:https://datatracker.ietf.org/doc/html/rfc6749#section-4.3}Section 4.3}. 230 + 231 + {b Warning}: This grant type should only be used for legacy or high-trust scenarios. *) 232 + 233 + val exchange_code : 234 + Requests.t -> 235 + config -> 236 + code:string -> 237 + ?pkce_verifier:string -> 238 + unit -> 239 + (token, error) result 240 + (** [exchange_code session config ~code ()] exchanges an authorization code for tokens. 241 + Per {{:https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.3}Section 4.1.3}. *) 242 + 243 + val refresh : 244 + Requests.t -> 245 + config -> 246 + refresh_token:string -> 247 + (token, error) result 248 + (** [refresh session config ~refresh_token] exchanges a refresh token for a new access token. 249 + Per {{:https://datatracker.ietf.org/doc/html/rfc6749#section-6}Section 6}. *) 250 + 251 + (** {1 Managed Token State} 252 + 253 + Thread-safe automatic token refresh. *) 254 + 255 + (** Managed OAuth state with automatic token refresh. *) 256 + type t 257 + 258 + val create : 259 + Requests.t -> 260 + config -> 261 + token -> 262 + ?on_refresh:(token -> unit) -> 263 + unit -> 264 + t 265 + (** [create session config token ()] creates managed OAuth state. 266 + @param on_refresh Optional callback when tokens are refreshed. *) 267 + 268 + val get_token : t -> token 269 + (** [get_token t] returns the current token, refreshing if needed. Thread-safe. *) 270 + 271 + val get_access_token_managed : t -> string 272 + (** [get_access_token_managed t] returns the current access token, refreshing if needed. *) 273 + 274 + val force_refresh : t -> (token, error) result 275 + (** [force_refresh t] forces a token refresh. Thread-safe. *) 276 + 277 + val with_client_credentials : 278 + Requests.t -> 279 + config -> 280 + ?on_refresh:(token -> unit) -> 281 + unit -> 282 + (t, error) result 283 + (** [with_client_credentials session config ()] performs client credentials grant 284 + and returns managed state ready for use. *)
+11 -8
lib/signature.ml
··· 410 410 (* ========================================================================= *) 411 411 412 412 module Context = struct 413 + (** Request context for signature computation. *) 413 414 type request_ctx = { 414 - method_ : Method.t; 415 - uri : Uri.t; 416 - headers : Headers.t; 415 + method_ : Method.t; (** The HTTP method *) 416 + uri : Uri.t; (** The request URI *) 417 + headers : Headers.t; (** The request headers *) 417 418 } 418 419 420 + (** Response context for signature computation. *) 419 421 type response_ctx = { 420 - status : int; 421 - headers : Headers.t; 422 - request : request_ctx option; 422 + status : int; (** The HTTP status code *) 423 + headers : Headers.t; (** The response headers *) 424 + request : request_ctx option; (** The original request, if available *) 423 425 } 424 426 427 + (** Message context (request or response). *) 425 428 type t = [ 426 - | `Request of request_ctx 427 - | `Response of response_ctx 429 + | `Request of request_ctx (** A request context *) 430 + | `Response of response_ctx (** A response context *) 428 431 ] 429 432 430 433 let request ~method_ ~uri ~headers : t =
+8 -6
lib/signature.mli
··· 277 277 (** Context for resolving message components. *) 278 278 279 279 type request_ctx = { 280 - method_ : Method.t; 281 - uri : Uri.t; 282 - headers : Headers.t; 280 + method_ : Method.t; (** The HTTP method *) 281 + uri : Uri.t; (** The request URI *) 282 + headers : Headers.t; (** The request headers *) 283 283 } 284 + (** Request context for signature computation. *) 284 285 285 286 type response_ctx = { 286 - status : int; 287 - headers : Headers.t; 288 - request : request_ctx option; 287 + status : int; (** The HTTP status code *) 288 + headers : Headers.t; (** The response headers *) 289 + request : request_ctx option; (** The original request, if available *) 289 290 } 291 + (** Response context for signature computation. *) 290 292 291 293 type t = [ 292 294 | `Request of request_ctx
+4259
spec/rfc6749.txt
··· 1 + 2 + 3 + 4 + 5 + 6 + 7 + Internet Engineering Task Force (IETF) D. Hardt, Ed. 8 + Request for Comments: 6749 Microsoft 9 + Obsoletes: 5849 October 2012 10 + Category: Standards Track 11 + ISSN: 2070-1721 12 + 13 + 14 + The OAuth 2.0 Authorization Framework 15 + 16 + Abstract 17 + 18 + The OAuth 2.0 authorization framework enables a third-party 19 + application to obtain limited access to an HTTP service, either on 20 + behalf of a resource owner by orchestrating an approval interaction 21 + between the resource owner and the HTTP service, or by allowing the 22 + third-party application to obtain access on its own behalf. This 23 + specification replaces and obsoletes the OAuth 1.0 protocol described 24 + in RFC 5849. 25 + 26 + Status of This Memo 27 + 28 + This is an Internet Standards Track document. 29 + 30 + This document is a product of the Internet Engineering Task Force 31 + (IETF). It represents the consensus of the IETF community. It has 32 + received public review and has been approved for publication by the 33 + Internet Engineering Steering Group (IESG). Further information on 34 + Internet Standards is available in Section 2 of RFC 5741. 35 + 36 + Information about the current status of this document, any errata, 37 + and how to provide feedback on it may be obtained at 38 + http://www.rfc-editor.org/info/rfc6749. 39 + 40 + Copyright Notice 41 + 42 + Copyright (c) 2012 IETF Trust and the persons identified as the 43 + document authors. All rights reserved. 44 + 45 + This document is subject to BCP 78 and the IETF Trust's Legal 46 + Provisions Relating to IETF Documents 47 + (http://trustee.ietf.org/license-info) in effect on the date of 48 + publication of this document. Please review these documents 49 + carefully, as they describe your rights and restrictions with respect 50 + to this document. Code Components extracted from this document must 51 + include Simplified BSD License text as described in Section 4.e of 52 + the Trust Legal Provisions and are provided without warranty as 53 + described in the Simplified BSD License. 54 + 55 + 56 + 57 + 58 + Hardt Standards Track [Page 1] 59 + 60 + RFC 6749 OAuth 2.0 October 2012 61 + 62 + 63 + Table of Contents 64 + 65 + 1. Introduction ....................................................4 66 + 1.1. Roles ......................................................6 67 + 1.2. Protocol Flow ..............................................7 68 + 1.3. Authorization Grant ........................................8 69 + 1.3.1. Authorization Code ..................................8 70 + 1.3.2. Implicit ............................................8 71 + 1.3.3. Resource Owner Password Credentials .................9 72 + 1.3.4. Client Credentials ..................................9 73 + 1.4. Access Token ..............................................10 74 + 1.5. Refresh Token .............................................10 75 + 1.6. TLS Version ...............................................12 76 + 1.7. HTTP Redirections .........................................12 77 + 1.8. Interoperability ..........................................12 78 + 1.9. Notational Conventions ....................................13 79 + 2. Client Registration ............................................13 80 + 2.1. Client Types ..............................................14 81 + 2.2. Client Identifier .........................................15 82 + 2.3. Client Authentication .....................................16 83 + 2.3.1. Client Password ....................................16 84 + 2.3.2. Other Authentication Methods .......................17 85 + 2.4. Unregistered Clients ......................................17 86 + 3. Protocol Endpoints .............................................18 87 + 3.1. Authorization Endpoint ....................................18 88 + 3.1.1. Response Type ......................................19 89 + 3.1.2. Redirection Endpoint ...............................19 90 + 3.2. Token Endpoint ............................................21 91 + 3.2.1. Client Authentication ..............................22 92 + 3.3. Access Token Scope ........................................23 93 + 4. Obtaining Authorization ........................................23 94 + 4.1. Authorization Code Grant ..................................24 95 + 4.1.1. Authorization Request ..............................25 96 + 4.1.2. Authorization Response .............................26 97 + 4.1.3. Access Token Request ...............................29 98 + 4.1.4. Access Token Response ..............................30 99 + 4.2. Implicit Grant ............................................31 100 + 4.2.1. Authorization Request ..............................33 101 + 4.2.2. Access Token Response ..............................35 102 + 4.3. Resource Owner Password Credentials Grant .................37 103 + 4.3.1. Authorization Request and Response .................39 104 + 4.3.2. Access Token Request ...............................39 105 + 4.3.3. Access Token Response ..............................40 106 + 4.4. Client Credentials Grant ..................................40 107 + 4.4.1. Authorization Request and Response .................41 108 + 4.4.2. Access Token Request ...............................41 109 + 4.4.3. Access Token Response ..............................42 110 + 4.5. Extension Grants ..........................................42 111 + 112 + 113 + 114 + Hardt Standards Track [Page 2] 115 + 116 + RFC 6749 OAuth 2.0 October 2012 117 + 118 + 119 + 5. Issuing an Access Token ........................................43 120 + 5.1. Successful Response .......................................43 121 + 5.2. Error Response ............................................45 122 + 6. Refreshing an Access Token .....................................47 123 + 7. Accessing Protected Resources ..................................48 124 + 7.1. Access Token Types ........................................49 125 + 7.2. Error Response ............................................49 126 + 8. Extensibility ..................................................50 127 + 8.1. Defining Access Token Types ...............................50 128 + 8.2. Defining New Endpoint Parameters ..........................50 129 + 8.3. Defining New Authorization Grant Types ....................51 130 + 8.4. Defining New Authorization Endpoint Response Types ........51 131 + 8.5. Defining Additional Error Codes ...........................51 132 + 9. Native Applications ............................................52 133 + 10. Security Considerations .......................................53 134 + 10.1. Client Authentication ....................................53 135 + 10.2. Client Impersonation .....................................54 136 + 10.3. Access Tokens ............................................55 137 + 10.4. Refresh Tokens ...........................................55 138 + 10.5. Authorization Codes ......................................56 139 + 10.6. Authorization Code Redirection URI Manipulation ..........56 140 + 10.7. Resource Owner Password Credentials ......................57 141 + 10.8. Request Confidentiality ..................................58 142 + 10.9. Ensuring Endpoint Authenticity ...........................58 143 + 10.10. Credentials-Guessing Attacks ............................58 144 + 10.11. Phishing Attacks ........................................58 145 + 10.12. Cross-Site Request Forgery ..............................59 146 + 10.13. Clickjacking ............................................60 147 + 10.14. Code Injection and Input Validation .....................60 148 + 10.15. Open Redirectors ........................................60 149 + 10.16. Misuse of Access Token to Impersonate Resource 150 + Owner in Implicit Flow ..................................61 151 + 11. IANA Considerations ...........................................62 152 + 11.1. OAuth Access Token Types Registry ........................62 153 + 11.1.1. Registration Template .............................62 154 + 11.2. OAuth Parameters Registry ................................63 155 + 11.2.1. Registration Template .............................63 156 + 11.2.2. Initial Registry Contents .........................64 157 + 11.3. OAuth Authorization Endpoint Response Types Registry .....66 158 + 11.3.1. Registration Template .............................66 159 + 11.3.2. Initial Registry Contents .........................67 160 + 11.4. OAuth Extensions Error Registry ..........................67 161 + 11.4.1. Registration Template .............................68 162 + 12. References ....................................................68 163 + 12.1. Normative References .....................................68 164 + 12.2. Informative References ...................................70 165 + 166 + 167 + 168 + 169 + 170 + Hardt Standards Track [Page 3] 171 + 172 + RFC 6749 OAuth 2.0 October 2012 173 + 174 + 175 + Appendix A. Augmented Backus-Naur Form (ABNF) Syntax ..............71 176 + A.1. "client_id" Syntax ........................................71 177 + A.2. "client_secret" Syntax ....................................71 178 + A.3. "response_type" Syntax ....................................71 179 + A.4. "scope" Syntax ............................................72 180 + A.5. "state" Syntax ............................................72 181 + A.6. "redirect_uri" Syntax .....................................72 182 + A.7. "error" Syntax ............................................72 183 + A.8. "error_description" Syntax ................................72 184 + A.9. "error_uri" Syntax ........................................72 185 + A.10. "grant_type" Syntax .......................................73 186 + A.11. "code" Syntax .............................................73 187 + A.12. "access_token" Syntax .....................................73 188 + A.13. "token_type" Syntax .......................................73 189 + A.14. "expires_in" Syntax .......................................73 190 + A.15. "username" Syntax .........................................73 191 + A.16. "password" Syntax .........................................73 192 + A.17. "refresh_token" Syntax ....................................74 193 + A.18. Endpoint Parameter Syntax .................................74 194 + Appendix B. Use of application/x-www-form-urlencoded Media Type ...74 195 + Appendix C. Acknowledgements ......................................75 196 + 197 + 1. Introduction 198 + 199 + In the traditional client-server authentication model, the client 200 + requests an access-restricted resource (protected resource) on the 201 + server by authenticating with the server using the resource owner's 202 + credentials. In order to provide third-party applications access to 203 + restricted resources, the resource owner shares its credentials with 204 + the third party. This creates several problems and limitations: 205 + 206 + o Third-party applications are required to store the resource 207 + owner's credentials for future use, typically a password in 208 + clear-text. 209 + 210 + o Servers are required to support password authentication, despite 211 + the security weaknesses inherent in passwords. 212 + 213 + o Third-party applications gain overly broad access to the resource 214 + owner's protected resources, leaving resource owners without any 215 + ability to restrict duration or access to a limited subset of 216 + resources. 217 + 218 + o Resource owners cannot revoke access to an individual third party 219 + without revoking access to all third parties, and must do so by 220 + changing the third party's password. 221 + 222 + 223 + 224 + 225 + 226 + Hardt Standards Track [Page 4] 227 + 228 + RFC 6749 OAuth 2.0 October 2012 229 + 230 + 231 + o Compromise of any third-party application results in compromise of 232 + the end-user's password and all of the data protected by that 233 + password. 234 + 235 + OAuth addresses these issues by introducing an authorization layer 236 + and separating the role of the client from that of the resource 237 + owner. In OAuth, the client requests access to resources controlled 238 + by the resource owner and hosted by the resource server, and is 239 + issued a different set of credentials than those of the resource 240 + owner. 241 + 242 + Instead of using the resource owner's credentials to access protected 243 + resources, the client obtains an access token -- a string denoting a 244 + specific scope, lifetime, and other access attributes. Access tokens 245 + are issued to third-party clients by an authorization server with the 246 + approval of the resource owner. The client uses the access token to 247 + access the protected resources hosted by the resource server. 248 + 249 + For example, an end-user (resource owner) can grant a printing 250 + service (client) access to her protected photos stored at a photo- 251 + sharing service (resource server), without sharing her username and 252 + password with the printing service. Instead, she authenticates 253 + directly with a server trusted by the photo-sharing service 254 + (authorization server), which issues the printing service delegation- 255 + specific credentials (access token). 256 + 257 + This specification is designed for use with HTTP ([RFC2616]). The 258 + use of OAuth over any protocol other than HTTP is out of scope. 259 + 260 + The OAuth 1.0 protocol ([RFC5849]), published as an informational 261 + document, was the result of a small ad hoc community effort. This 262 + Standards Track specification builds on the OAuth 1.0 deployment 263 + experience, as well as additional use cases and extensibility 264 + requirements gathered from the wider IETF community. The OAuth 2.0 265 + protocol is not backward compatible with OAuth 1.0. The two versions 266 + may co-exist on the network, and implementations may choose to 267 + support both. However, it is the intention of this specification 268 + that new implementations support OAuth 2.0 as specified in this 269 + document and that OAuth 1.0 is used only to support existing 270 + deployments. The OAuth 2.0 protocol shares very few implementation 271 + details with the OAuth 1.0 protocol. Implementers familiar with 272 + OAuth 1.0 should approach this document without any assumptions as to 273 + its structure and details. 274 + 275 + 276 + 277 + 278 + 279 + 280 + 281 + 282 + Hardt Standards Track [Page 5] 283 + 284 + RFC 6749 OAuth 2.0 October 2012 285 + 286 + 287 + 1.1. Roles 288 + 289 + OAuth defines four roles: 290 + 291 + resource owner 292 + An entity capable of granting access to a protected resource. 293 + When the resource owner is a person, it is referred to as an 294 + end-user. 295 + 296 + resource server 297 + The server hosting the protected resources, capable of accepting 298 + and responding to protected resource requests using access tokens. 299 + 300 + client 301 + An application making protected resource requests on behalf of the 302 + resource owner and with its authorization. The term "client" does 303 + not imply any particular implementation characteristics (e.g., 304 + whether the application executes on a server, a desktop, or other 305 + devices). 306 + 307 + authorization server 308 + The server issuing access tokens to the client after successfully 309 + authenticating the resource owner and obtaining authorization. 310 + 311 + The interaction between the authorization server and resource server 312 + is beyond the scope of this specification. The authorization server 313 + may be the same server as the resource server or a separate entity. 314 + A single authorization server may issue access tokens accepted by 315 + multiple resource servers. 316 + 317 + 318 + 319 + 320 + 321 + 322 + 323 + 324 + 325 + 326 + 327 + 328 + 329 + 330 + 331 + 332 + 333 + 334 + 335 + 336 + 337 + 338 + Hardt Standards Track [Page 6] 339 + 340 + RFC 6749 OAuth 2.0 October 2012 341 + 342 + 343 + 1.2. Protocol Flow 344 + 345 + +--------+ +---------------+ 346 + | |--(A)- Authorization Request ->| Resource | 347 + | | | Owner | 348 + | |<-(B)-- Authorization Grant ---| | 349 + | | +---------------+ 350 + | | 351 + | | +---------------+ 352 + | |--(C)-- Authorization Grant -->| Authorization | 353 + | Client | | Server | 354 + | |<-(D)----- Access Token -------| | 355 + | | +---------------+ 356 + | | 357 + | | +---------------+ 358 + | |--(E)----- Access Token ------>| Resource | 359 + | | | Server | 360 + | |<-(F)--- Protected Resource ---| | 361 + +--------+ +---------------+ 362 + 363 + Figure 1: Abstract Protocol Flow 364 + 365 + The abstract OAuth 2.0 flow illustrated in Figure 1 describes the 366 + interaction between the four roles and includes the following steps: 367 + 368 + (A) The client requests authorization from the resource owner. The 369 + authorization request can be made directly to the resource owner 370 + (as shown), or preferably indirectly via the authorization 371 + server as an intermediary. 372 + 373 + (B) The client receives an authorization grant, which is a 374 + credential representing the resource owner's authorization, 375 + expressed using one of four grant types defined in this 376 + specification or using an extension grant type. The 377 + authorization grant type depends on the method used by the 378 + client to request authorization and the types supported by the 379 + authorization server. 380 + 381 + (C) The client requests an access token by authenticating with the 382 + authorization server and presenting the authorization grant. 383 + 384 + (D) The authorization server authenticates the client and validates 385 + the authorization grant, and if valid, issues an access token. 386 + 387 + 388 + 389 + 390 + 391 + 392 + 393 + 394 + Hardt Standards Track [Page 7] 395 + 396 + RFC 6749 OAuth 2.0 October 2012 397 + 398 + 399 + (E) The client requests the protected resource from the resource 400 + server and authenticates by presenting the access token. 401 + 402 + (F) The resource server validates the access token, and if valid, 403 + serves the request. 404 + 405 + The preferred method for the client to obtain an authorization grant 406 + from the resource owner (depicted in steps (A) and (B)) is to use the 407 + authorization server as an intermediary, which is illustrated in 408 + Figure 3 in Section 4.1. 409 + 410 + 1.3. Authorization Grant 411 + 412 + An authorization grant is a credential representing the resource 413 + owner's authorization (to access its protected resources) used by the 414 + client to obtain an access token. This specification defines four 415 + grant types -- authorization code, implicit, resource owner password 416 + credentials, and client credentials -- as well as an extensibility 417 + mechanism for defining additional types. 418 + 419 + 1.3.1. Authorization Code 420 + 421 + The authorization code is obtained by using an authorization server 422 + as an intermediary between the client and resource owner. Instead of 423 + requesting authorization directly from the resource owner, the client 424 + directs the resource owner to an authorization server (via its 425 + user-agent as defined in [RFC2616]), which in turn directs the 426 + resource owner back to the client with the authorization code. 427 + 428 + Before directing the resource owner back to the client with the 429 + authorization code, the authorization server authenticates the 430 + resource owner and obtains authorization. Because the resource owner 431 + only authenticates with the authorization server, the resource 432 + owner's credentials are never shared with the client. 433 + 434 + The authorization code provides a few important security benefits, 435 + such as the ability to authenticate the client, as well as the 436 + transmission of the access token directly to the client without 437 + passing it through the resource owner's user-agent and potentially 438 + exposing it to others, including the resource owner. 439 + 440 + 1.3.2. Implicit 441 + 442 + The implicit grant is a simplified authorization code flow optimized 443 + for clients implemented in a browser using a scripting language such 444 + as JavaScript. In the implicit flow, instead of issuing the client 445 + an authorization code, the client is issued an access token directly 446 + 447 + 448 + 449 + 450 + Hardt Standards Track [Page 8] 451 + 452 + RFC 6749 OAuth 2.0 October 2012 453 + 454 + 455 + (as the result of the resource owner authorization). The grant type 456 + is implicit, as no intermediate credentials (such as an authorization 457 + code) are issued (and later used to obtain an access token). 458 + 459 + When issuing an access token during the implicit grant flow, the 460 + authorization server does not authenticate the client. In some 461 + cases, the client identity can be verified via the redirection URI 462 + used to deliver the access token to the client. The access token may 463 + be exposed to the resource owner or other applications with access to 464 + the resource owner's user-agent. 465 + 466 + Implicit grants improve the responsiveness and efficiency of some 467 + clients (such as a client implemented as an in-browser application), 468 + since it reduces the number of round trips required to obtain an 469 + access token. However, this convenience should be weighed against 470 + the security implications of using implicit grants, such as those 471 + described in Sections 10.3 and 10.16, especially when the 472 + authorization code grant type is available. 473 + 474 + 1.3.3. Resource Owner Password Credentials 475 + 476 + The resource owner password credentials (i.e., username and password) 477 + can be used directly as an authorization grant to obtain an access 478 + token. The credentials should only be used when there is a high 479 + degree of trust between the resource owner and the client (e.g., the 480 + client is part of the device operating system or a highly privileged 481 + application), and when other authorization grant types are not 482 + available (such as an authorization code). 483 + 484 + Even though this grant type requires direct client access to the 485 + resource owner credentials, the resource owner credentials are used 486 + for a single request and are exchanged for an access token. This 487 + grant type can eliminate the need for the client to store the 488 + resource owner credentials for future use, by exchanging the 489 + credentials with a long-lived access token or refresh token. 490 + 491 + 1.3.4. Client Credentials 492 + 493 + The client credentials (or other forms of client authentication) can 494 + be used as an authorization grant when the authorization scope is 495 + limited to the protected resources under the control of the client, 496 + or to protected resources previously arranged with the authorization 497 + server. Client credentials are used as an authorization grant 498 + typically when the client is acting on its own behalf (the client is 499 + also the resource owner) or is requesting access to protected 500 + resources based on an authorization previously arranged with the 501 + authorization server. 502 + 503 + 504 + 505 + 506 + Hardt Standards Track [Page 9] 507 + 508 + RFC 6749 OAuth 2.0 October 2012 509 + 510 + 511 + 1.4. Access Token 512 + 513 + Access tokens are credentials used to access protected resources. An 514 + access token is a string representing an authorization issued to the 515 + client. The string is usually opaque to the client. Tokens 516 + represent specific scopes and durations of access, granted by the 517 + resource owner, and enforced by the resource server and authorization 518 + server. 519 + 520 + The token may denote an identifier used to retrieve the authorization 521 + information or may self-contain the authorization information in a 522 + verifiable manner (i.e., a token string consisting of some data and a 523 + signature). Additional authentication credentials, which are beyond 524 + the scope of this specification, may be required in order for the 525 + client to use a token. 526 + 527 + The access token provides an abstraction layer, replacing different 528 + authorization constructs (e.g., username and password) with a single 529 + token understood by the resource server. This abstraction enables 530 + issuing access tokens more restrictive than the authorization grant 531 + used to obtain them, as well as removing the resource server's need 532 + to understand a wide range of authentication methods. 533 + 534 + Access tokens can have different formats, structures, and methods of 535 + utilization (e.g., cryptographic properties) based on the resource 536 + server security requirements. Access token attributes and the 537 + methods used to access protected resources are beyond the scope of 538 + this specification and are defined by companion specifications such 539 + as [RFC6750]. 540 + 541 + 1.5. Refresh Token 542 + 543 + Refresh tokens are credentials used to obtain access tokens. Refresh 544 + tokens are issued to the client by the authorization server and are 545 + used to obtain a new access token when the current access token 546 + becomes invalid or expires, or to obtain additional access tokens 547 + with identical or narrower scope (access tokens may have a shorter 548 + lifetime and fewer permissions than authorized by the resource 549 + owner). Issuing a refresh token is optional at the discretion of the 550 + authorization server. If the authorization server issues a refresh 551 + token, it is included when issuing an access token (i.e., step (D) in 552 + Figure 1). 553 + 554 + A refresh token is a string representing the authorization granted to 555 + the client by the resource owner. The string is usually opaque to 556 + the client. The token denotes an identifier used to retrieve the 557 + 558 + 559 + 560 + 561 + 562 + Hardt Standards Track [Page 10] 563 + 564 + RFC 6749 OAuth 2.0 October 2012 565 + 566 + 567 + authorization information. Unlike access tokens, refresh tokens are 568 + intended for use only with authorization servers and are never sent 569 + to resource servers. 570 + 571 + +--------+ +---------------+ 572 + | |--(A)------- Authorization Grant --------->| | 573 + | | | | 574 + | |<-(B)----------- Access Token -------------| | 575 + | | & Refresh Token | | 576 + | | | | 577 + | | +----------+ | | 578 + | |--(C)---- Access Token ---->| | | | 579 + | | | | | | 580 + | |<-(D)- Protected Resource --| Resource | | Authorization | 581 + | Client | | Server | | Server | 582 + | |--(E)---- Access Token ---->| | | | 583 + | | | | | | 584 + | |<-(F)- Invalid Token Error -| | | | 585 + | | +----------+ | | 586 + | | | | 587 + | |--(G)----------- Refresh Token ----------->| | 588 + | | | | 589 + | |<-(H)----------- Access Token -------------| | 590 + +--------+ & Optional Refresh Token +---------------+ 591 + 592 + Figure 2: Refreshing an Expired Access Token 593 + 594 + The flow illustrated in Figure 2 includes the following steps: 595 + 596 + (A) The client requests an access token by authenticating with the 597 + authorization server and presenting an authorization grant. 598 + 599 + (B) The authorization server authenticates the client and validates 600 + the authorization grant, and if valid, issues an access token 601 + and a refresh token. 602 + 603 + (C) The client makes a protected resource request to the resource 604 + server by presenting the access token. 605 + 606 + (D) The resource server validates the access token, and if valid, 607 + serves the request. 608 + 609 + (E) Steps (C) and (D) repeat until the access token expires. If the 610 + client knows the access token expired, it skips to step (G); 611 + otherwise, it makes another protected resource request. 612 + 613 + (F) Since the access token is invalid, the resource server returns 614 + an invalid token error. 615 + 616 + 617 + 618 + Hardt Standards Track [Page 11] 619 + 620 + RFC 6749 OAuth 2.0 October 2012 621 + 622 + 623 + (G) The client requests a new access token by authenticating with 624 + the authorization server and presenting the refresh token. The 625 + client authentication requirements are based on the client type 626 + and on the authorization server policies. 627 + 628 + (H) The authorization server authenticates the client and validates 629 + the refresh token, and if valid, issues a new access token (and, 630 + optionally, a new refresh token). 631 + 632 + Steps (C), (D), (E), and (F) are outside the scope of this 633 + specification, as described in Section 7. 634 + 635 + 1.6. TLS Version 636 + 637 + Whenever Transport Layer Security (TLS) is used by this 638 + specification, the appropriate version (or versions) of TLS will vary 639 + over time, based on the widespread deployment and known security 640 + vulnerabilities. At the time of this writing, TLS version 1.2 641 + [RFC5246] is the most recent version, but has a very limited 642 + deployment base and might not be readily available for 643 + implementation. TLS version 1.0 [RFC2246] is the most widely 644 + deployed version and will provide the broadest interoperability. 645 + 646 + Implementations MAY also support additional transport-layer security 647 + mechanisms that meet their security requirements. 648 + 649 + 1.7. HTTP Redirections 650 + 651 + This specification makes extensive use of HTTP redirections, in which 652 + the client or the authorization server directs the resource owner's 653 + user-agent to another destination. While the examples in this 654 + specification show the use of the HTTP 302 status code, any other 655 + method available via the user-agent to accomplish this redirection is 656 + allowed and is considered to be an implementation detail. 657 + 658 + 1.8. Interoperability 659 + 660 + OAuth 2.0 provides a rich authorization framework with well-defined 661 + security properties. However, as a rich and highly extensible 662 + framework with many optional components, on its own, this 663 + specification is likely to produce a wide range of non-interoperable 664 + implementations. 665 + 666 + In addition, this specification leaves a few required components 667 + partially or fully undefined (e.g., client registration, 668 + authorization server capabilities, endpoint discovery). Without 669 + 670 + 671 + 672 + 673 + 674 + Hardt Standards Track [Page 12] 675 + 676 + RFC 6749 OAuth 2.0 October 2012 677 + 678 + 679 + these components, clients must be manually and specifically 680 + configured against a specific authorization server and resource 681 + server in order to interoperate. 682 + 683 + This framework was designed with the clear expectation that future 684 + work will define prescriptive profiles and extensions necessary to 685 + achieve full web-scale interoperability. 686 + 687 + 1.9. Notational Conventions 688 + 689 + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 690 + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 691 + specification are to be interpreted as described in [RFC2119]. 692 + 693 + This specification uses the Augmented Backus-Naur Form (ABNF) 694 + notation of [RFC5234]. Additionally, the rule URI-reference is 695 + included from "Uniform Resource Identifier (URI): Generic Syntax" 696 + [RFC3986]. 697 + 698 + Certain security-related terms are to be understood in the sense 699 + defined in [RFC4949]. These terms include, but are not limited to, 700 + "attack", "authentication", "authorization", "certificate", 701 + "confidentiality", "credential", "encryption", "identity", "sign", 702 + "signature", "trust", "validate", and "verify". 703 + 704 + Unless otherwise noted, all the protocol parameter names and values 705 + are case sensitive. 706 + 707 + 2. Client Registration 708 + 709 + Before initiating the protocol, the client registers with the 710 + authorization server. The means through which the client registers 711 + with the authorization server are beyond the scope of this 712 + specification but typically involve end-user interaction with an HTML 713 + registration form. 714 + 715 + Client registration does not require a direct interaction between the 716 + client and the authorization server. When supported by the 717 + authorization server, registration can rely on other means for 718 + establishing trust and obtaining the required client properties 719 + (e.g., redirection URI, client type). For example, registration can 720 + be accomplished using a self-issued or third-party-issued assertion, 721 + or by the authorization server performing client discovery using a 722 + trusted channel. 723 + 724 + 725 + 726 + 727 + 728 + 729 + 730 + Hardt Standards Track [Page 13] 731 + 732 + RFC 6749 OAuth 2.0 October 2012 733 + 734 + 735 + When registering a client, the client developer SHALL: 736 + 737 + o specify the client type as described in Section 2.1, 738 + 739 + o provide its client redirection URIs as described in Section 3.1.2, 740 + and 741 + 742 + o include any other information required by the authorization server 743 + (e.g., application name, website, description, logo image, the 744 + acceptance of legal terms). 745 + 746 + 2.1. Client Types 747 + 748 + OAuth defines two client types, based on their ability to 749 + authenticate securely with the authorization server (i.e., ability to 750 + maintain the confidentiality of their client credentials): 751 + 752 + confidential 753 + Clients capable of maintaining the confidentiality of their 754 + credentials (e.g., client implemented on a secure server with 755 + restricted access to the client credentials), or capable of secure 756 + client authentication using other means. 757 + 758 + public 759 + Clients incapable of maintaining the confidentiality of their 760 + credentials (e.g., clients executing on the device used by the 761 + resource owner, such as an installed native application or a web 762 + browser-based application), and incapable of secure client 763 + authentication via any other means. 764 + 765 + The client type designation is based on the authorization server's 766 + definition of secure authentication and its acceptable exposure 767 + levels of client credentials. The authorization server SHOULD NOT 768 + make assumptions about the client type. 769 + 770 + A client may be implemented as a distributed set of components, each 771 + with a different client type and security context (e.g., a 772 + distributed client with both a confidential server-based component 773 + and a public browser-based component). If the authorization server 774 + does not provide support for such clients or does not provide 775 + guidance with regard to their registration, the client SHOULD 776 + register each component as a separate client. 777 + 778 + 779 + 780 + 781 + 782 + 783 + 784 + 785 + 786 + Hardt Standards Track [Page 14] 787 + 788 + RFC 6749 OAuth 2.0 October 2012 789 + 790 + 791 + This specification has been designed around the following client 792 + profiles: 793 + 794 + web application 795 + A web application is a confidential client running on a web 796 + server. Resource owners access the client via an HTML user 797 + interface rendered in a user-agent on the device used by the 798 + resource owner. The client credentials as well as any access 799 + token issued to the client are stored on the web server and are 800 + not exposed to or accessible by the resource owner. 801 + 802 + user-agent-based application 803 + A user-agent-based application is a public client in which the 804 + client code is downloaded from a web server and executes within a 805 + user-agent (e.g., web browser) on the device used by the resource 806 + owner. Protocol data and credentials are easily accessible (and 807 + often visible) to the resource owner. Since such applications 808 + reside within the user-agent, they can make seamless use of the 809 + user-agent capabilities when requesting authorization. 810 + 811 + native application 812 + A native application is a public client installed and executed on 813 + the device used by the resource owner. Protocol data and 814 + credentials are accessible to the resource owner. It is assumed 815 + that any client authentication credentials included in the 816 + application can be extracted. On the other hand, dynamically 817 + issued credentials such as access tokens or refresh tokens can 818 + receive an acceptable level of protection. At a minimum, these 819 + credentials are protected from hostile servers with which the 820 + application may interact. On some platforms, these credentials 821 + might be protected from other applications residing on the same 822 + device. 823 + 824 + 2.2. Client Identifier 825 + 826 + The authorization server issues the registered client a client 827 + identifier -- a unique string representing the registration 828 + information provided by the client. The client identifier is not a 829 + secret; it is exposed to the resource owner and MUST NOT be used 830 + alone for client authentication. The client identifier is unique to 831 + the authorization server. 832 + 833 + The client identifier string size is left undefined by this 834 + specification. The client should avoid making assumptions about the 835 + identifier size. The authorization server SHOULD document the size 836 + of any identifier it issues. 837 + 838 + 839 + 840 + 841 + 842 + Hardt Standards Track [Page 15] 843 + 844 + RFC 6749 OAuth 2.0 October 2012 845 + 846 + 847 + 2.3. Client Authentication 848 + 849 + If the client type is confidential, the client and authorization 850 + server establish a client authentication method suitable for the 851 + security requirements of the authorization server. The authorization 852 + server MAY accept any form of client authentication meeting its 853 + security requirements. 854 + 855 + Confidential clients are typically issued (or establish) a set of 856 + client credentials used for authenticating with the authorization 857 + server (e.g., password, public/private key pair). 858 + 859 + The authorization server MAY establish a client authentication method 860 + with public clients. However, the authorization server MUST NOT rely 861 + on public client authentication for the purpose of identifying the 862 + client. 863 + 864 + The client MUST NOT use more than one authentication method in each 865 + request. 866 + 867 + 2.3.1. Client Password 868 + 869 + Clients in possession of a client password MAY use the HTTP Basic 870 + authentication scheme as defined in [RFC2617] to authenticate with 871 + the authorization server. The client identifier is encoded using the 872 + "application/x-www-form-urlencoded" encoding algorithm per 873 + Appendix B, and the encoded value is used as the username; the client 874 + password is encoded using the same algorithm and used as the 875 + password. The authorization server MUST support the HTTP Basic 876 + authentication scheme for authenticating clients that were issued a 877 + client password. 878 + 879 + For example (with extra line breaks for display purposes only): 880 + 881 + Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3 882 + 883 + Alternatively, the authorization server MAY support including the 884 + client credentials in the request-body using the following 885 + parameters: 886 + 887 + client_id 888 + REQUIRED. The client identifier issued to the client during 889 + the registration process described by Section 2.2. 890 + 891 + client_secret 892 + REQUIRED. The client secret. The client MAY omit the 893 + parameter if the client secret is an empty string. 894 + 895 + 896 + 897 + 898 + Hardt Standards Track [Page 16] 899 + 900 + RFC 6749 OAuth 2.0 October 2012 901 + 902 + 903 + Including the client credentials in the request-body using the two 904 + parameters is NOT RECOMMENDED and SHOULD be limited to clients unable 905 + to directly utilize the HTTP Basic authentication scheme (or other 906 + password-based HTTP authentication schemes). The parameters can only 907 + be transmitted in the request-body and MUST NOT be included in the 908 + request URI. 909 + 910 + For example, a request to refresh an access token (Section 6) using 911 + the body parameters (with extra line breaks for display purposes 912 + only): 913 + 914 + POST /token HTTP/1.1 915 + Host: server.example.com 916 + Content-Type: application/x-www-form-urlencoded 917 + 918 + grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA 919 + &client_id=s6BhdRkqt3&client_secret=7Fjfp0ZBr1KtDRbnfVdmIw 920 + 921 + The authorization server MUST require the use of TLS as described in 922 + Section 1.6 when sending requests using password authentication. 923 + 924 + Since this client authentication method involves a password, the 925 + authorization server MUST protect any endpoint utilizing it against 926 + brute force attacks. 927 + 928 + 2.3.2. Other Authentication Methods 929 + 930 + The authorization server MAY support any suitable HTTP authentication 931 + scheme matching its security requirements. When using other 932 + authentication methods, the authorization server MUST define a 933 + mapping between the client identifier (registration record) and 934 + authentication scheme. 935 + 936 + 2.4. Unregistered Clients 937 + 938 + This specification does not exclude the use of unregistered clients. 939 + However, the use of such clients is beyond the scope of this 940 + specification and requires additional security analysis and review of 941 + its interoperability impact. 942 + 943 + 944 + 945 + 946 + 947 + 948 + 949 + 950 + 951 + 952 + 953 + 954 + Hardt Standards Track [Page 17] 955 + 956 + RFC 6749 OAuth 2.0 October 2012 957 + 958 + 959 + 3. Protocol Endpoints 960 + 961 + The authorization process utilizes two authorization server endpoints 962 + (HTTP resources): 963 + 964 + o Authorization endpoint - used by the client to obtain 965 + authorization from the resource owner via user-agent redirection. 966 + 967 + o Token endpoint - used by the client to exchange an authorization 968 + grant for an access token, typically with client authentication. 969 + 970 + As well as one client endpoint: 971 + 972 + o Redirection endpoint - used by the authorization server to return 973 + responses containing authorization credentials to the client via 974 + the resource owner user-agent. 975 + 976 + Not every authorization grant type utilizes both endpoints. 977 + Extension grant types MAY define additional endpoints as needed. 978 + 979 + 3.1. Authorization Endpoint 980 + 981 + The authorization endpoint is used to interact with the resource 982 + owner and obtain an authorization grant. The authorization server 983 + MUST first verify the identity of the resource owner. The way in 984 + which the authorization server authenticates the resource owner 985 + (e.g., username and password login, session cookies) is beyond the 986 + scope of this specification. 987 + 988 + The means through which the client obtains the location of the 989 + authorization endpoint are beyond the scope of this specification, 990 + but the location is typically provided in the service documentation. 991 + 992 + The endpoint URI MAY include an "application/x-www-form-urlencoded" 993 + formatted (per Appendix B) query component ([RFC3986] Section 3.4), 994 + which MUST be retained when adding additional query parameters. The 995 + endpoint URI MUST NOT include a fragment component. 996 + 997 + Since requests to the authorization endpoint result in user 998 + authentication and the transmission of clear-text credentials (in the 999 + HTTP response), the authorization server MUST require the use of TLS 1000 + as described in Section 1.6 when sending requests to the 1001 + authorization endpoint. 1002 + 1003 + The authorization server MUST support the use of the HTTP "GET" 1004 + method [RFC2616] for the authorization endpoint and MAY support the 1005 + use of the "POST" method as well. 1006 + 1007 + 1008 + 1009 + 1010 + Hardt Standards Track [Page 18] 1011 + 1012 + RFC 6749 OAuth 2.0 October 2012 1013 + 1014 + 1015 + Parameters sent without a value MUST be treated as if they were 1016 + omitted from the request. The authorization server MUST ignore 1017 + unrecognized request parameters. Request and response parameters 1018 + MUST NOT be included more than once. 1019 + 1020 + 3.1.1. Response Type 1021 + 1022 + The authorization endpoint is used by the authorization code grant 1023 + type and implicit grant type flows. The client informs the 1024 + authorization server of the desired grant type using the following 1025 + parameter: 1026 + 1027 + response_type 1028 + REQUIRED. The value MUST be one of "code" for requesting an 1029 + authorization code as described by Section 4.1.1, "token" for 1030 + requesting an access token (implicit grant) as described by 1031 + Section 4.2.1, or a registered extension value as described by 1032 + Section 8.4. 1033 + 1034 + Extension response types MAY contain a space-delimited (%x20) list of 1035 + values, where the order of values does not matter (e.g., response 1036 + type "a b" is the same as "b a"). The meaning of such composite 1037 + response types is defined by their respective specifications. 1038 + 1039 + If an authorization request is missing the "response_type" parameter, 1040 + or if the response type is not understood, the authorization server 1041 + MUST return an error response as described in Section 4.1.2.1. 1042 + 1043 + 3.1.2. Redirection Endpoint 1044 + 1045 + After completing its interaction with the resource owner, the 1046 + authorization server directs the resource owner's user-agent back to 1047 + the client. The authorization server redirects the user-agent to the 1048 + client's redirection endpoint previously established with the 1049 + authorization server during the client registration process or when 1050 + making the authorization request. 1051 + 1052 + The redirection endpoint URI MUST be an absolute URI as defined by 1053 + [RFC3986] Section 4.3. The endpoint URI MAY include an 1054 + "application/x-www-form-urlencoded" formatted (per Appendix B) query 1055 + component ([RFC3986] Section 3.4), which MUST be retained when adding 1056 + additional query parameters. The endpoint URI MUST NOT include a 1057 + fragment component. 1058 + 1059 + 1060 + 1061 + 1062 + 1063 + 1064 + 1065 + 1066 + Hardt Standards Track [Page 19] 1067 + 1068 + RFC 6749 OAuth 2.0 October 2012 1069 + 1070 + 1071 + 3.1.2.1. Endpoint Request Confidentiality 1072 + 1073 + The redirection endpoint SHOULD require the use of TLS as described 1074 + in Section 1.6 when the requested response type is "code" or "token", 1075 + or when the redirection request will result in the transmission of 1076 + sensitive credentials over an open network. This specification does 1077 + not mandate the use of TLS because at the time of this writing, 1078 + requiring clients to deploy TLS is a significant hurdle for many 1079 + client developers. If TLS is not available, the authorization server 1080 + SHOULD warn the resource owner about the insecure endpoint prior to 1081 + redirection (e.g., display a message during the authorization 1082 + request). 1083 + 1084 + Lack of transport-layer security can have a severe impact on the 1085 + security of the client and the protected resources it is authorized 1086 + to access. The use of transport-layer security is particularly 1087 + critical when the authorization process is used as a form of 1088 + delegated end-user authentication by the client (e.g., third-party 1089 + sign-in service). 1090 + 1091 + 3.1.2.2. Registration Requirements 1092 + 1093 + The authorization server MUST require the following clients to 1094 + register their redirection endpoint: 1095 + 1096 + o Public clients. 1097 + 1098 + o Confidential clients utilizing the implicit grant type. 1099 + 1100 + The authorization server SHOULD require all clients to register their 1101 + redirection endpoint prior to utilizing the authorization endpoint. 1102 + 1103 + The authorization server SHOULD require the client to provide the 1104 + complete redirection URI (the client MAY use the "state" request 1105 + parameter to achieve per-request customization). If requiring the 1106 + registration of the complete redirection URI is not possible, the 1107 + authorization server SHOULD require the registration of the URI 1108 + scheme, authority, and path (allowing the client to dynamically vary 1109 + only the query component of the redirection URI when requesting 1110 + authorization). 1111 + 1112 + The authorization server MAY allow the client to register multiple 1113 + redirection endpoints. 1114 + 1115 + Lack of a redirection URI registration requirement can enable an 1116 + attacker to use the authorization endpoint as an open redirector as 1117 + described in Section 10.15. 1118 + 1119 + 1120 + 1121 + 1122 + Hardt Standards Track [Page 20] 1123 + 1124 + RFC 6749 OAuth 2.0 October 2012 1125 + 1126 + 1127 + 3.1.2.3. Dynamic Configuration 1128 + 1129 + If multiple redirection URIs have been registered, if only part of 1130 + the redirection URI has been registered, or if no redirection URI has 1131 + been registered, the client MUST include a redirection URI with the 1132 + authorization request using the "redirect_uri" request parameter. 1133 + 1134 + When a redirection URI is included in an authorization request, the 1135 + authorization server MUST compare and match the value received 1136 + against at least one of the registered redirection URIs (or URI 1137 + components) as defined in [RFC3986] Section 6, if any redirection 1138 + URIs were registered. If the client registration included the full 1139 + redirection URI, the authorization server MUST compare the two URIs 1140 + using simple string comparison as defined in [RFC3986] Section 6.2.1. 1141 + 1142 + 3.1.2.4. Invalid Endpoint 1143 + 1144 + If an authorization request fails validation due to a missing, 1145 + invalid, or mismatching redirection URI, the authorization server 1146 + SHOULD inform the resource owner of the error and MUST NOT 1147 + automatically redirect the user-agent to the invalid redirection URI. 1148 + 1149 + 3.1.2.5. Endpoint Content 1150 + 1151 + The redirection request to the client's endpoint typically results in 1152 + an HTML document response, processed by the user-agent. If the HTML 1153 + response is served directly as the result of the redirection request, 1154 + any script included in the HTML document will execute with full 1155 + access to the redirection URI and the credentials it contains. 1156 + 1157 + The client SHOULD NOT include any third-party scripts (e.g., third- 1158 + party analytics, social plug-ins, ad networks) in the redirection 1159 + endpoint response. Instead, it SHOULD extract the credentials from 1160 + the URI and redirect the user-agent again to another endpoint without 1161 + exposing the credentials (in the URI or elsewhere). If third-party 1162 + scripts are included, the client MUST ensure that its own scripts 1163 + (used to extract and remove the credentials from the URI) will 1164 + execute first. 1165 + 1166 + 3.2. Token Endpoint 1167 + 1168 + The token endpoint is used by the client to obtain an access token by 1169 + presenting its authorization grant or refresh token. The token 1170 + endpoint is used with every authorization grant except for the 1171 + implicit grant type (since an access token is issued directly). 1172 + 1173 + 1174 + 1175 + 1176 + 1177 + 1178 + Hardt Standards Track [Page 21] 1179 + 1180 + RFC 6749 OAuth 2.0 October 2012 1181 + 1182 + 1183 + The means through which the client obtains the location of the token 1184 + endpoint are beyond the scope of this specification, but the location 1185 + is typically provided in the service documentation. 1186 + 1187 + The endpoint URI MAY include an "application/x-www-form-urlencoded" 1188 + formatted (per Appendix B) query component ([RFC3986] Section 3.4), 1189 + which MUST be retained when adding additional query parameters. The 1190 + endpoint URI MUST NOT include a fragment component. 1191 + 1192 + Since requests to the token endpoint result in the transmission of 1193 + clear-text credentials (in the HTTP request and response), the 1194 + authorization server MUST require the use of TLS as described in 1195 + Section 1.6 when sending requests to the token endpoint. 1196 + 1197 + The client MUST use the HTTP "POST" method when making access token 1198 + requests. 1199 + 1200 + Parameters sent without a value MUST be treated as if they were 1201 + omitted from the request. The authorization server MUST ignore 1202 + unrecognized request parameters. Request and response parameters 1203 + MUST NOT be included more than once. 1204 + 1205 + 3.2.1. Client Authentication 1206 + 1207 + Confidential clients or other clients issued client credentials MUST 1208 + authenticate with the authorization server as described in 1209 + Section 2.3 when making requests to the token endpoint. Client 1210 + authentication is used for: 1211 + 1212 + o Enforcing the binding of refresh tokens and authorization codes to 1213 + the client they were issued to. Client authentication is critical 1214 + when an authorization code is transmitted to the redirection 1215 + endpoint over an insecure channel or when the redirection URI has 1216 + not been registered in full. 1217 + 1218 + o Recovering from a compromised client by disabling the client or 1219 + changing its credentials, thus preventing an attacker from abusing 1220 + stolen refresh tokens. Changing a single set of client 1221 + credentials is significantly faster than revoking an entire set of 1222 + refresh tokens. 1223 + 1224 + o Implementing authentication management best practices, which 1225 + require periodic credential rotation. Rotation of an entire set 1226 + of refresh tokens can be challenging, while rotation of a single 1227 + set of client credentials is significantly easier. 1228 + 1229 + 1230 + 1231 + 1232 + 1233 + 1234 + Hardt Standards Track [Page 22] 1235 + 1236 + RFC 6749 OAuth 2.0 October 2012 1237 + 1238 + 1239 + A client MAY use the "client_id" request parameter to identify itself 1240 + when sending requests to the token endpoint. In the 1241 + "authorization_code" "grant_type" request to the token endpoint, an 1242 + unauthenticated client MUST send its "client_id" to prevent itself 1243 + from inadvertently accepting a code intended for a client with a 1244 + different "client_id". This protects the client from substitution of 1245 + the authentication code. (It provides no additional security for the 1246 + protected resource.) 1247 + 1248 + 3.3. Access Token Scope 1249 + 1250 + The authorization and token endpoints allow the client to specify the 1251 + scope of the access request using the "scope" request parameter. In 1252 + turn, the authorization server uses the "scope" response parameter to 1253 + inform the client of the scope of the access token issued. 1254 + 1255 + The value of the scope parameter is expressed as a list of space- 1256 + delimited, case-sensitive strings. The strings are defined by the 1257 + authorization server. If the value contains multiple space-delimited 1258 + strings, their order does not matter, and each string adds an 1259 + additional access range to the requested scope. 1260 + 1261 + scope = scope-token *( SP scope-token ) 1262 + scope-token = 1*( %x21 / %x23-5B / %x5D-7E ) 1263 + 1264 + The authorization server MAY fully or partially ignore the scope 1265 + requested by the client, based on the authorization server policy or 1266 + the resource owner's instructions. If the issued access token scope 1267 + is different from the one requested by the client, the authorization 1268 + server MUST include the "scope" response parameter to inform the 1269 + client of the actual scope granted. 1270 + 1271 + If the client omits the scope parameter when requesting 1272 + authorization, the authorization server MUST either process the 1273 + request using a pre-defined default value or fail the request 1274 + indicating an invalid scope. The authorization server SHOULD 1275 + document its scope requirements and default value (if defined). 1276 + 1277 + 4. Obtaining Authorization 1278 + 1279 + To request an access token, the client obtains authorization from the 1280 + resource owner. The authorization is expressed in the form of an 1281 + authorization grant, which the client uses to request the access 1282 + token. OAuth defines four grant types: authorization code, implicit, 1283 + resource owner password credentials, and client credentials. It also 1284 + provides an extension mechanism for defining additional grant types. 1285 + 1286 + 1287 + 1288 + 1289 + 1290 + Hardt Standards Track [Page 23] 1291 + 1292 + RFC 6749 OAuth 2.0 October 2012 1293 + 1294 + 1295 + 4.1. Authorization Code Grant 1296 + 1297 + The authorization code grant type is used to obtain both access 1298 + tokens and refresh tokens and is optimized for confidential clients. 1299 + Since this is a redirection-based flow, the client must be capable of 1300 + interacting with the resource owner's user-agent (typically a web 1301 + browser) and capable of receiving incoming requests (via redirection) 1302 + from the authorization server. 1303 + 1304 + +----------+ 1305 + | Resource | 1306 + | Owner | 1307 + | | 1308 + +----------+ 1309 + ^ 1310 + | 1311 + (B) 1312 + +----|-----+ Client Identifier +---------------+ 1313 + | -+----(A)-- & Redirection URI ---->| | 1314 + | User- | | Authorization | 1315 + | Agent -+----(B)-- User authenticates --->| Server | 1316 + | | | | 1317 + | -+----(C)-- Authorization Code ---<| | 1318 + +-|----|---+ +---------------+ 1319 + | | ^ v 1320 + (A) (C) | | 1321 + | | | | 1322 + ^ v | | 1323 + +---------+ | | 1324 + | |>---(D)-- Authorization Code ---------' | 1325 + | Client | & Redirection URI | 1326 + | | | 1327 + | |<---(E)----- Access Token -------------------' 1328 + +---------+ (w/ Optional Refresh Token) 1329 + 1330 + Note: The lines illustrating steps (A), (B), and (C) are broken into 1331 + two parts as they pass through the user-agent. 1332 + 1333 + Figure 3: Authorization Code Flow 1334 + 1335 + 1336 + 1337 + 1338 + 1339 + 1340 + 1341 + 1342 + 1343 + 1344 + 1345 + 1346 + Hardt Standards Track [Page 24] 1347 + 1348 + RFC 6749 OAuth 2.0 October 2012 1349 + 1350 + 1351 + The flow illustrated in Figure 3 includes the following steps: 1352 + 1353 + (A) The client initiates the flow by directing the resource owner's 1354 + user-agent to the authorization endpoint. The client includes 1355 + its client identifier, requested scope, local state, and a 1356 + redirection URI to which the authorization server will send the 1357 + user-agent back once access is granted (or denied). 1358 + 1359 + (B) The authorization server authenticates the resource owner (via 1360 + the user-agent) and establishes whether the resource owner 1361 + grants or denies the client's access request. 1362 + 1363 + (C) Assuming the resource owner grants access, the authorization 1364 + server redirects the user-agent back to the client using the 1365 + redirection URI provided earlier (in the request or during 1366 + client registration). The redirection URI includes an 1367 + authorization code and any local state provided by the client 1368 + earlier. 1369 + 1370 + (D) The client requests an access token from the authorization 1371 + server's token endpoint by including the authorization code 1372 + received in the previous step. When making the request, the 1373 + client authenticates with the authorization server. The client 1374 + includes the redirection URI used to obtain the authorization 1375 + code for verification. 1376 + 1377 + (E) The authorization server authenticates the client, validates the 1378 + authorization code, and ensures that the redirection URI 1379 + received matches the URI used to redirect the client in 1380 + step (C). If valid, the authorization server responds back with 1381 + an access token and, optionally, a refresh token. 1382 + 1383 + 4.1.1. Authorization Request 1384 + 1385 + The client constructs the request URI by adding the following 1386 + parameters to the query component of the authorization endpoint URI 1387 + using the "application/x-www-form-urlencoded" format, per Appendix B: 1388 + 1389 + response_type 1390 + REQUIRED. Value MUST be set to "code". 1391 + 1392 + client_id 1393 + REQUIRED. The client identifier as described in Section 2.2. 1394 + 1395 + redirect_uri 1396 + OPTIONAL. As described in Section 3.1.2. 1397 + 1398 + 1399 + 1400 + 1401 + 1402 + Hardt Standards Track [Page 25] 1403 + 1404 + RFC 6749 OAuth 2.0 October 2012 1405 + 1406 + 1407 + scope 1408 + OPTIONAL. The scope of the access request as described by 1409 + Section 3.3. 1410 + 1411 + state 1412 + RECOMMENDED. An opaque value used by the client to maintain 1413 + state between the request and callback. The authorization 1414 + server includes this value when redirecting the user-agent back 1415 + to the client. The parameter SHOULD be used for preventing 1416 + cross-site request forgery as described in Section 10.12. 1417 + 1418 + The client directs the resource owner to the constructed URI using an 1419 + HTTP redirection response, or by other means available to it via the 1420 + user-agent. 1421 + 1422 + For example, the client directs the user-agent to make the following 1423 + HTTP request using TLS (with extra line breaks for display purposes 1424 + only): 1425 + 1426 + GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz 1427 + &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1 1428 + Host: server.example.com 1429 + 1430 + The authorization server validates the request to ensure that all 1431 + required parameters are present and valid. If the request is valid, 1432 + the authorization server authenticates the resource owner and obtains 1433 + an authorization decision (by asking the resource owner or by 1434 + establishing approval via other means). 1435 + 1436 + When a decision is established, the authorization server directs the 1437 + user-agent to the provided client redirection URI using an HTTP 1438 + redirection response, or by other means available to it via the 1439 + user-agent. 1440 + 1441 + 4.1.2. Authorization Response 1442 + 1443 + If the resource owner grants the access request, the authorization 1444 + server issues an authorization code and delivers it to the client by 1445 + adding the following parameters to the query component of the 1446 + redirection URI using the "application/x-www-form-urlencoded" format, 1447 + per Appendix B: 1448 + 1449 + code 1450 + REQUIRED. The authorization code generated by the 1451 + authorization server. The authorization code MUST expire 1452 + shortly after it is issued to mitigate the risk of leaks. A 1453 + maximum authorization code lifetime of 10 minutes is 1454 + RECOMMENDED. The client MUST NOT use the authorization code 1455 + 1456 + 1457 + 1458 + Hardt Standards Track [Page 26] 1459 + 1460 + RFC 6749 OAuth 2.0 October 2012 1461 + 1462 + 1463 + more than once. If an authorization code is used more than 1464 + once, the authorization server MUST deny the request and SHOULD 1465 + revoke (when possible) all tokens previously issued based on 1466 + that authorization code. The authorization code is bound to 1467 + the client identifier and redirection URI. 1468 + 1469 + state 1470 + REQUIRED if the "state" parameter was present in the client 1471 + authorization request. The exact value received from the 1472 + client. 1473 + 1474 + For example, the authorization server redirects the user-agent by 1475 + sending the following HTTP response: 1476 + 1477 + HTTP/1.1 302 Found 1478 + Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA 1479 + &state=xyz 1480 + 1481 + The client MUST ignore unrecognized response parameters. The 1482 + authorization code string size is left undefined by this 1483 + specification. The client should avoid making assumptions about code 1484 + value sizes. The authorization server SHOULD document the size of 1485 + any value it issues. 1486 + 1487 + 4.1.2.1. Error Response 1488 + 1489 + If the request fails due to a missing, invalid, or mismatching 1490 + redirection URI, or if the client identifier is missing or invalid, 1491 + the authorization server SHOULD inform the resource owner of the 1492 + error and MUST NOT automatically redirect the user-agent to the 1493 + invalid redirection URI. 1494 + 1495 + If the resource owner denies the access request or if the request 1496 + fails for reasons other than a missing or invalid redirection URI, 1497 + the authorization server informs the client by adding the following 1498 + parameters to the query component of the redirection URI using the 1499 + "application/x-www-form-urlencoded" format, per Appendix B: 1500 + 1501 + error 1502 + REQUIRED. A single ASCII [USASCII] error code from the 1503 + following: 1504 + 1505 + invalid_request 1506 + The request is missing a required parameter, includes an 1507 + invalid parameter value, includes a parameter more than 1508 + once, or is otherwise malformed. 1509 + 1510 + 1511 + 1512 + 1513 + 1514 + Hardt Standards Track [Page 27] 1515 + 1516 + RFC 6749 OAuth 2.0 October 2012 1517 + 1518 + 1519 + unauthorized_client 1520 + The client is not authorized to request an authorization 1521 + code using this method. 1522 + 1523 + access_denied 1524 + The resource owner or authorization server denied the 1525 + request. 1526 + 1527 + unsupported_response_type 1528 + The authorization server does not support obtaining an 1529 + authorization code using this method. 1530 + 1531 + invalid_scope 1532 + The requested scope is invalid, unknown, or malformed. 1533 + 1534 + server_error 1535 + The authorization server encountered an unexpected 1536 + condition that prevented it from fulfilling the request. 1537 + (This error code is needed because a 500 Internal Server 1538 + Error HTTP status code cannot be returned to the client 1539 + via an HTTP redirect.) 1540 + 1541 + temporarily_unavailable 1542 + The authorization server is currently unable to handle 1543 + the request due to a temporary overloading or maintenance 1544 + of the server. (This error code is needed because a 503 1545 + Service Unavailable HTTP status code cannot be returned 1546 + to the client via an HTTP redirect.) 1547 + 1548 + Values for the "error" parameter MUST NOT include characters 1549 + outside the set %x20-21 / %x23-5B / %x5D-7E. 1550 + 1551 + error_description 1552 + OPTIONAL. Human-readable ASCII [USASCII] text providing 1553 + additional information, used to assist the client developer in 1554 + understanding the error that occurred. 1555 + Values for the "error_description" parameter MUST NOT include 1556 + characters outside the set %x20-21 / %x23-5B / %x5D-7E. 1557 + 1558 + error_uri 1559 + OPTIONAL. A URI identifying a human-readable web page with 1560 + information about the error, used to provide the client 1561 + developer with additional information about the error. 1562 + Values for the "error_uri" parameter MUST conform to the 1563 + URI-reference syntax and thus MUST NOT include characters 1564 + outside the set %x21 / %x23-5B / %x5D-7E. 1565 + 1566 + 1567 + 1568 + 1569 + 1570 + Hardt Standards Track [Page 28] 1571 + 1572 + RFC 6749 OAuth 2.0 October 2012 1573 + 1574 + 1575 + state 1576 + REQUIRED if a "state" parameter was present in the client 1577 + authorization request. The exact value received from the 1578 + client. 1579 + 1580 + For example, the authorization server redirects the user-agent by 1581 + sending the following HTTP response: 1582 + 1583 + HTTP/1.1 302 Found 1584 + Location: https://client.example.com/cb?error=access_denied&state=xyz 1585 + 1586 + 4.1.3. Access Token Request 1587 + 1588 + The client makes a request to the token endpoint by sending the 1589 + following parameters using the "application/x-www-form-urlencoded" 1590 + format per Appendix B with a character encoding of UTF-8 in the HTTP 1591 + request entity-body: 1592 + 1593 + grant_type 1594 + REQUIRED. Value MUST be set to "authorization_code". 1595 + 1596 + code 1597 + REQUIRED. The authorization code received from the 1598 + authorization server. 1599 + 1600 + redirect_uri 1601 + REQUIRED, if the "redirect_uri" parameter was included in the 1602 + authorization request as described in Section 4.1.1, and their 1603 + values MUST be identical. 1604 + 1605 + client_id 1606 + REQUIRED, if the client is not authenticating with the 1607 + authorization server as described in Section 3.2.1. 1608 + 1609 + If the client type is confidential or the client was issued client 1610 + credentials (or assigned other authentication requirements), the 1611 + client MUST authenticate with the authorization server as described 1612 + in Section 3.2.1. 1613 + 1614 + 1615 + 1616 + 1617 + 1618 + 1619 + 1620 + 1621 + 1622 + 1623 + 1624 + 1625 + 1626 + Hardt Standards Track [Page 29] 1627 + 1628 + RFC 6749 OAuth 2.0 October 2012 1629 + 1630 + 1631 + For example, the client makes the following HTTP request using TLS 1632 + (with extra line breaks for display purposes only): 1633 + 1634 + POST /token HTTP/1.1 1635 + Host: server.example.com 1636 + Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW 1637 + Content-Type: application/x-www-form-urlencoded 1638 + 1639 + grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA 1640 + &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb 1641 + 1642 + The authorization server MUST: 1643 + 1644 + o require client authentication for confidential clients or for any 1645 + client that was issued client credentials (or with other 1646 + authentication requirements), 1647 + 1648 + o authenticate the client if client authentication is included, 1649 + 1650 + o ensure that the authorization code was issued to the authenticated 1651 + confidential client, or if the client is public, ensure that the 1652 + code was issued to "client_id" in the request, 1653 + 1654 + o verify that the authorization code is valid, and 1655 + 1656 + o ensure that the "redirect_uri" parameter is present if the 1657 + "redirect_uri" parameter was included in the initial authorization 1658 + request as described in Section 4.1.1, and if included ensure that 1659 + their values are identical. 1660 + 1661 + 4.1.4. Access Token Response 1662 + 1663 + If the access token request is valid and authorized, the 1664 + authorization server issues an access token and optional refresh 1665 + token as described in Section 5.1. If the request client 1666 + authentication failed or is invalid, the authorization server returns 1667 + an error response as described in Section 5.2. 1668 + 1669 + 1670 + 1671 + 1672 + 1673 + 1674 + 1675 + 1676 + 1677 + 1678 + 1679 + 1680 + 1681 + 1682 + Hardt Standards Track [Page 30] 1683 + 1684 + RFC 6749 OAuth 2.0 October 2012 1685 + 1686 + 1687 + An example successful response: 1688 + 1689 + HTTP/1.1 200 OK 1690 + Content-Type: application/json;charset=UTF-8 1691 + Cache-Control: no-store 1692 + Pragma: no-cache 1693 + 1694 + { 1695 + "access_token":"2YotnFZFEjr1zCsicMWpAA", 1696 + "token_type":"example", 1697 + "expires_in":3600, 1698 + "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", 1699 + "example_parameter":"example_value" 1700 + } 1701 + 1702 + 4.2. Implicit Grant 1703 + 1704 + The implicit grant type is used to obtain access tokens (it does not 1705 + support the issuance of refresh tokens) and is optimized for public 1706 + clients known to operate a particular redirection URI. These clients 1707 + are typically implemented in a browser using a scripting language 1708 + such as JavaScript. 1709 + 1710 + Since this is a redirection-based flow, the client must be capable of 1711 + interacting with the resource owner's user-agent (typically a web 1712 + browser) and capable of receiving incoming requests (via redirection) 1713 + from the authorization server. 1714 + 1715 + Unlike the authorization code grant type, in which the client makes 1716 + separate requests for authorization and for an access token, the 1717 + client receives the access token as the result of the authorization 1718 + request. 1719 + 1720 + The implicit grant type does not include client authentication, and 1721 + relies on the presence of the resource owner and the registration of 1722 + the redirection URI. Because the access token is encoded into the 1723 + redirection URI, it may be exposed to the resource owner and other 1724 + applications residing on the same device. 1725 + 1726 + 1727 + 1728 + 1729 + 1730 + 1731 + 1732 + 1733 + 1734 + 1735 + 1736 + 1737 + 1738 + Hardt Standards Track [Page 31] 1739 + 1740 + RFC 6749 OAuth 2.0 October 2012 1741 + 1742 + 1743 + +----------+ 1744 + | Resource | 1745 + | Owner | 1746 + | | 1747 + +----------+ 1748 + ^ 1749 + | 1750 + (B) 1751 + +----|-----+ Client Identifier +---------------+ 1752 + | -+----(A)-- & Redirection URI --->| | 1753 + | User- | | Authorization | 1754 + | Agent -|----(B)-- User authenticates -->| Server | 1755 + | | | | 1756 + | |<---(C)--- Redirection URI ----<| | 1757 + | | with Access Token +---------------+ 1758 + | | in Fragment 1759 + | | +---------------+ 1760 + | |----(D)--- Redirection URI ---->| Web-Hosted | 1761 + | | without Fragment | Client | 1762 + | | | Resource | 1763 + | (F) |<---(E)------- Script ---------<| | 1764 + | | +---------------+ 1765 + +-|--------+ 1766 + | | 1767 + (A) (G) Access Token 1768 + | | 1769 + ^ v 1770 + +---------+ 1771 + | | 1772 + | Client | 1773 + | | 1774 + +---------+ 1775 + 1776 + Note: The lines illustrating steps (A) and (B) are broken into two 1777 + parts as they pass through the user-agent. 1778 + 1779 + Figure 4: Implicit Grant Flow 1780 + 1781 + 1782 + 1783 + 1784 + 1785 + 1786 + 1787 + 1788 + 1789 + 1790 + 1791 + 1792 + 1793 + 1794 + Hardt Standards Track [Page 32] 1795 + 1796 + RFC 6749 OAuth 2.0 October 2012 1797 + 1798 + 1799 + The flow illustrated in Figure 4 includes the following steps: 1800 + 1801 + (A) The client initiates the flow by directing the resource owner's 1802 + user-agent to the authorization endpoint. The client includes 1803 + its client identifier, requested scope, local state, and a 1804 + redirection URI to which the authorization server will send the 1805 + user-agent back once access is granted (or denied). 1806 + 1807 + (B) The authorization server authenticates the resource owner (via 1808 + the user-agent) and establishes whether the resource owner 1809 + grants or denies the client's access request. 1810 + 1811 + (C) Assuming the resource owner grants access, the authorization 1812 + server redirects the user-agent back to the client using the 1813 + redirection URI provided earlier. The redirection URI includes 1814 + the access token in the URI fragment. 1815 + 1816 + (D) The user-agent follows the redirection instructions by making a 1817 + request to the web-hosted client resource (which does not 1818 + include the fragment per [RFC2616]). The user-agent retains the 1819 + fragment information locally. 1820 + 1821 + (E) The web-hosted client resource returns a web page (typically an 1822 + HTML document with an embedded script) capable of accessing the 1823 + full redirection URI including the fragment retained by the 1824 + user-agent, and extracting the access token (and other 1825 + parameters) contained in the fragment. 1826 + 1827 + (F) The user-agent executes the script provided by the web-hosted 1828 + client resource locally, which extracts the access token. 1829 + 1830 + (G) The user-agent passes the access token to the client. 1831 + 1832 + See Sections 1.3.2 and 9 for background on using the implicit grant. 1833 + See Sections 10.3 and 10.16 for important security considerations 1834 + when using the implicit grant. 1835 + 1836 + 4.2.1. Authorization Request 1837 + 1838 + The client constructs the request URI by adding the following 1839 + parameters to the query component of the authorization endpoint URI 1840 + using the "application/x-www-form-urlencoded" format, per Appendix B: 1841 + 1842 + response_type 1843 + REQUIRED. Value MUST be set to "token". 1844 + 1845 + client_id 1846 + REQUIRED. The client identifier as described in Section 2.2. 1847 + 1848 + 1849 + 1850 + Hardt Standards Track [Page 33] 1851 + 1852 + RFC 6749 OAuth 2.0 October 2012 1853 + 1854 + 1855 + redirect_uri 1856 + OPTIONAL. As described in Section 3.1.2. 1857 + 1858 + scope 1859 + OPTIONAL. The scope of the access request as described by 1860 + Section 3.3. 1861 + 1862 + state 1863 + RECOMMENDED. An opaque value used by the client to maintain 1864 + state between the request and callback. The authorization 1865 + server includes this value when redirecting the user-agent back 1866 + to the client. The parameter SHOULD be used for preventing 1867 + cross-site request forgery as described in Section 10.12. 1868 + 1869 + The client directs the resource owner to the constructed URI using an 1870 + HTTP redirection response, or by other means available to it via the 1871 + user-agent. 1872 + 1873 + For example, the client directs the user-agent to make the following 1874 + HTTP request using TLS (with extra line breaks for display purposes 1875 + only): 1876 + 1877 + GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz 1878 + &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1 1879 + Host: server.example.com 1880 + 1881 + The authorization server validates the request to ensure that all 1882 + required parameters are present and valid. The authorization server 1883 + MUST verify that the redirection URI to which it will redirect the 1884 + access token matches a redirection URI registered by the client as 1885 + described in Section 3.1.2. 1886 + 1887 + If the request is valid, the authorization server authenticates the 1888 + resource owner and obtains an authorization decision (by asking the 1889 + resource owner or by establishing approval via other means). 1890 + 1891 + When a decision is established, the authorization server directs the 1892 + user-agent to the provided client redirection URI using an HTTP 1893 + redirection response, or by other means available to it via the 1894 + user-agent. 1895 + 1896 + 1897 + 1898 + 1899 + 1900 + 1901 + 1902 + 1903 + 1904 + 1905 + 1906 + Hardt Standards Track [Page 34] 1907 + 1908 + RFC 6749 OAuth 2.0 October 2012 1909 + 1910 + 1911 + 4.2.2. Access Token Response 1912 + 1913 + If the resource owner grants the access request, the authorization 1914 + server issues an access token and delivers it to the client by adding 1915 + the following parameters to the fragment component of the redirection 1916 + URI using the "application/x-www-form-urlencoded" format, per 1917 + Appendix B: 1918 + 1919 + access_token 1920 + REQUIRED. The access token issued by the authorization server. 1921 + 1922 + token_type 1923 + REQUIRED. The type of the token issued as described in 1924 + Section 7.1. Value is case insensitive. 1925 + 1926 + expires_in 1927 + RECOMMENDED. The lifetime in seconds of the access token. For 1928 + example, the value "3600" denotes that the access token will 1929 + expire in one hour from the time the response was generated. 1930 + If omitted, the authorization server SHOULD provide the 1931 + expiration time via other means or document the default value. 1932 + 1933 + scope 1934 + OPTIONAL, if identical to the scope requested by the client; 1935 + otherwise, REQUIRED. The scope of the access token as 1936 + described by Section 3.3. 1937 + 1938 + state 1939 + REQUIRED if the "state" parameter was present in the client 1940 + authorization request. The exact value received from the 1941 + client. 1942 + 1943 + The authorization server MUST NOT issue a refresh token. 1944 + 1945 + For example, the authorization server redirects the user-agent by 1946 + sending the following HTTP response (with extra line breaks for 1947 + display purposes only): 1948 + 1949 + HTTP/1.1 302 Found 1950 + Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA 1951 + &state=xyz&token_type=example&expires_in=3600 1952 + 1953 + Developers should note that some user-agents do not support the 1954 + inclusion of a fragment component in the HTTP "Location" response 1955 + header field. Such clients will require using other methods for 1956 + redirecting the client than a 3xx redirection response -- for 1957 + example, returning an HTML page that includes a 'continue' button 1958 + with an action linked to the redirection URI. 1959 + 1960 + 1961 + 1962 + Hardt Standards Track [Page 35] 1963 + 1964 + RFC 6749 OAuth 2.0 October 2012 1965 + 1966 + 1967 + The client MUST ignore unrecognized response parameters. The access 1968 + token string size is left undefined by this specification. The 1969 + client should avoid making assumptions about value sizes. The 1970 + authorization server SHOULD document the size of any value it issues. 1971 + 1972 + 4.2.2.1. Error Response 1973 + 1974 + If the request fails due to a missing, invalid, or mismatching 1975 + redirection URI, or if the client identifier is missing or invalid, 1976 + the authorization server SHOULD inform the resource owner of the 1977 + error and MUST NOT automatically redirect the user-agent to the 1978 + invalid redirection URI. 1979 + 1980 + If the resource owner denies the access request or if the request 1981 + fails for reasons other than a missing or invalid redirection URI, 1982 + the authorization server informs the client by adding the following 1983 + parameters to the fragment component of the redirection URI using the 1984 + "application/x-www-form-urlencoded" format, per Appendix B: 1985 + 1986 + error 1987 + REQUIRED. A single ASCII [USASCII] error code from the 1988 + following: 1989 + 1990 + invalid_request 1991 + The request is missing a required parameter, includes an 1992 + invalid parameter value, includes a parameter more than 1993 + once, or is otherwise malformed. 1994 + 1995 + unauthorized_client 1996 + The client is not authorized to request an access token 1997 + using this method. 1998 + 1999 + access_denied 2000 + The resource owner or authorization server denied the 2001 + request. 2002 + 2003 + unsupported_response_type 2004 + The authorization server does not support obtaining an 2005 + access token using this method. 2006 + 2007 + invalid_scope 2008 + The requested scope is invalid, unknown, or malformed. 2009 + 2010 + 2011 + 2012 + 2013 + 2014 + 2015 + 2016 + 2017 + 2018 + Hardt Standards Track [Page 36] 2019 + 2020 + RFC 6749 OAuth 2.0 October 2012 2021 + 2022 + 2023 + server_error 2024 + The authorization server encountered an unexpected 2025 + condition that prevented it from fulfilling the request. 2026 + (This error code is needed because a 500 Internal Server 2027 + Error HTTP status code cannot be returned to the client 2028 + via an HTTP redirect.) 2029 + 2030 + temporarily_unavailable 2031 + The authorization server is currently unable to handle 2032 + the request due to a temporary overloading or maintenance 2033 + of the server. (This error code is needed because a 503 2034 + Service Unavailable HTTP status code cannot be returned 2035 + to the client via an HTTP redirect.) 2036 + 2037 + Values for the "error" parameter MUST NOT include characters 2038 + outside the set %x20-21 / %x23-5B / %x5D-7E. 2039 + 2040 + error_description 2041 + OPTIONAL. Human-readable ASCII [USASCII] text providing 2042 + additional information, used to assist the client developer in 2043 + understanding the error that occurred. 2044 + Values for the "error_description" parameter MUST NOT include 2045 + characters outside the set %x20-21 / %x23-5B / %x5D-7E. 2046 + 2047 + error_uri 2048 + OPTIONAL. A URI identifying a human-readable web page with 2049 + information about the error, used to provide the client 2050 + developer with additional information about the error. 2051 + Values for the "error_uri" parameter MUST conform to the 2052 + URI-reference syntax and thus MUST NOT include characters 2053 + outside the set %x21 / %x23-5B / %x5D-7E. 2054 + 2055 + state 2056 + REQUIRED if a "state" parameter was present in the client 2057 + authorization request. The exact value received from the 2058 + client. 2059 + 2060 + For example, the authorization server redirects the user-agent by 2061 + sending the following HTTP response: 2062 + 2063 + HTTP/1.1 302 Found 2064 + Location: https://client.example.com/cb#error=access_denied&state=xyz 2065 + 2066 + 4.3. Resource Owner Password Credentials Grant 2067 + 2068 + The resource owner password credentials grant type is suitable in 2069 + cases where the resource owner has a trust relationship with the 2070 + client, such as the device operating system or a highly privileged 2071 + 2072 + 2073 + 2074 + Hardt Standards Track [Page 37] 2075 + 2076 + RFC 6749 OAuth 2.0 October 2012 2077 + 2078 + 2079 + application. The authorization server should take special care when 2080 + enabling this grant type and only allow it when other flows are not 2081 + viable. 2082 + 2083 + This grant type is suitable for clients capable of obtaining the 2084 + resource owner's credentials (username and password, typically using 2085 + an interactive form). It is also used to migrate existing clients 2086 + using direct authentication schemes such as HTTP Basic or Digest 2087 + authentication to OAuth by converting the stored credentials to an 2088 + access token. 2089 + 2090 + +----------+ 2091 + | Resource | 2092 + | Owner | 2093 + | | 2094 + +----------+ 2095 + v 2096 + | Resource Owner 2097 + (A) Password Credentials 2098 + | 2099 + v 2100 + +---------+ +---------------+ 2101 + | |>--(B)---- Resource Owner ------->| | 2102 + | | Password Credentials | Authorization | 2103 + | Client | | Server | 2104 + | |<--(C)---- Access Token ---------<| | 2105 + | | (w/ Optional Refresh Token) | | 2106 + +---------+ +---------------+ 2107 + 2108 + Figure 5: Resource Owner Password Credentials Flow 2109 + 2110 + The flow illustrated in Figure 5 includes the following steps: 2111 + 2112 + (A) The resource owner provides the client with its username and 2113 + password. 2114 + 2115 + (B) The client requests an access token from the authorization 2116 + server's token endpoint by including the credentials received 2117 + from the resource owner. When making the request, the client 2118 + authenticates with the authorization server. 2119 + 2120 + (C) The authorization server authenticates the client and validates 2121 + the resource owner credentials, and if valid, issues an access 2122 + token. 2123 + 2124 + 2125 + 2126 + 2127 + 2128 + 2129 + 2130 + Hardt Standards Track [Page 38] 2131 + 2132 + RFC 6749 OAuth 2.0 October 2012 2133 + 2134 + 2135 + 4.3.1. Authorization Request and Response 2136 + 2137 + The method through which the client obtains the resource owner 2138 + credentials is beyond the scope of this specification. The client 2139 + MUST discard the credentials once an access token has been obtained. 2140 + 2141 + 4.3.2. Access Token Request 2142 + 2143 + The client makes a request to the token endpoint by adding the 2144 + following parameters using the "application/x-www-form-urlencoded" 2145 + format per Appendix B with a character encoding of UTF-8 in the HTTP 2146 + request entity-body: 2147 + 2148 + grant_type 2149 + REQUIRED. Value MUST be set to "password". 2150 + 2151 + username 2152 + REQUIRED. The resource owner username. 2153 + 2154 + password 2155 + REQUIRED. The resource owner password. 2156 + 2157 + scope 2158 + OPTIONAL. The scope of the access request as described by 2159 + Section 3.3. 2160 + 2161 + If the client type is confidential or the client was issued client 2162 + credentials (or assigned other authentication requirements), the 2163 + client MUST authenticate with the authorization server as described 2164 + in Section 3.2.1. 2165 + 2166 + For example, the client makes the following HTTP request using 2167 + transport-layer security (with extra line breaks for display purposes 2168 + only): 2169 + 2170 + POST /token HTTP/1.1 2171 + Host: server.example.com 2172 + Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW 2173 + Content-Type: application/x-www-form-urlencoded 2174 + 2175 + grant_type=password&username=johndoe&password=A3ddj3w 2176 + 2177 + 2178 + 2179 + 2180 + 2181 + 2182 + 2183 + 2184 + 2185 + 2186 + Hardt Standards Track [Page 39] 2187 + 2188 + RFC 6749 OAuth 2.0 October 2012 2189 + 2190 + 2191 + The authorization server MUST: 2192 + 2193 + o require client authentication for confidential clients or for any 2194 + client that was issued client credentials (or with other 2195 + authentication requirements), 2196 + 2197 + o authenticate the client if client authentication is included, and 2198 + 2199 + o validate the resource owner password credentials using its 2200 + existing password validation algorithm. 2201 + 2202 + Since this access token request utilizes the resource owner's 2203 + password, the authorization server MUST protect the endpoint against 2204 + brute force attacks (e.g., using rate-limitation or generating 2205 + alerts). 2206 + 2207 + 4.3.3. Access Token Response 2208 + 2209 + If the access token request is valid and authorized, the 2210 + authorization server issues an access token and optional refresh 2211 + token as described in Section 5.1. If the request failed client 2212 + authentication or is invalid, the authorization server returns an 2213 + error response as described in Section 5.2. 2214 + 2215 + An example successful response: 2216 + 2217 + HTTP/1.1 200 OK 2218 + Content-Type: application/json;charset=UTF-8 2219 + Cache-Control: no-store 2220 + Pragma: no-cache 2221 + 2222 + { 2223 + "access_token":"2YotnFZFEjr1zCsicMWpAA", 2224 + "token_type":"example", 2225 + "expires_in":3600, 2226 + "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", 2227 + "example_parameter":"example_value" 2228 + } 2229 + 2230 + 4.4. Client Credentials Grant 2231 + 2232 + The client can request an access token using only its client 2233 + credentials (or other supported means of authentication) when the 2234 + client is requesting access to the protected resources under its 2235 + control, or those of another resource owner that have been previously 2236 + arranged with the authorization server (the method of which is beyond 2237 + the scope of this specification). 2238 + 2239 + 2240 + 2241 + 2242 + Hardt Standards Track [Page 40] 2243 + 2244 + RFC 6749 OAuth 2.0 October 2012 2245 + 2246 + 2247 + The client credentials grant type MUST only be used by confidential 2248 + clients. 2249 + 2250 + +---------+ +---------------+ 2251 + | | | | 2252 + | |>--(A)- Client Authentication --->| Authorization | 2253 + | Client | | Server | 2254 + | |<--(B)---- Access Token ---------<| | 2255 + | | | | 2256 + +---------+ +---------------+ 2257 + 2258 + Figure 6: Client Credentials Flow 2259 + 2260 + The flow illustrated in Figure 6 includes the following steps: 2261 + 2262 + (A) The client authenticates with the authorization server and 2263 + requests an access token from the token endpoint. 2264 + 2265 + (B) The authorization server authenticates the client, and if valid, 2266 + issues an access token. 2267 + 2268 + 4.4.1. Authorization Request and Response 2269 + 2270 + Since the client authentication is used as the authorization grant, 2271 + no additional authorization request is needed. 2272 + 2273 + 4.4.2. Access Token Request 2274 + 2275 + The client makes a request to the token endpoint by adding the 2276 + following parameters using the "application/x-www-form-urlencoded" 2277 + format per Appendix B with a character encoding of UTF-8 in the HTTP 2278 + request entity-body: 2279 + 2280 + grant_type 2281 + REQUIRED. Value MUST be set to "client_credentials". 2282 + 2283 + scope 2284 + OPTIONAL. The scope of the access request as described by 2285 + Section 3.3. 2286 + 2287 + The client MUST authenticate with the authorization server as 2288 + described in Section 3.2.1. 2289 + 2290 + 2291 + 2292 + 2293 + 2294 + 2295 + 2296 + 2297 + 2298 + Hardt Standards Track [Page 41] 2299 + 2300 + RFC 6749 OAuth 2.0 October 2012 2301 + 2302 + 2303 + For example, the client makes the following HTTP request using 2304 + transport-layer security (with extra line breaks for display purposes 2305 + only): 2306 + 2307 + POST /token HTTP/1.1 2308 + Host: server.example.com 2309 + Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW 2310 + Content-Type: application/x-www-form-urlencoded 2311 + 2312 + grant_type=client_credentials 2313 + 2314 + The authorization server MUST authenticate the client. 2315 + 2316 + 4.4.3. Access Token Response 2317 + 2318 + If the access token request is valid and authorized, the 2319 + authorization server issues an access token as described in 2320 + Section 5.1. A refresh token SHOULD NOT be included. If the request 2321 + failed client authentication or is invalid, the authorization server 2322 + returns an error response as described in Section 5.2. 2323 + 2324 + An example successful response: 2325 + 2326 + HTTP/1.1 200 OK 2327 + Content-Type: application/json;charset=UTF-8 2328 + Cache-Control: no-store 2329 + Pragma: no-cache 2330 + 2331 + { 2332 + "access_token":"2YotnFZFEjr1zCsicMWpAA", 2333 + "token_type":"example", 2334 + "expires_in":3600, 2335 + "example_parameter":"example_value" 2336 + } 2337 + 2338 + 4.5. Extension Grants 2339 + 2340 + The client uses an extension grant type by specifying the grant type 2341 + using an absolute URI (defined by the authorization server) as the 2342 + value of the "grant_type" parameter of the token endpoint, and by 2343 + adding any additional parameters necessary. 2344 + 2345 + 2346 + 2347 + 2348 + 2349 + 2350 + 2351 + 2352 + 2353 + 2354 + Hardt Standards Track [Page 42] 2355 + 2356 + RFC 6749 OAuth 2.0 October 2012 2357 + 2358 + 2359 + For example, to request an access token using a Security Assertion 2360 + Markup Language (SAML) 2.0 assertion grant type as defined by 2361 + [OAuth-SAML2], the client could make the following HTTP request using 2362 + TLS (with extra line breaks for display purposes only): 2363 + 2364 + POST /token HTTP/1.1 2365 + Host: server.example.com 2366 + Content-Type: application/x-www-form-urlencoded 2367 + 2368 + grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Asaml2- 2369 + bearer&assertion=PEFzc2VydGlvbiBJc3N1ZUluc3RhbnQ9IjIwMTEtMDU 2370 + [...omitted for brevity...]aG5TdGF0ZW1lbnQ-PC9Bc3NlcnRpb24- 2371 + 2372 + If the access token request is valid and authorized, the 2373 + authorization server issues an access token and optional refresh 2374 + token as described in Section 5.1. If the request failed client 2375 + authentication or is invalid, the authorization server returns an 2376 + error response as described in Section 5.2. 2377 + 2378 + 5. Issuing an Access Token 2379 + 2380 + If the access token request is valid and authorized, the 2381 + authorization server issues an access token and optional refresh 2382 + token as described in Section 5.1. If the request failed client 2383 + authentication or is invalid, the authorization server returns an 2384 + error response as described in Section 5.2. 2385 + 2386 + 5.1. Successful Response 2387 + 2388 + The authorization server issues an access token and optional refresh 2389 + token, and constructs the response by adding the following parameters 2390 + to the entity-body of the HTTP response with a 200 (OK) status code: 2391 + 2392 + access_token 2393 + REQUIRED. The access token issued by the authorization server. 2394 + 2395 + token_type 2396 + REQUIRED. The type of the token issued as described in 2397 + Section 7.1. Value is case insensitive. 2398 + 2399 + expires_in 2400 + RECOMMENDED. The lifetime in seconds of the access token. For 2401 + example, the value "3600" denotes that the access token will 2402 + expire in one hour from the time the response was generated. 2403 + If omitted, the authorization server SHOULD provide the 2404 + expiration time via other means or document the default value. 2405 + 2406 + 2407 + 2408 + 2409 + 2410 + Hardt Standards Track [Page 43] 2411 + 2412 + RFC 6749 OAuth 2.0 October 2012 2413 + 2414 + 2415 + refresh_token 2416 + OPTIONAL. The refresh token, which can be used to obtain new 2417 + access tokens using the same authorization grant as described 2418 + in Section 6. 2419 + 2420 + scope 2421 + OPTIONAL, if identical to the scope requested by the client; 2422 + otherwise, REQUIRED. The scope of the access token as 2423 + described by Section 3.3. 2424 + 2425 + The parameters are included in the entity-body of the HTTP response 2426 + using the "application/json" media type as defined by [RFC4627]. The 2427 + parameters are serialized into a JavaScript Object Notation (JSON) 2428 + structure by adding each parameter at the highest structure level. 2429 + Parameter names and string values are included as JSON strings. 2430 + Numerical values are included as JSON numbers. The order of 2431 + parameters does not matter and can vary. 2432 + 2433 + The authorization server MUST include the HTTP "Cache-Control" 2434 + response header field [RFC2616] with a value of "no-store" in any 2435 + response containing tokens, credentials, or other sensitive 2436 + information, as well as the "Pragma" response header field [RFC2616] 2437 + with a value of "no-cache". 2438 + 2439 + For example: 2440 + 2441 + HTTP/1.1 200 OK 2442 + Content-Type: application/json;charset=UTF-8 2443 + Cache-Control: no-store 2444 + Pragma: no-cache 2445 + 2446 + { 2447 + "access_token":"2YotnFZFEjr1zCsicMWpAA", 2448 + "token_type":"example", 2449 + "expires_in":3600, 2450 + "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", 2451 + "example_parameter":"example_value" 2452 + } 2453 + 2454 + The client MUST ignore unrecognized value names in the response. The 2455 + sizes of tokens and other values received from the authorization 2456 + server are left undefined. The client should avoid making 2457 + assumptions about value sizes. The authorization server SHOULD 2458 + document the size of any value it issues. 2459 + 2460 + 2461 + 2462 + 2463 + 2464 + 2465 + 2466 + Hardt Standards Track [Page 44] 2467 + 2468 + RFC 6749 OAuth 2.0 October 2012 2469 + 2470 + 2471 + 5.2. Error Response 2472 + 2473 + The authorization server responds with an HTTP 400 (Bad Request) 2474 + status code (unless specified otherwise) and includes the following 2475 + parameters with the response: 2476 + 2477 + error 2478 + REQUIRED. A single ASCII [USASCII] error code from the 2479 + following: 2480 + 2481 + invalid_request 2482 + The request is missing a required parameter, includes an 2483 + unsupported parameter value (other than grant type), 2484 + repeats a parameter, includes multiple credentials, 2485 + utilizes more than one mechanism for authenticating the 2486 + client, or is otherwise malformed. 2487 + 2488 + invalid_client 2489 + Client authentication failed (e.g., unknown client, no 2490 + client authentication included, or unsupported 2491 + authentication method). The authorization server MAY 2492 + return an HTTP 401 (Unauthorized) status code to indicate 2493 + which HTTP authentication schemes are supported. If the 2494 + client attempted to authenticate via the "Authorization" 2495 + request header field, the authorization server MUST 2496 + respond with an HTTP 401 (Unauthorized) status code and 2497 + include the "WWW-Authenticate" response header field 2498 + matching the authentication scheme used by the client. 2499 + 2500 + invalid_grant 2501 + The provided authorization grant (e.g., authorization 2502 + code, resource owner credentials) or refresh token is 2503 + invalid, expired, revoked, does not match the redirection 2504 + URI used in the authorization request, or was issued to 2505 + another client. 2506 + 2507 + unauthorized_client 2508 + The authenticated client is not authorized to use this 2509 + authorization grant type. 2510 + 2511 + unsupported_grant_type 2512 + The authorization grant type is not supported by the 2513 + authorization server. 2514 + 2515 + 2516 + 2517 + 2518 + 2519 + 2520 + 2521 + 2522 + Hardt Standards Track [Page 45] 2523 + 2524 + RFC 6749 OAuth 2.0 October 2012 2525 + 2526 + 2527 + invalid_scope 2528 + The requested scope is invalid, unknown, malformed, or 2529 + exceeds the scope granted by the resource owner. 2530 + 2531 + Values for the "error" parameter MUST NOT include characters 2532 + outside the set %x20-21 / %x23-5B / %x5D-7E. 2533 + 2534 + error_description 2535 + OPTIONAL. Human-readable ASCII [USASCII] text providing 2536 + additional information, used to assist the client developer in 2537 + understanding the error that occurred. 2538 + Values for the "error_description" parameter MUST NOT include 2539 + characters outside the set %x20-21 / %x23-5B / %x5D-7E. 2540 + 2541 + error_uri 2542 + OPTIONAL. A URI identifying a human-readable web page with 2543 + information about the error, used to provide the client 2544 + developer with additional information about the error. 2545 + Values for the "error_uri" parameter MUST conform to the 2546 + URI-reference syntax and thus MUST NOT include characters 2547 + outside the set %x21 / %x23-5B / %x5D-7E. 2548 + 2549 + The parameters are included in the entity-body of the HTTP response 2550 + using the "application/json" media type as defined by [RFC4627]. The 2551 + parameters are serialized into a JSON structure by adding each 2552 + parameter at the highest structure level. Parameter names and string 2553 + values are included as JSON strings. Numerical values are included 2554 + as JSON numbers. The order of parameters does not matter and can 2555 + vary. 2556 + 2557 + For example: 2558 + 2559 + HTTP/1.1 400 Bad Request 2560 + Content-Type: application/json;charset=UTF-8 2561 + Cache-Control: no-store 2562 + Pragma: no-cache 2563 + 2564 + { 2565 + "error":"invalid_request" 2566 + } 2567 + 2568 + 2569 + 2570 + 2571 + 2572 + 2573 + 2574 + 2575 + 2576 + 2577 + 2578 + Hardt Standards Track [Page 46] 2579 + 2580 + RFC 6749 OAuth 2.0 October 2012 2581 + 2582 + 2583 + 6. Refreshing an Access Token 2584 + 2585 + If the authorization server issued a refresh token to the client, the 2586 + client makes a refresh request to the token endpoint by adding the 2587 + following parameters using the "application/x-www-form-urlencoded" 2588 + format per Appendix B with a character encoding of UTF-8 in the HTTP 2589 + request entity-body: 2590 + 2591 + grant_type 2592 + REQUIRED. Value MUST be set to "refresh_token". 2593 + 2594 + refresh_token 2595 + REQUIRED. The refresh token issued to the client. 2596 + 2597 + scope 2598 + OPTIONAL. The scope of the access request as described by 2599 + Section 3.3. The requested scope MUST NOT include any scope 2600 + not originally granted by the resource owner, and if omitted is 2601 + treated as equal to the scope originally granted by the 2602 + resource owner. 2603 + 2604 + Because refresh tokens are typically long-lasting credentials used to 2605 + request additional access tokens, the refresh token is bound to the 2606 + client to which it was issued. If the client type is confidential or 2607 + the client was issued client credentials (or assigned other 2608 + authentication requirements), the client MUST authenticate with the 2609 + authorization server as described in Section 3.2.1. 2610 + 2611 + For example, the client makes the following HTTP request using 2612 + transport-layer security (with extra line breaks for display purposes 2613 + only): 2614 + 2615 + POST /token HTTP/1.1 2616 + Host: server.example.com 2617 + Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW 2618 + Content-Type: application/x-www-form-urlencoded 2619 + 2620 + grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA 2621 + 2622 + 2623 + 2624 + 2625 + 2626 + 2627 + 2628 + 2629 + 2630 + 2631 + 2632 + 2633 + 2634 + Hardt Standards Track [Page 47] 2635 + 2636 + RFC 6749 OAuth 2.0 October 2012 2637 + 2638 + 2639 + The authorization server MUST: 2640 + 2641 + o require client authentication for confidential clients or for any 2642 + client that was issued client credentials (or with other 2643 + authentication requirements), 2644 + 2645 + o authenticate the client if client authentication is included and 2646 + ensure that the refresh token was issued to the authenticated 2647 + client, and 2648 + 2649 + o validate the refresh token. 2650 + 2651 + If valid and authorized, the authorization server issues an access 2652 + token as described in Section 5.1. If the request failed 2653 + verification or is invalid, the authorization server returns an error 2654 + response as described in Section 5.2. 2655 + 2656 + The authorization server MAY issue a new refresh token, in which case 2657 + the client MUST discard the old refresh token and replace it with the 2658 + new refresh token. The authorization server MAY revoke the old 2659 + refresh token after issuing a new refresh token to the client. If a 2660 + new refresh token is issued, the refresh token scope MUST be 2661 + identical to that of the refresh token included by the client in the 2662 + request. 2663 + 2664 + 7. Accessing Protected Resources 2665 + 2666 + The client accesses protected resources by presenting the access 2667 + token to the resource server. The resource server MUST validate the 2668 + access token and ensure that it has not expired and that its scope 2669 + covers the requested resource. The methods used by the resource 2670 + server to validate the access token (as well as any error responses) 2671 + are beyond the scope of this specification but generally involve an 2672 + interaction or coordination between the resource server and the 2673 + authorization server. 2674 + 2675 + The method in which the client utilizes the access token to 2676 + authenticate with the resource server depends on the type of access 2677 + token issued by the authorization server. Typically, it involves 2678 + using the HTTP "Authorization" request header field [RFC2617] with an 2679 + authentication scheme defined by the specification of the access 2680 + token type used, such as [RFC6750]. 2681 + 2682 + 2683 + 2684 + 2685 + 2686 + 2687 + 2688 + 2689 + 2690 + Hardt Standards Track [Page 48] 2691 + 2692 + RFC 6749 OAuth 2.0 October 2012 2693 + 2694 + 2695 + 7.1. Access Token Types 2696 + 2697 + The access token type provides the client with the information 2698 + required to successfully utilize the access token to make a protected 2699 + resource request (along with type-specific attributes). The client 2700 + MUST NOT use an access token if it does not understand the token 2701 + type. 2702 + 2703 + For example, the "bearer" token type defined in [RFC6750] is utilized 2704 + by simply including the access token string in the request: 2705 + 2706 + GET /resource/1 HTTP/1.1 2707 + Host: example.com 2708 + Authorization: Bearer mF_9.B5f-4.1JqM 2709 + 2710 + while the "mac" token type defined in [OAuth-HTTP-MAC] is utilized by 2711 + issuing a Message Authentication Code (MAC) key together with the 2712 + access token that is used to sign certain components of the HTTP 2713 + requests: 2714 + 2715 + GET /resource/1 HTTP/1.1 2716 + Host: example.com 2717 + Authorization: MAC id="h480djs93hd8", 2718 + nonce="274312:dj83hs9s", 2719 + mac="kDZvddkndxvhGRXZhvuDjEWhGeE=" 2720 + 2721 + The above examples are provided for illustration purposes only. 2722 + Developers are advised to consult the [RFC6750] and [OAuth-HTTP-MAC] 2723 + specifications before use. 2724 + 2725 + Each access token type definition specifies the additional attributes 2726 + (if any) sent to the client together with the "access_token" response 2727 + parameter. It also defines the HTTP authentication method used to 2728 + include the access token when making a protected resource request. 2729 + 2730 + 7.2. Error Response 2731 + 2732 + If a resource access request fails, the resource server SHOULD inform 2733 + the client of the error. While the specifics of such error responses 2734 + are beyond the scope of this specification, this document establishes 2735 + a common registry in Section 11.4 for error values to be shared among 2736 + OAuth token authentication schemes. 2737 + 2738 + New authentication schemes designed primarily for OAuth token 2739 + authentication SHOULD define a mechanism for providing an error 2740 + status code to the client, in which the error values allowed are 2741 + registered in the error registry established by this specification. 2742 + 2743 + 2744 + 2745 + 2746 + Hardt Standards Track [Page 49] 2747 + 2748 + RFC 6749 OAuth 2.0 October 2012 2749 + 2750 + 2751 + Such schemes MAY limit the set of valid error codes to a subset of 2752 + the registered values. If the error code is returned using a named 2753 + parameter, the parameter name SHOULD be "error". 2754 + 2755 + Other schemes capable of being used for OAuth token authentication, 2756 + but not primarily designed for that purpose, MAY bind their error 2757 + values to the registry in the same manner. 2758 + 2759 + New authentication schemes MAY choose to also specify the use of the 2760 + "error_description" and "error_uri" parameters to return error 2761 + information in a manner parallel to their usage in this 2762 + specification. 2763 + 2764 + 8. Extensibility 2765 + 2766 + 8.1. Defining Access Token Types 2767 + 2768 + Access token types can be defined in one of two ways: registered in 2769 + the Access Token Types registry (following the procedures in 2770 + Section 11.1), or by using a unique absolute URI as its name. 2771 + 2772 + Types utilizing a URI name SHOULD be limited to vendor-specific 2773 + implementations that are not commonly applicable, and are specific to 2774 + the implementation details of the resource server where they are 2775 + used. 2776 + 2777 + All other types MUST be registered. Type names MUST conform to the 2778 + type-name ABNF. If the type definition includes a new HTTP 2779 + authentication scheme, the type name SHOULD be identical to the HTTP 2780 + authentication scheme name (as defined by [RFC2617]). The token type 2781 + "example" is reserved for use in examples. 2782 + 2783 + type-name = 1*name-char 2784 + name-char = "-" / "." / "_" / DIGIT / ALPHA 2785 + 2786 + 8.2. Defining New Endpoint Parameters 2787 + 2788 + New request or response parameters for use with the authorization 2789 + endpoint or the token endpoint are defined and registered in the 2790 + OAuth Parameters registry following the procedure in Section 11.2. 2791 + 2792 + Parameter names MUST conform to the param-name ABNF, and parameter 2793 + values syntax MUST be well-defined (e.g., using ABNF, or a reference 2794 + to the syntax of an existing parameter). 2795 + 2796 + param-name = 1*name-char 2797 + name-char = "-" / "." / "_" / DIGIT / ALPHA 2798 + 2799 + 2800 + 2801 + 2802 + Hardt Standards Track [Page 50] 2803 + 2804 + RFC 6749 OAuth 2.0 October 2012 2805 + 2806 + 2807 + Unregistered vendor-specific parameter extensions that are not 2808 + commonly applicable and that are specific to the implementation 2809 + details of the authorization server where they are used SHOULD 2810 + utilize a vendor-specific prefix that is not likely to conflict with 2811 + other registered values (e.g., begin with 'companyname_'). 2812 + 2813 + 8.3. Defining New Authorization Grant Types 2814 + 2815 + New authorization grant types can be defined by assigning them a 2816 + unique absolute URI for use with the "grant_type" parameter. If the 2817 + extension grant type requires additional token endpoint parameters, 2818 + they MUST be registered in the OAuth Parameters registry as described 2819 + by Section 11.2. 2820 + 2821 + 8.4. Defining New Authorization Endpoint Response Types 2822 + 2823 + New response types for use with the authorization endpoint are 2824 + defined and registered in the Authorization Endpoint Response Types 2825 + registry following the procedure in Section 11.3. Response type 2826 + names MUST conform to the response-type ABNF. 2827 + 2828 + response-type = response-name *( SP response-name ) 2829 + response-name = 1*response-char 2830 + response-char = "_" / DIGIT / ALPHA 2831 + 2832 + If a response type contains one or more space characters (%x20), it 2833 + is compared as a space-delimited list of values in which the order of 2834 + values does not matter. Only one order of values can be registered, 2835 + which covers all other arrangements of the same set of values. 2836 + 2837 + For example, the response type "token code" is left undefined by this 2838 + specification. However, an extension can define and register the 2839 + "token code" response type. Once registered, the same combination 2840 + cannot be registered as "code token", but both values can be used to 2841 + denote the same response type. 2842 + 2843 + 8.5. Defining Additional Error Codes 2844 + 2845 + In cases where protocol extensions (i.e., access token types, 2846 + extension parameters, or extension grant types) require additional 2847 + error codes to be used with the authorization code grant error 2848 + response (Section 4.1.2.1), the implicit grant error response 2849 + (Section 4.2.2.1), the token error response (Section 5.2), or the 2850 + resource access error response (Section 7.2), such error codes MAY be 2851 + defined. 2852 + 2853 + 2854 + 2855 + 2856 + 2857 + 2858 + Hardt Standards Track [Page 51] 2859 + 2860 + RFC 6749 OAuth 2.0 October 2012 2861 + 2862 + 2863 + Extension error codes MUST be registered (following the procedures in 2864 + Section 11.4) if the extension they are used in conjunction with is a 2865 + registered access token type, a registered endpoint parameter, or an 2866 + extension grant type. Error codes used with unregistered extensions 2867 + MAY be registered. 2868 + 2869 + Error codes MUST conform to the error ABNF and SHOULD be prefixed by 2870 + an identifying name when possible. For example, an error identifying 2871 + an invalid value set to the extension parameter "example" SHOULD be 2872 + named "example_invalid". 2873 + 2874 + error = 1*error-char 2875 + error-char = %x20-21 / %x23-5B / %x5D-7E 2876 + 2877 + 9. Native Applications 2878 + 2879 + Native applications are clients installed and executed on the device 2880 + used by the resource owner (i.e., desktop application, native mobile 2881 + application). Native applications require special consideration 2882 + related to security, platform capabilities, and overall end-user 2883 + experience. 2884 + 2885 + The authorization endpoint requires interaction between the client 2886 + and the resource owner's user-agent. Native applications can invoke 2887 + an external user-agent or embed a user-agent within the application. 2888 + For example: 2889 + 2890 + o External user-agent - the native application can capture the 2891 + response from the authorization server using a redirection URI 2892 + with a scheme registered with the operating system to invoke the 2893 + client as the handler, manual copy-and-paste of the credentials, 2894 + running a local web server, installing a user-agent extension, or 2895 + by providing a redirection URI identifying a server-hosted 2896 + resource under the client's control, which in turn makes the 2897 + response available to the native application. 2898 + 2899 + o Embedded user-agent - the native application obtains the response 2900 + by directly communicating with the embedded user-agent by 2901 + monitoring state changes emitted during the resource load, or 2902 + accessing the user-agent's cookies storage. 2903 + 2904 + When choosing between an external or embedded user-agent, developers 2905 + should consider the following: 2906 + 2907 + o An external user-agent may improve completion rate, as the 2908 + resource owner may already have an active session with the 2909 + authorization server, removing the need to re-authenticate. It 2910 + provides a familiar end-user experience and functionality. The 2911 + 2912 + 2913 + 2914 + Hardt Standards Track [Page 52] 2915 + 2916 + RFC 6749 OAuth 2.0 October 2012 2917 + 2918 + 2919 + resource owner may also rely on user-agent features or extensions 2920 + to assist with authentication (e.g., password manager, 2-factor 2921 + device reader). 2922 + 2923 + o An embedded user-agent may offer improved usability, as it removes 2924 + the need to switch context and open new windows. 2925 + 2926 + o An embedded user-agent poses a security challenge because resource 2927 + owners are authenticating in an unidentified window without access 2928 + to the visual protections found in most external user-agents. An 2929 + embedded user-agent educates end-users to trust unidentified 2930 + requests for authentication (making phishing attacks easier to 2931 + execute). 2932 + 2933 + When choosing between the implicit grant type and the authorization 2934 + code grant type, the following should be considered: 2935 + 2936 + o Native applications that use the authorization code grant type 2937 + SHOULD do so without using client credentials, due to the native 2938 + application's inability to keep client credentials confidential. 2939 + 2940 + o When using the implicit grant type flow, a refresh token is not 2941 + returned, which requires repeating the authorization process once 2942 + the access token expires. 2943 + 2944 + 10. Security Considerations 2945 + 2946 + As a flexible and extensible framework, OAuth's security 2947 + considerations depend on many factors. The following sections 2948 + provide implementers with security guidelines focused on the three 2949 + client profiles described in Section 2.1: web application, 2950 + user-agent-based application, and native application. 2951 + 2952 + A comprehensive OAuth security model and analysis, as well as 2953 + background for the protocol design, is provided by 2954 + [OAuth-THREATMODEL]. 2955 + 2956 + 10.1. Client Authentication 2957 + 2958 + The authorization server establishes client credentials with web 2959 + application clients for the purpose of client authentication. The 2960 + authorization server is encouraged to consider stronger client 2961 + authentication means than a client password. Web application clients 2962 + MUST ensure confidentiality of client passwords and other client 2963 + credentials. 2964 + 2965 + 2966 + 2967 + 2968 + 2969 + 2970 + Hardt Standards Track [Page 53] 2971 + 2972 + RFC 6749 OAuth 2.0 October 2012 2973 + 2974 + 2975 + The authorization server MUST NOT issue client passwords or other 2976 + client credentials to native application or user-agent-based 2977 + application clients for the purpose of client authentication. The 2978 + authorization server MAY issue a client password or other credentials 2979 + for a specific installation of a native application client on a 2980 + specific device. 2981 + 2982 + When client authentication is not possible, the authorization server 2983 + SHOULD employ other means to validate the client's identity -- for 2984 + example, by requiring the registration of the client redirection URI 2985 + or enlisting the resource owner to confirm identity. A valid 2986 + redirection URI is not sufficient to verify the client's identity 2987 + when asking for resource owner authorization but can be used to 2988 + prevent delivering credentials to a counterfeit client after 2989 + obtaining resource owner authorization. 2990 + 2991 + The authorization server must consider the security implications of 2992 + interacting with unauthenticated clients and take measures to limit 2993 + the potential exposure of other credentials (e.g., refresh tokens) 2994 + issued to such clients. 2995 + 2996 + 10.2. Client Impersonation 2997 + 2998 + A malicious client can impersonate another client and obtain access 2999 + to protected resources if the impersonated client fails to, or is 3000 + unable to, keep its client credentials confidential. 3001 + 3002 + The authorization server MUST authenticate the client whenever 3003 + possible. If the authorization server cannot authenticate the client 3004 + due to the client's nature, the authorization server MUST require the 3005 + registration of any redirection URI used for receiving authorization 3006 + responses and SHOULD utilize other means to protect resource owners 3007 + from such potentially malicious clients. For example, the 3008 + authorization server can engage the resource owner to assist in 3009 + identifying the client and its origin. 3010 + 3011 + The authorization server SHOULD enforce explicit resource owner 3012 + authentication and provide the resource owner with information about 3013 + the client and the requested authorization scope and lifetime. It is 3014 + up to the resource owner to review the information in the context of 3015 + the current client and to authorize or deny the request. 3016 + 3017 + The authorization server SHOULD NOT process repeated authorization 3018 + requests automatically (without active resource owner interaction) 3019 + without authenticating the client or relying on other measures to 3020 + ensure that the repeated request comes from the original client and 3021 + not an impersonator. 3022 + 3023 + 3024 + 3025 + 3026 + Hardt Standards Track [Page 54] 3027 + 3028 + RFC 6749 OAuth 2.0 October 2012 3029 + 3030 + 3031 + 10.3. Access Tokens 3032 + 3033 + Access token credentials (as well as any confidential access token 3034 + attributes) MUST be kept confidential in transit and storage, and 3035 + only shared among the authorization server, the resource servers the 3036 + access token is valid for, and the client to whom the access token is 3037 + issued. Access token credentials MUST only be transmitted using TLS 3038 + as described in Section 1.6 with server authentication as defined by 3039 + [RFC2818]. 3040 + 3041 + When using the implicit grant type, the access token is transmitted 3042 + in the URI fragment, which can expose it to unauthorized parties. 3043 + 3044 + The authorization server MUST ensure that access tokens cannot be 3045 + generated, modified, or guessed to produce valid access tokens by 3046 + unauthorized parties. 3047 + 3048 + The client SHOULD request access tokens with the minimal scope 3049 + necessary. The authorization server SHOULD take the client identity 3050 + into account when choosing how to honor the requested scope and MAY 3051 + issue an access token with less rights than requested. 3052 + 3053 + This specification does not provide any methods for the resource 3054 + server to ensure that an access token presented to it by a given 3055 + client was issued to that client by the authorization server. 3056 + 3057 + 10.4. Refresh Tokens 3058 + 3059 + Authorization servers MAY issue refresh tokens to web application 3060 + clients and native application clients. 3061 + 3062 + Refresh tokens MUST be kept confidential in transit and storage, and 3063 + shared only among the authorization server and the client to whom the 3064 + refresh tokens were issued. The authorization server MUST maintain 3065 + the binding between a refresh token and the client to whom it was 3066 + issued. Refresh tokens MUST only be transmitted using TLS as 3067 + described in Section 1.6 with server authentication as defined by 3068 + [RFC2818]. 3069 + 3070 + The authorization server MUST verify the binding between the refresh 3071 + token and client identity whenever the client identity can be 3072 + authenticated. When client authentication is not possible, the 3073 + authorization server SHOULD deploy other means to detect refresh 3074 + token abuse. 3075 + 3076 + For example, the authorization server could employ refresh token 3077 + rotation in which a new refresh token is issued with every access 3078 + token refresh response. The previous refresh token is invalidated 3079 + 3080 + 3081 + 3082 + Hardt Standards Track [Page 55] 3083 + 3084 + RFC 6749 OAuth 2.0 October 2012 3085 + 3086 + 3087 + but retained by the authorization server. If a refresh token is 3088 + compromised and subsequently used by both the attacker and the 3089 + legitimate client, one of them will present an invalidated refresh 3090 + token, which will inform the authorization server of the breach. 3091 + 3092 + The authorization server MUST ensure that refresh tokens cannot be 3093 + generated, modified, or guessed to produce valid refresh tokens by 3094 + unauthorized parties. 3095 + 3096 + 10.5. Authorization Codes 3097 + 3098 + The transmission of authorization codes SHOULD be made over a secure 3099 + channel, and the client SHOULD require the use of TLS with its 3100 + redirection URI if the URI identifies a network resource. Since 3101 + authorization codes are transmitted via user-agent redirections, they 3102 + could potentially be disclosed through user-agent history and HTTP 3103 + referrer headers. 3104 + 3105 + Authorization codes operate as plaintext bearer credentials, used to 3106 + verify that the resource owner who granted authorization at the 3107 + authorization server is the same resource owner returning to the 3108 + client to complete the process. Therefore, if the client relies on 3109 + the authorization code for its own resource owner authentication, the 3110 + client redirection endpoint MUST require the use of TLS. 3111 + 3112 + Authorization codes MUST be short lived and single-use. If the 3113 + authorization server observes multiple attempts to exchange an 3114 + authorization code for an access token, the authorization server 3115 + SHOULD attempt to revoke all access tokens already granted based on 3116 + the compromised authorization code. 3117 + 3118 + If the client can be authenticated, the authorization servers MUST 3119 + authenticate the client and ensure that the authorization code was 3120 + issued to the same client. 3121 + 3122 + 10.6. Authorization Code Redirection URI Manipulation 3123 + 3124 + When requesting authorization using the authorization code grant 3125 + type, the client can specify a redirection URI via the "redirect_uri" 3126 + parameter. If an attacker can manipulate the value of the 3127 + redirection URI, it can cause the authorization server to redirect 3128 + the resource owner user-agent to a URI under the control of the 3129 + attacker with the authorization code. 3130 + 3131 + An attacker can create an account at a legitimate client and initiate 3132 + the authorization flow. When the attacker's user-agent is sent to 3133 + the authorization server to grant access, the attacker grabs the 3134 + authorization URI provided by the legitimate client and replaces the 3135 + 3136 + 3137 + 3138 + Hardt Standards Track [Page 56] 3139 + 3140 + RFC 6749 OAuth 2.0 October 2012 3141 + 3142 + 3143 + client's redirection URI with a URI under the control of the 3144 + attacker. The attacker then tricks the victim into following the 3145 + manipulated link to authorize access to the legitimate client. 3146 + 3147 + Once at the authorization server, the victim is prompted with a 3148 + normal, valid request on behalf of a legitimate and trusted client, 3149 + and authorizes the request. The victim is then redirected to an 3150 + endpoint under the control of the attacker with the authorization 3151 + code. The attacker completes the authorization flow by sending the 3152 + authorization code to the client using the original redirection URI 3153 + provided by the client. The client exchanges the authorization code 3154 + with an access token and links it to the attacker's client account, 3155 + which can now gain access to the protected resources authorized by 3156 + the victim (via the client). 3157 + 3158 + In order to prevent such an attack, the authorization server MUST 3159 + ensure that the redirection URI used to obtain the authorization code 3160 + is identical to the redirection URI provided when exchanging the 3161 + authorization code for an access token. The authorization server 3162 + MUST require public clients and SHOULD require confidential clients 3163 + to register their redirection URIs. If a redirection URI is provided 3164 + in the request, the authorization server MUST validate it against the 3165 + registered value. 3166 + 3167 + 10.7. Resource Owner Password Credentials 3168 + 3169 + The resource owner password credentials grant type is often used for 3170 + legacy or migration reasons. It reduces the overall risk of storing 3171 + usernames and passwords by the client but does not eliminate the need 3172 + to expose highly privileged credentials to the client. 3173 + 3174 + This grant type carries a higher risk than other grant types because 3175 + it maintains the password anti-pattern this protocol seeks to avoid. 3176 + The client could abuse the password, or the password could 3177 + unintentionally be disclosed to an attacker (e.g., via log files or 3178 + other records kept by the client). 3179 + 3180 + Additionally, because the resource owner does not have control over 3181 + the authorization process (the resource owner's involvement ends when 3182 + it hands over its credentials to the client), the client can obtain 3183 + access tokens with a broader scope than desired by the resource 3184 + owner. The authorization server should consider the scope and 3185 + lifetime of access tokens issued via this grant type. 3186 + 3187 + The authorization server and client SHOULD minimize use of this grant 3188 + type and utilize other grant types whenever possible. 3189 + 3190 + 3191 + 3192 + 3193 + 3194 + Hardt Standards Track [Page 57] 3195 + 3196 + RFC 6749 OAuth 2.0 October 2012 3197 + 3198 + 3199 + 10.8. Request Confidentiality 3200 + 3201 + Access tokens, refresh tokens, resource owner passwords, and client 3202 + credentials MUST NOT be transmitted in the clear. Authorization 3203 + codes SHOULD NOT be transmitted in the clear. 3204 + 3205 + The "state" and "scope" parameters SHOULD NOT include sensitive 3206 + client or resource owner information in plain text, as they can be 3207 + transmitted over insecure channels or stored insecurely. 3208 + 3209 + 10.9. Ensuring Endpoint Authenticity 3210 + 3211 + In order to prevent man-in-the-middle attacks, the authorization 3212 + server MUST require the use of TLS with server authentication as 3213 + defined by [RFC2818] for any request sent to the authorization and 3214 + token endpoints. The client MUST validate the authorization server's 3215 + TLS certificate as defined by [RFC6125] and in accordance with its 3216 + requirements for server identity authentication. 3217 + 3218 + 10.10. Credentials-Guessing Attacks 3219 + 3220 + The authorization server MUST prevent attackers from guessing access 3221 + tokens, authorization codes, refresh tokens, resource owner 3222 + passwords, and client credentials. 3223 + 3224 + The probability of an attacker guessing generated tokens (and other 3225 + credentials not intended for handling by end-users) MUST be less than 3226 + or equal to 2^(-128) and SHOULD be less than or equal to 2^(-160). 3227 + 3228 + The authorization server MUST utilize other means to protect 3229 + credentials intended for end-user usage. 3230 + 3231 + 10.11. Phishing Attacks 3232 + 3233 + Wide deployment of this and similar protocols may cause end-users to 3234 + become inured to the practice of being redirected to websites where 3235 + they are asked to enter their passwords. If end-users are not 3236 + careful to verify the authenticity of these websites before entering 3237 + their credentials, it will be possible for attackers to exploit this 3238 + practice to steal resource owners' passwords. 3239 + 3240 + Service providers should attempt to educate end-users about the risks 3241 + phishing attacks pose and should provide mechanisms that make it easy 3242 + for end-users to confirm the authenticity of their sites. Client 3243 + developers should consider the security implications of how they 3244 + interact with the user-agent (e.g., external, embedded), and the 3245 + ability of the end-user to verify the authenticity of the 3246 + authorization server. 3247 + 3248 + 3249 + 3250 + Hardt Standards Track [Page 58] 3251 + 3252 + RFC 6749 OAuth 2.0 October 2012 3253 + 3254 + 3255 + To reduce the risk of phishing attacks, the authorization servers 3256 + MUST require the use of TLS on every endpoint used for end-user 3257 + interaction. 3258 + 3259 + 10.12. Cross-Site Request Forgery 3260 + 3261 + Cross-site request forgery (CSRF) is an exploit in which an attacker 3262 + causes the user-agent of a victim end-user to follow a malicious URI 3263 + (e.g., provided to the user-agent as a misleading link, image, or 3264 + redirection) to a trusting server (usually established via the 3265 + presence of a valid session cookie). 3266 + 3267 + A CSRF attack against the client's redirection URI allows an attacker 3268 + to inject its own authorization code or access token, which can 3269 + result in the client using an access token associated with the 3270 + attacker's protected resources rather than the victim's (e.g., save 3271 + the victim's bank account information to a protected resource 3272 + controlled by the attacker). 3273 + 3274 + The client MUST implement CSRF protection for its redirection URI. 3275 + This is typically accomplished by requiring any request sent to the 3276 + redirection URI endpoint to include a value that binds the request to 3277 + the user-agent's authenticated state (e.g., a hash of the session 3278 + cookie used to authenticate the user-agent). The client SHOULD 3279 + utilize the "state" request parameter to deliver this value to the 3280 + authorization server when making an authorization request. 3281 + 3282 + Once authorization has been obtained from the end-user, the 3283 + authorization server redirects the end-user's user-agent back to the 3284 + client with the required binding value contained in the "state" 3285 + parameter. The binding value enables the client to verify the 3286 + validity of the request by matching the binding value to the 3287 + user-agent's authenticated state. The binding value used for CSRF 3288 + protection MUST contain a non-guessable value (as described in 3289 + Section 10.10), and the user-agent's authenticated state (e.g., 3290 + session cookie, HTML5 local storage) MUST be kept in a location 3291 + accessible only to the client and the user-agent (i.e., protected by 3292 + same-origin policy). 3293 + 3294 + A CSRF attack against the authorization server's authorization 3295 + endpoint can result in an attacker obtaining end-user authorization 3296 + for a malicious client without involving or alerting the end-user. 3297 + 3298 + The authorization server MUST implement CSRF protection for its 3299 + authorization endpoint and ensure that a malicious client cannot 3300 + obtain authorization without the awareness and explicit consent of 3301 + the resource owner. 3302 + 3303 + 3304 + 3305 + 3306 + Hardt Standards Track [Page 59] 3307 + 3308 + RFC 6749 OAuth 2.0 October 2012 3309 + 3310 + 3311 + 10.13. Clickjacking 3312 + 3313 + In a clickjacking attack, an attacker registers a legitimate client 3314 + and then constructs a malicious site in which it loads the 3315 + authorization server's authorization endpoint web page in a 3316 + transparent iframe overlaid on top of a set of dummy buttons, which 3317 + are carefully constructed to be placed directly under important 3318 + buttons on the authorization page. When an end-user clicks a 3319 + misleading visible button, the end-user is actually clicking an 3320 + invisible button on the authorization page (such as an "Authorize" 3321 + button). This allows an attacker to trick a resource owner into 3322 + granting its client access without the end-user's knowledge. 3323 + 3324 + To prevent this form of attack, native applications SHOULD use 3325 + external browsers instead of embedding browsers within the 3326 + application when requesting end-user authorization. For most newer 3327 + browsers, avoidance of iframes can be enforced by the authorization 3328 + server using the (non-standard) "x-frame-options" header. This 3329 + header can have two values, "deny" and "sameorigin", which will block 3330 + any framing, or framing by sites with a different origin, 3331 + respectively. For older browsers, JavaScript frame-busting 3332 + techniques can be used but may not be effective in all browsers. 3333 + 3334 + 10.14. Code Injection and Input Validation 3335 + 3336 + A code injection attack occurs when an input or otherwise external 3337 + variable is used by an application unsanitized and causes 3338 + modification to the application logic. This may allow an attacker to 3339 + gain access to the application device or its data, cause denial of 3340 + service, or introduce a wide range of malicious side-effects. 3341 + 3342 + The authorization server and client MUST sanitize (and validate when 3343 + possible) any value received -- in particular, the value of the 3344 + "state" and "redirect_uri" parameters. 3345 + 3346 + 10.15. Open Redirectors 3347 + 3348 + The authorization server, authorization endpoint, and client 3349 + redirection endpoint can be improperly configured and operate as open 3350 + redirectors. An open redirector is an endpoint using a parameter to 3351 + automatically redirect a user-agent to the location specified by the 3352 + parameter value without any validation. 3353 + 3354 + Open redirectors can be used in phishing attacks, or by an attacker 3355 + to get end-users to visit malicious sites by using the URI authority 3356 + component of a familiar and trusted destination. In addition, if the 3357 + authorization server allows the client to register only part of the 3358 + redirection URI, an attacker can use an open redirector operated by 3359 + 3360 + 3361 + 3362 + Hardt Standards Track [Page 60] 3363 + 3364 + RFC 6749 OAuth 2.0 October 2012 3365 + 3366 + 3367 + the client to construct a redirection URI that will pass the 3368 + authorization server validation but will send the authorization code 3369 + or access token to an endpoint under the control of the attacker. 3370 + 3371 + 10.16. Misuse of Access Token to Impersonate Resource Owner in Implicit 3372 + Flow 3373 + 3374 + For public clients using implicit flows, this specification does not 3375 + provide any method for the client to determine what client an access 3376 + token was issued to. 3377 + 3378 + A resource owner may willingly delegate access to a resource by 3379 + granting an access token to an attacker's malicious client. This may 3380 + be due to phishing or some other pretext. An attacker may also steal 3381 + a token via some other mechanism. An attacker may then attempt to 3382 + impersonate the resource owner by providing the access token to a 3383 + legitimate public client. 3384 + 3385 + In the implicit flow (response_type=token), the attacker can easily 3386 + switch the token in the response from the authorization server, 3387 + replacing the real access token with the one previously issued to the 3388 + attacker. 3389 + 3390 + Servers communicating with native applications that rely on being 3391 + passed an access token in the back channel to identify the user of 3392 + the client may be similarly compromised by an attacker creating a 3393 + compromised application that can inject arbitrary stolen access 3394 + tokens. 3395 + 3396 + Any public client that makes the assumption that only the resource 3397 + owner can present it with a valid access token for the resource is 3398 + vulnerable to this type of attack. 3399 + 3400 + This type of attack may expose information about the resource owner 3401 + at the legitimate client to the attacker (malicious client). This 3402 + will also allow the attacker to perform operations at the legitimate 3403 + client with the same permissions as the resource owner who originally 3404 + granted the access token or authorization code. 3405 + 3406 + Authenticating resource owners to clients is out of scope for this 3407 + specification. Any specification that uses the authorization process 3408 + as a form of delegated end-user authentication to the client (e.g., 3409 + third-party sign-in service) MUST NOT use the implicit flow without 3410 + additional security mechanisms that would enable the client to 3411 + determine if the access token was issued for its use (e.g., audience- 3412 + restricting the access token). 3413 + 3414 + 3415 + 3416 + 3417 + 3418 + Hardt Standards Track [Page 61] 3419 + 3420 + RFC 6749 OAuth 2.0 October 2012 3421 + 3422 + 3423 + 11. IANA Considerations 3424 + 3425 + 11.1. OAuth Access Token Types Registry 3426 + 3427 + This specification establishes the OAuth Access Token Types registry. 3428 + 3429 + Access token types are registered with a Specification Required 3430 + ([RFC5226]) after a two-week review period on the 3431 + oauth-ext-review@ietf.org mailing list, on the advice of one or more 3432 + Designated Experts. However, to allow for the allocation of values 3433 + prior to publication, the Designated Expert(s) may approve 3434 + registration once they are satisfied that such a specification will 3435 + be published. 3436 + 3437 + Registration requests must be sent to the oauth-ext-review@ietf.org 3438 + mailing list for review and comment, with an appropriate subject 3439 + (e.g., "Request for access token type: example"). 3440 + 3441 + Within the review period, the Designated Expert(s) will either 3442 + approve or deny the registration request, communicating this decision 3443 + to the review list and IANA. Denials should include an explanation 3444 + and, if applicable, suggestions as to how to make the request 3445 + successful. 3446 + 3447 + IANA must only accept registry updates from the Designated Expert(s) 3448 + and should direct all requests for registration to the review mailing 3449 + list. 3450 + 3451 + 11.1.1. Registration Template 3452 + 3453 + Type name: 3454 + The name requested (e.g., "example"). 3455 + 3456 + Additional Token Endpoint Response Parameters: 3457 + Additional response parameters returned together with the 3458 + "access_token" parameter. New parameters MUST be separately 3459 + registered in the OAuth Parameters registry as described by 3460 + Section 11.2. 3461 + 3462 + HTTP Authentication Scheme(s): 3463 + The HTTP authentication scheme name(s), if any, used to 3464 + authenticate protected resource requests using access tokens of 3465 + this type. 3466 + 3467 + Change controller: 3468 + For Standards Track RFCs, state "IETF". For others, give the name 3469 + of the responsible party. Other details (e.g., postal address, 3470 + email address, home page URI) may also be included. 3471 + 3472 + 3473 + 3474 + Hardt Standards Track [Page 62] 3475 + 3476 + RFC 6749 OAuth 2.0 October 2012 3477 + 3478 + 3479 + Specification document(s): 3480 + Reference to the document(s) that specify the parameter, 3481 + preferably including a URI that can be used to retrieve a copy of 3482 + the document(s). An indication of the relevant sections may also 3483 + be included but is not required. 3484 + 3485 + 11.2. OAuth Parameters Registry 3486 + 3487 + This specification establishes the OAuth Parameters registry. 3488 + 3489 + Additional parameters for inclusion in the authorization endpoint 3490 + request, the authorization endpoint response, the token endpoint 3491 + request, or the token endpoint response are registered with a 3492 + Specification Required ([RFC5226]) after a two-week review period on 3493 + the oauth-ext-review@ietf.org mailing list, on the advice of one or 3494 + more Designated Experts. However, to allow for the allocation of 3495 + values prior to publication, the Designated Expert(s) may approve 3496 + registration once they are satisfied that such a specification will 3497 + be published. 3498 + 3499 + Registration requests must be sent to the oauth-ext-review@ietf.org 3500 + mailing list for review and comment, with an appropriate subject 3501 + (e.g., "Request for parameter: example"). 3502 + 3503 + Within the review period, the Designated Expert(s) will either 3504 + approve or deny the registration request, communicating this decision 3505 + to the review list and IANA. Denials should include an explanation 3506 + and, if applicable, suggestions as to how to make the request 3507 + successful. 3508 + 3509 + IANA must only accept registry updates from the Designated Expert(s) 3510 + and should direct all requests for registration to the review mailing 3511 + list. 3512 + 3513 + 11.2.1. Registration Template 3514 + 3515 + Parameter name: 3516 + The name requested (e.g., "example"). 3517 + 3518 + Parameter usage location: 3519 + The location(s) where parameter can be used. The possible 3520 + locations are authorization request, authorization response, token 3521 + request, or token response. 3522 + 3523 + Change controller: 3524 + For Standards Track RFCs, state "IETF". For others, give the name 3525 + of the responsible party. Other details (e.g., postal address, 3526 + email address, home page URI) may also be included. 3527 + 3528 + 3529 + 3530 + Hardt Standards Track [Page 63] 3531 + 3532 + RFC 6749 OAuth 2.0 October 2012 3533 + 3534 + 3535 + Specification document(s): 3536 + Reference to the document(s) that specify the parameter, 3537 + preferably including a URI that can be used to retrieve a copy of 3538 + the document(s). An indication of the relevant sections may also 3539 + be included but is not required. 3540 + 3541 + 11.2.2. Initial Registry Contents 3542 + 3543 + The OAuth Parameters registry's initial contents are: 3544 + 3545 + o Parameter name: client_id 3546 + o Parameter usage location: authorization request, token request 3547 + o Change controller: IETF 3548 + o Specification document(s): RFC 6749 3549 + 3550 + o Parameter name: client_secret 3551 + o Parameter usage location: token request 3552 + o Change controller: IETF 3553 + o Specification document(s): RFC 6749 3554 + 3555 + o Parameter name: response_type 3556 + o Parameter usage location: authorization request 3557 + o Change controller: IETF 3558 + o Specification document(s): RFC 6749 3559 + 3560 + o Parameter name: redirect_uri 3561 + o Parameter usage location: authorization request, token request 3562 + o Change controller: IETF 3563 + o Specification document(s): RFC 6749 3564 + 3565 + o Parameter name: scope 3566 + o Parameter usage location: authorization request, authorization 3567 + response, token request, token response 3568 + o Change controller: IETF 3569 + o Specification document(s): RFC 6749 3570 + 3571 + o Parameter name: state 3572 + o Parameter usage location: authorization request, authorization 3573 + response 3574 + o Change controller: IETF 3575 + o Specification document(s): RFC 6749 3576 + 3577 + o Parameter name: code 3578 + o Parameter usage location: authorization response, token request 3579 + o Change controller: IETF 3580 + o Specification document(s): RFC 6749 3581 + 3582 + 3583 + 3584 + 3585 + 3586 + Hardt Standards Track [Page 64] 3587 + 3588 + RFC 6749 OAuth 2.0 October 2012 3589 + 3590 + 3591 + o Parameter name: error_description 3592 + o Parameter usage location: authorization response, token response 3593 + o Change controller: IETF 3594 + o Specification document(s): RFC 6749 3595 + 3596 + o Parameter name: error_uri 3597 + o Parameter usage location: authorization response, token response 3598 + o Change controller: IETF 3599 + o Specification document(s): RFC 6749 3600 + 3601 + o Parameter name: grant_type 3602 + o Parameter usage location: token request 3603 + o Change controller: IETF 3604 + o Specification document(s): RFC 6749 3605 + 3606 + o Parameter name: access_token 3607 + o Parameter usage location: authorization response, token response 3608 + o Change controller: IETF 3609 + o Specification document(s): RFC 6749 3610 + 3611 + o Parameter name: token_type 3612 + o Parameter usage location: authorization response, token response 3613 + o Change controller: IETF 3614 + o Specification document(s): RFC 6749 3615 + 3616 + o Parameter name: expires_in 3617 + o Parameter usage location: authorization response, token response 3618 + o Change controller: IETF 3619 + o Specification document(s): RFC 6749 3620 + 3621 + o Parameter name: username 3622 + o Parameter usage location: token request 3623 + o Change controller: IETF 3624 + o Specification document(s): RFC 6749 3625 + 3626 + o Parameter name: password 3627 + o Parameter usage location: token request 3628 + o Change controller: IETF 3629 + o Specification document(s): RFC 6749 3630 + 3631 + o Parameter name: refresh_token 3632 + o Parameter usage location: token request, token response 3633 + o Change controller: IETF 3634 + o Specification document(s): RFC 6749 3635 + 3636 + 3637 + 3638 + 3639 + 3640 + 3641 + 3642 + Hardt Standards Track [Page 65] 3643 + 3644 + RFC 6749 OAuth 2.0 October 2012 3645 + 3646 + 3647 + 11.3. OAuth Authorization Endpoint Response Types Registry 3648 + 3649 + This specification establishes the OAuth Authorization Endpoint 3650 + Response Types registry. 3651 + 3652 + Additional response types for use with the authorization endpoint are 3653 + registered with a Specification Required ([RFC5226]) after a two-week 3654 + review period on the oauth-ext-review@ietf.org mailing list, on the 3655 + advice of one or more Designated Experts. However, to allow for the 3656 + allocation of values prior to publication, the Designated Expert(s) 3657 + may approve registration once they are satisfied that such a 3658 + specification will be published. 3659 + 3660 + Registration requests must be sent to the oauth-ext-review@ietf.org 3661 + mailing list for review and comment, with an appropriate subject 3662 + (e.g., "Request for response type: example"). 3663 + 3664 + Within the review period, the Designated Expert(s) will either 3665 + approve or deny the registration request, communicating this decision 3666 + to the review list and IANA. Denials should include an explanation 3667 + and, if applicable, suggestions as to how to make the request 3668 + successful. 3669 + 3670 + IANA must only accept registry updates from the Designated Expert(s) 3671 + and should direct all requests for registration to the review mailing 3672 + list. 3673 + 3674 + 11.3.1. Registration Template 3675 + 3676 + Response type name: 3677 + The name requested (e.g., "example"). 3678 + 3679 + Change controller: 3680 + For Standards Track RFCs, state "IETF". For others, give the name 3681 + of the responsible party. Other details (e.g., postal address, 3682 + email address, home page URI) may also be included. 3683 + 3684 + Specification document(s): 3685 + Reference to the document(s) that specify the type, preferably 3686 + including a URI that can be used to retrieve a copy of the 3687 + document(s). An indication of the relevant sections may also be 3688 + included but is not required. 3689 + 3690 + 3691 + 3692 + 3693 + 3694 + 3695 + 3696 + 3697 + 3698 + Hardt Standards Track [Page 66] 3699 + 3700 + RFC 6749 OAuth 2.0 October 2012 3701 + 3702 + 3703 + 11.3.2. Initial Registry Contents 3704 + 3705 + The OAuth Authorization Endpoint Response Types registry's initial 3706 + contents are: 3707 + 3708 + o Response type name: code 3709 + o Change controller: IETF 3710 + o Specification document(s): RFC 6749 3711 + 3712 + o Response type name: token 3713 + o Change controller: IETF 3714 + o Specification document(s): RFC 6749 3715 + 3716 + 11.4. OAuth Extensions Error Registry 3717 + 3718 + This specification establishes the OAuth Extensions Error registry. 3719 + 3720 + Additional error codes used together with other protocol extensions 3721 + (i.e., extension grant types, access token types, or extension 3722 + parameters) are registered with a Specification Required ([RFC5226]) 3723 + after a two-week review period on the oauth-ext-review@ietf.org 3724 + mailing list, on the advice of one or more Designated Experts. 3725 + However, to allow for the allocation of values prior to publication, 3726 + the Designated Expert(s) may approve registration once they are 3727 + satisfied that such a specification will be published. 3728 + 3729 + Registration requests must be sent to the oauth-ext-review@ietf.org 3730 + mailing list for review and comment, with an appropriate subject 3731 + (e.g., "Request for error code: example"). 3732 + 3733 + Within the review period, the Designated Expert(s) will either 3734 + approve or deny the registration request, communicating this decision 3735 + to the review list and IANA. Denials should include an explanation 3736 + and, if applicable, suggestions as to how to make the request 3737 + successful. 3738 + 3739 + IANA must only accept registry updates from the Designated Expert(s) 3740 + and should direct all requests for registration to the review mailing 3741 + list. 3742 + 3743 + 3744 + 3745 + 3746 + 3747 + 3748 + 3749 + 3750 + 3751 + 3752 + 3753 + 3754 + Hardt Standards Track [Page 67] 3755 + 3756 + RFC 6749 OAuth 2.0 October 2012 3757 + 3758 + 3759 + 11.4.1. Registration Template 3760 + 3761 + Error name: 3762 + The name requested (e.g., "example"). Values for the error name 3763 + MUST NOT include characters outside the set %x20-21 / %x23-5B / 3764 + %x5D-7E. 3765 + 3766 + Error usage location: 3767 + The location(s) where the error can be used. The possible 3768 + locations are authorization code grant error response 3769 + (Section 4.1.2.1), implicit grant error response 3770 + (Section 4.2.2.1), token error response (Section 5.2), or resource 3771 + access error response (Section 7.2). 3772 + 3773 + Related protocol extension: 3774 + The name of the extension grant type, access token type, or 3775 + extension parameter that the error code is used in conjunction 3776 + with. 3777 + 3778 + Change controller: 3779 + For Standards Track RFCs, state "IETF". For others, give the name 3780 + of the responsible party. Other details (e.g., postal address, 3781 + email address, home page URI) may also be included. 3782 + 3783 + Specification document(s): 3784 + Reference to the document(s) that specify the error code, 3785 + preferably including a URI that can be used to retrieve a copy of 3786 + the document(s). An indication of the relevant sections may also 3787 + be included but is not required. 3788 + 3789 + 12. References 3790 + 3791 + 12.1. Normative References 3792 + 3793 + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 3794 + Requirement Levels", BCP 14, RFC 2119, March 1997. 3795 + 3796 + [RFC2246] Dierks, T. and C. Allen, "The TLS Protocol Version 1.0", 3797 + RFC 2246, January 1999. 3798 + 3799 + [RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H., 3800 + Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext 3801 + Transfer Protocol -- HTTP/1.1", RFC 2616, June 1999. 3802 + 3803 + [RFC2617] Franks, J., Hallam-Baker, P., Hostetler, J., Lawrence, S., 3804 + Leach, P., Luotonen, A., and L. Stewart, "HTTP 3805 + Authentication: Basic and Digest Access Authentication", 3806 + RFC 2617, June 1999. 3807 + 3808 + 3809 + 3810 + Hardt Standards Track [Page 68] 3811 + 3812 + RFC 6749 OAuth 2.0 October 2012 3813 + 3814 + 3815 + [RFC2818] Rescorla, E., "HTTP Over TLS", RFC 2818, May 2000. 3816 + 3817 + [RFC3629] Yergeau, F., "UTF-8, a transformation format of 3818 + ISO 10646", STD 63, RFC 3629, November 2003. 3819 + 3820 + [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform 3821 + Resource Identifier (URI): Generic Syntax", STD 66, 3822 + RFC 3986, January 2005. 3823 + 3824 + [RFC4627] Crockford, D., "The application/json Media Type for 3825 + JavaScript Object Notation (JSON)", RFC 4627, July 2006. 3826 + 3827 + [RFC4949] Shirey, R., "Internet Security Glossary, Version 2", 3828 + RFC 4949, August 2007. 3829 + 3830 + [RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an 3831 + IANA Considerations Section in RFCs", BCP 26, RFC 5226, 3832 + May 2008. 3833 + 3834 + [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax 3835 + Specifications: ABNF", STD 68, RFC 5234, January 2008. 3836 + 3837 + [RFC5246] Dierks, T. and E. Rescorla, "The Transport Layer Security 3838 + (TLS) Protocol Version 1.2", RFC 5246, August 2008. 3839 + 3840 + [RFC6125] Saint-Andre, P. and J. Hodges, "Representation and 3841 + Verification of Domain-Based Application Service Identity 3842 + within Internet Public Key Infrastructure Using X.509 3843 + (PKIX) Certificates in the Context of Transport Layer 3844 + Security (TLS)", RFC 6125, March 2011. 3845 + 3846 + [USASCII] American National Standards Institute, "Coded Character 3847 + Set -- 7-bit American Standard Code for Information 3848 + Interchange", ANSI X3.4, 1986. 3849 + 3850 + [W3C.REC-html401-19991224] 3851 + Raggett, D., Le Hors, A., and I. Jacobs, "HTML 4.01 3852 + Specification", World Wide Web Consortium 3853 + Recommendation REC-html401-19991224, December 1999, 3854 + <http://www.w3.org/TR/1999/REC-html401-19991224>. 3855 + 3856 + [W3C.REC-xml-20081126] 3857 + Bray, T., Paoli, J., Sperberg-McQueen, C., Maler, E., 3858 + and F. Yergeau, "Extensible Markup Language (XML) 1.0 3859 + (Fifth Edition)", World Wide Web Consortium 3860 + Recommendation REC-xml-20081126, November 2008, 3861 + <http://www.w3.org/TR/2008/REC-xml-20081126>. 3862 + 3863 + 3864 + 3865 + 3866 + Hardt Standards Track [Page 69] 3867 + 3868 + RFC 6749 OAuth 2.0 October 2012 3869 + 3870 + 3871 + 12.2. Informative References 3872 + 3873 + [OAuth-HTTP-MAC] 3874 + Hammer-Lahav, E., Ed., "HTTP Authentication: MAC Access 3875 + Authentication", Work in Progress, February 2012. 3876 + 3877 + [OAuth-SAML2] 3878 + Campbell, B. and C. Mortimore, "SAML 2.0 Bearer Assertion 3879 + Profiles for OAuth 2.0", Work in Progress, September 2012. 3880 + 3881 + [OAuth-THREATMODEL] 3882 + Lodderstedt, T., Ed., McGloin, M., and P. Hunt, "OAuth 2.0 3883 + Threat Model and Security Considerations", Work 3884 + in Progress, October 2012. 3885 + 3886 + [OAuth-WRAP] 3887 + Hardt, D., Ed., Tom, A., Eaton, B., and Y. Goland, "OAuth 3888 + Web Resource Authorization Profiles", Work in Progress, 3889 + January 2010. 3890 + 3891 + [RFC5849] Hammer-Lahav, E., "The OAuth 1.0 Protocol", RFC 5849, 3892 + April 2010. 3893 + 3894 + [RFC6750] Jones, M. and D. Hardt, "The OAuth 2.0 Authorization 3895 + Framework: Bearer Token Usage", RFC 6750, October 2012. 3896 + 3897 + 3898 + 3899 + 3900 + 3901 + 3902 + 3903 + 3904 + 3905 + 3906 + 3907 + 3908 + 3909 + 3910 + 3911 + 3912 + 3913 + 3914 + 3915 + 3916 + 3917 + 3918 + 3919 + 3920 + 3921 + 3922 + Hardt Standards Track [Page 70] 3923 + 3924 + RFC 6749 OAuth 2.0 October 2012 3925 + 3926 + 3927 + Appendix A. Augmented Backus-Naur Form (ABNF) Syntax 3928 + 3929 + This section provides Augmented Backus-Naur Form (ABNF) syntax 3930 + descriptions for the elements defined in this specification using the 3931 + notation of [RFC5234]. The ABNF below is defined in terms of Unicode 3932 + code points [W3C.REC-xml-20081126]; these characters are typically 3933 + encoded in UTF-8. Elements are presented in the order first defined. 3934 + 3935 + Some of the definitions that follow use the "URI-reference" 3936 + definition from [RFC3986]. 3937 + 3938 + Some of the definitions that follow use these common definitions: 3939 + 3940 + VSCHAR = %x20-7E 3941 + NQCHAR = %x21 / %x23-5B / %x5D-7E 3942 + NQSCHAR = %x20-21 / %x23-5B / %x5D-7E 3943 + UNICODECHARNOCRLF = %x09 /%x20-7E / %x80-D7FF / 3944 + %xE000-FFFD / %x10000-10FFFF 3945 + 3946 + (The UNICODECHARNOCRLF definition is based upon the Char definition 3947 + in Section 2.2 of [W3C.REC-xml-20081126], but omitting the Carriage 3948 + Return and Linefeed characters.) 3949 + 3950 + A.1. "client_id" Syntax 3951 + 3952 + The "client_id" element is defined in Section 2.3.1: 3953 + 3954 + client-id = *VSCHAR 3955 + 3956 + A.2. "client_secret" Syntax 3957 + 3958 + The "client_secret" element is defined in Section 2.3.1: 3959 + 3960 + client-secret = *VSCHAR 3961 + 3962 + A.3. "response_type" Syntax 3963 + 3964 + The "response_type" element is defined in Sections 3.1.1 and 8.4: 3965 + 3966 + response-type = response-name *( SP response-name ) 3967 + response-name = 1*response-char 3968 + response-char = "_" / DIGIT / ALPHA 3969 + 3970 + 3971 + 3972 + 3973 + 3974 + 3975 + 3976 + 3977 + 3978 + Hardt Standards Track [Page 71] 3979 + 3980 + RFC 6749 OAuth 2.0 October 2012 3981 + 3982 + 3983 + A.4. "scope" Syntax 3984 + 3985 + The "scope" element is defined in Section 3.3: 3986 + 3987 + scope = scope-token *( SP scope-token ) 3988 + scope-token = 1*NQCHAR 3989 + 3990 + A.5. "state" Syntax 3991 + 3992 + The "state" element is defined in Sections 4.1.1, 4.1.2, 4.1.2.1, 3993 + 4.2.1, 4.2.2, and 4.2.2.1: 3994 + 3995 + state = 1*VSCHAR 3996 + 3997 + A.6. "redirect_uri" Syntax 3998 + 3999 + The "redirect_uri" element is defined in Sections 4.1.1, 4.1.3, 4000 + and 4.2.1: 4001 + 4002 + redirect-uri = URI-reference 4003 + 4004 + A.7. "error" Syntax 4005 + 4006 + The "error" element is defined in Sections 4.1.2.1, 4.2.2.1, 5.2, 4007 + 7.2, and 8.5: 4008 + 4009 + error = 1*NQSCHAR 4010 + 4011 + A.8. "error_description" Syntax 4012 + 4013 + The "error_description" element is defined in Sections 4.1.2.1, 4014 + 4.2.2.1, 5.2, and 7.2: 4015 + 4016 + error-description = 1*NQSCHAR 4017 + 4018 + A.9. "error_uri" Syntax 4019 + 4020 + The "error_uri" element is defined in Sections 4.1.2.1, 4.2.2.1, 5.2, 4021 + and 7.2: 4022 + 4023 + error-uri = URI-reference 4024 + 4025 + 4026 + 4027 + 4028 + 4029 + 4030 + 4031 + 4032 + 4033 + 4034 + Hardt Standards Track [Page 72] 4035 + 4036 + RFC 6749 OAuth 2.0 October 2012 4037 + 4038 + 4039 + A.10. "grant_type" Syntax 4040 + 4041 + The "grant_type" element is defined in Sections 4.1.3, 4.3.2, 4.4.2, 4042 + 4.5, and 6: 4043 + 4044 + grant-type = grant-name / URI-reference 4045 + grant-name = 1*name-char 4046 + name-char = "-" / "." / "_" / DIGIT / ALPHA 4047 + 4048 + A.11. "code" Syntax 4049 + 4050 + The "code" element is defined in Section 4.1.3: 4051 + 4052 + code = 1*VSCHAR 4053 + 4054 + A.12. "access_token" Syntax 4055 + 4056 + The "access_token" element is defined in Sections 4.2.2 and 5.1: 4057 + 4058 + access-token = 1*VSCHAR 4059 + 4060 + A.13. "token_type" Syntax 4061 + 4062 + The "token_type" element is defined in Sections 4.2.2, 5.1, and 8.1: 4063 + 4064 + token-type = type-name / URI-reference 4065 + type-name = 1*name-char 4066 + name-char = "-" / "." / "_" / DIGIT / ALPHA 4067 + 4068 + A.14. "expires_in" Syntax 4069 + 4070 + The "expires_in" element is defined in Sections 4.2.2 and 5.1: 4071 + 4072 + expires-in = 1*DIGIT 4073 + 4074 + A.15. "username" Syntax 4075 + 4076 + The "username" element is defined in Section 4.3.2: 4077 + 4078 + username = *UNICODECHARNOCRLF 4079 + 4080 + A.16. "password" Syntax 4081 + 4082 + The "password" element is defined in Section 4.3.2: 4083 + 4084 + password = *UNICODECHARNOCRLF 4085 + 4086 + 4087 + 4088 + 4089 + 4090 + Hardt Standards Track [Page 73] 4091 + 4092 + RFC 6749 OAuth 2.0 October 2012 4093 + 4094 + 4095 + A.17. "refresh_token" Syntax 4096 + 4097 + The "refresh_token" element is defined in Sections 5.1 and 6: 4098 + 4099 + refresh-token = 1*VSCHAR 4100 + 4101 + A.18. Endpoint Parameter Syntax 4102 + 4103 + The syntax for new endpoint parameters is defined in Section 8.2: 4104 + 4105 + param-name = 1*name-char 4106 + name-char = "-" / "." / "_" / DIGIT / ALPHA 4107 + 4108 + Appendix B. Use of application/x-www-form-urlencoded Media Type 4109 + 4110 + At the time of publication of this specification, the 4111 + "application/x-www-form-urlencoded" media type was defined in 4112 + Section 17.13.4 of [W3C.REC-html401-19991224] but not registered in 4113 + the IANA MIME Media Types registry 4114 + (<http://www.iana.org/assignments/media-types>). Furthermore, that 4115 + definition is incomplete, as it does not consider non-US-ASCII 4116 + characters. 4117 + 4118 + To address this shortcoming when generating payloads using this media 4119 + type, names and values MUST be encoded using the UTF-8 character 4120 + encoding scheme [RFC3629] first; the resulting octet sequence then 4121 + needs to be further encoded using the escaping rules defined in 4122 + [W3C.REC-html401-19991224]. 4123 + 4124 + When parsing data from a payload using this media type, the names and 4125 + values resulting from reversing the name/value encoding consequently 4126 + need to be treated as octet sequences, to be decoded using the UTF-8 4127 + character encoding scheme. 4128 + 4129 + For example, the value consisting of the six Unicode code points 4130 + (1) U+0020 (SPACE), (2) U+0025 (PERCENT SIGN), 4131 + (3) U+0026 (AMPERSAND), (4) U+002B (PLUS SIGN), 4132 + (5) U+00A3 (POUND SIGN), and (6) U+20AC (EURO SIGN) would be encoded 4133 + into the octet sequence below (using hexadecimal notation): 4134 + 4135 + 20 25 26 2B C2 A3 E2 82 AC 4136 + 4137 + and then represented in the payload as: 4138 + 4139 + +%25%26%2B%C2%A3%E2%82%AC 4140 + 4141 + 4142 + 4143 + 4144 + 4145 + 4146 + Hardt Standards Track [Page 74] 4147 + 4148 + RFC 6749 OAuth 2.0 October 2012 4149 + 4150 + 4151 + Appendix C. Acknowledgements 4152 + 4153 + The initial OAuth 2.0 protocol specification was edited by David 4154 + Recordon, based on two previous publications: the OAuth 1.0 community 4155 + specification [RFC5849], and OAuth WRAP (OAuth Web Resource 4156 + Authorization Profiles) [OAuth-WRAP]. Eran Hammer then edited many 4157 + of the intermediate drafts that evolved into this RFC. The Security 4158 + Considerations section was drafted by Torsten Lodderstedt, Mark 4159 + McGloin, Phil Hunt, Anthony Nadalin, and John Bradley. The section 4160 + on use of the "application/x-www-form-urlencoded" media type was 4161 + drafted by Julian Reschke. The ABNF section was drafted by Michael 4162 + B. Jones. 4163 + 4164 + The OAuth 1.0 community specification was edited by Eran Hammer and 4165 + authored by Mark Atwood, Dirk Balfanz, Darren Bounds, Richard M. 4166 + Conlan, Blaine Cook, Leah Culver, Breno de Medeiros, Brian Eaton, 4167 + Kellan Elliott-McCrea, Larry Halff, Eran Hammer, Ben Laurie, Chris 4168 + Messina, John Panzer, Sam Quigley, David Recordon, Eran Sandler, 4169 + Jonathan Sergent, Todd Sieling, Brian Slesinsky, and Andy Smith. 4170 + 4171 + The OAuth WRAP specification was edited by Dick Hardt and authored by 4172 + Brian Eaton, Yaron Y. Goland, Dick Hardt, and Allen Tom. 4173 + 4174 + This specification is the work of the OAuth Working Group, which 4175 + includes dozens of active and dedicated participants. In particular, 4176 + the following individuals contributed ideas, feedback, and wording 4177 + that shaped and formed the final specification: 4178 + 4179 + Michael Adams, Amanda Anganes, Andrew Arnott, Dirk Balfanz, Aiden 4180 + Bell, John Bradley, Marcos Caceres, Brian Campbell, Scott Cantor, 4181 + Blaine Cook, Roger Crew, Leah Culver, Bill de hOra, Andre DeMarre, 4182 + Brian Eaton, Wesley Eddy, Wolter Eldering, Brian Ellin, Igor 4183 + Faynberg, George Fletcher, Tim Freeman, Luca Frosini, Evan Gilbert, 4184 + Yaron Y. Goland, Brent Goldman, Kristoffer Gronowski, Eran Hammer, 4185 + Dick Hardt, Justin Hart, Craig Heath, Phil Hunt, Michael B. Jones, 4186 + Terry Jones, John Kemp, Mark Kent, Raffi Krikorian, Chasen Le Hara, 4187 + Rasmus Lerdorf, Torsten Lodderstedt, Hui-Lan Lu, Casey Lucas, Paul 4188 + Madsen, Alastair Mair, Eve Maler, James Manger, Mark McGloin, 4189 + Laurence Miao, William Mills, Chuck Mortimore, Anthony Nadalin, 4190 + Julian Reschke, Justin Richer, Peter Saint-Andre, Nat Sakimura, Rob 4191 + Sayre, Marius Scurtescu, Naitik Shah, Luke Shepard, Vlad Skvortsov, 4192 + Justin Smith, Haibin Song, Niv Steingarten, Christian Stuebner, 4193 + Jeremy Suriel, Paul Tarjan, Christopher Thomas, Henry S. Thompson, 4194 + Allen Tom, Franklin Tse, Nick Walker, Shane Weeden, and Skylar 4195 + Woodward. 4196 + 4197 + 4198 + 4199 + 4200 + 4201 + 4202 + Hardt Standards Track [Page 75] 4203 + 4204 + RFC 6749 OAuth 2.0 October 2012 4205 + 4206 + 4207 + This document was produced under the chairmanship of Blaine Cook, 4208 + Peter Saint-Andre, Hannes Tschofenig, Barry Leiba, and Derek Atkins. 4209 + The area directors included Lisa Dusseault, Peter Saint-Andre, and 4210 + Stephen Farrell. 4211 + 4212 + Author's Address 4213 + 4214 + Dick Hardt (editor) 4215 + Microsoft 4216 + 4217 + EMail: dick.hardt@gmail.com 4218 + URI: http://dickhardt.org/ 4219 + 4220 + 4221 + 4222 + 4223 + 4224 + 4225 + 4226 + 4227 + 4228 + 4229 + 4230 + 4231 + 4232 + 4233 + 4234 + 4235 + 4236 + 4237 + 4238 + 4239 + 4240 + 4241 + 4242 + 4243 + 4244 + 4245 + 4246 + 4247 + 4248 + 4249 + 4250 + 4251 + 4252 + 4253 + 4254 + 4255 + 4256 + 4257 + 4258 + Hardt Standards Track [Page 76] 4259 +
+1123
spec/rfc7636.txt
··· 1 + 2 + 3 + 4 + 5 + 6 + 7 + Internet Engineering Task Force (IETF) N. Sakimura, Ed. 8 + Request for Comments: 7636 Nomura Research Institute 9 + Category: Standards Track J. Bradley 10 + ISSN: 2070-1721 Ping Identity 11 + N. Agarwal 12 + Google 13 + September 2015 14 + 15 + 16 + Proof Key for Code Exchange by OAuth Public Clients 17 + 18 + Abstract 19 + 20 + OAuth 2.0 public clients utilizing the Authorization Code Grant are 21 + susceptible to the authorization code interception attack. This 22 + specification describes the attack as well as a technique to mitigate 23 + against the threat through the use of Proof Key for Code Exchange 24 + (PKCE, pronounced "pixy"). 25 + 26 + Status of This Memo 27 + 28 + This is an Internet Standards Track document. 29 + 30 + This document is a product of the Internet Engineering Task Force 31 + (IETF). It represents the consensus of the IETF community. It has 32 + received public review and has been approved for publication by the 33 + Internet Engineering Steering Group (IESG). Further information on 34 + Internet Standards is available in Section 2 of RFC 5741. 35 + 36 + Information about the current status of this document, any errata, 37 + and how to provide feedback on it may be obtained at 38 + http://www.rfc-editor.org/info/rfc7636. 39 + 40 + Copyright Notice 41 + 42 + Copyright (c) 2015 IETF Trust and the persons identified as the 43 + document authors. All rights reserved. 44 + 45 + This document is subject to BCP 78 and the IETF Trust's Legal 46 + Provisions Relating to IETF Documents 47 + (http://trustee.ietf.org/license-info) in effect on the date of 48 + publication of this document. Please review these documents 49 + carefully, as they describe your rights and restrictions with respect 50 + to this document. Code Components extracted from this document must 51 + include Simplified BSD License text as described in Section 4.e of 52 + the Trust Legal Provisions and are provided without warranty as 53 + described in the Simplified BSD License. 54 + 55 + 56 + 57 + 58 + Sakimura, et al. Standards Track [Page 1] 59 + 60 + RFC 7636 OAUTH PKCE September 2015 61 + 62 + 63 + Table of Contents 64 + 65 + 1. Introduction ....................................................3 66 + 1.1. Protocol Flow ..............................................5 67 + 2. Notational Conventions ..........................................6 68 + 3. Terminology .....................................................7 69 + 3.1. Abbreviations ..............................................7 70 + 4. Protocol ........................................................8 71 + 4.1. Client Creates a Code Verifier .............................8 72 + 4.2. Client Creates the Code Challenge ..........................8 73 + 4.3. Client Sends the Code Challenge with the 74 + Authorization Request ......................................9 75 + 4.4. Server Returns the Code ....................................9 76 + 4.4.1. Error Response ......................................9 77 + 4.5. Client Sends the Authorization Code and the Code 78 + Verifier to the Token Endpoint ............................10 79 + 4.6. Server Verifies code_verifier before Returning the 80 + Tokens ....................................................10 81 + 5. Compatibility ..................................................11 82 + 6. IANA Considerations ............................................11 83 + 6.1. OAuth Parameters Registry .................................11 84 + 6.2. PKCE Code Challenge Method Registry .......................11 85 + 6.2.1. Registration Template ..............................12 86 + 6.2.2. Initial Registry Contents ..........................13 87 + 7. Security Considerations ........................................13 88 + 7.1. Entropy of the code_verifier ..............................13 89 + 7.2. Protection against Eavesdroppers ..........................13 90 + 7.3. Salting the code_challenge ................................14 91 + 7.4. OAuth Security Considerations .............................14 92 + 7.5. TLS Security Considerations ...............................15 93 + 8. References .....................................................15 94 + 8.1. Normative References ......................................15 95 + 8.2. Informative References ....................................16 96 + Appendix A. Notes on Implementing Base64url Encoding without 97 + Padding .............................................17 98 + Appendix B. Example for the S256 code_challenge_method ...........17 99 + Acknowledgements ..................................................19 100 + Authors' Addresses ................................................20 101 + 102 + 103 + 104 + 105 + 106 + 107 + 108 + 109 + 110 + 111 + 112 + 113 + 114 + Sakimura, et al. Standards Track [Page 2] 115 + 116 + RFC 7636 OAUTH PKCE September 2015 117 + 118 + 119 + 1. Introduction 120 + 121 + OAuth 2.0 [RFC6749] public clients are susceptible to the 122 + authorization code interception attack. 123 + 124 + In this attack, the attacker intercepts the authorization code 125 + returned from the authorization endpoint within a communication path 126 + not protected by Transport Layer Security (TLS), such as inter- 127 + application communication within the client's operating system. 128 + 129 + Once the attacker has gained access to the authorization code, it can 130 + use it to obtain the access token. 131 + 132 + Figure 1 shows the attack graphically. In step (1), the native 133 + application running on the end device, such as a smartphone, issues 134 + an OAuth 2.0 Authorization Request via the browser/operating system. 135 + The Redirection Endpoint URI in this case typically uses a custom URI 136 + scheme. Step (1) happens through a secure API that cannot be 137 + intercepted, though it may potentially be observed in advanced attack 138 + scenarios. The request then gets forwarded to the OAuth 2.0 139 + authorization server in step (2). Because OAuth requires the use of 140 + TLS, this communication is protected by TLS and cannot be 141 + intercepted. The authorization server returns the authorization code 142 + in step (3). In step (4), the Authorization Code is returned to the 143 + requester via the Redirection Endpoint URI that was provided in step 144 + (1). 145 + 146 + Note that it is possible for a malicious app to register itself as a 147 + handler for the custom scheme in addition to the legitimate OAuth 2.0 148 + app. Once it does so, the malicious app is now able to intercept the 149 + authorization code in step (4). This allows the attacker to request 150 + and obtain an access token in steps (5) and (6), respectively. 151 + 152 + 153 + 154 + 155 + 156 + 157 + 158 + 159 + 160 + 161 + 162 + 163 + 164 + 165 + 166 + 167 + 168 + 169 + 170 + Sakimura, et al. Standards Track [Page 3] 171 + 172 + RFC 7636 OAUTH PKCE September 2015 173 + 174 + 175 + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ 176 + | End Device (e.g., Smartphone) | 177 + | | 178 + | +-------------+ +----------+ | (6) Access Token +----------+ 179 + | |Legitimate | | Malicious|<--------------------| | 180 + | |OAuth 2.0 App| | App |-------------------->| | 181 + | +-------------+ +----------+ | (5) Authorization | | 182 + | | ^ ^ | Grant | | 183 + | | \ | | | | 184 + | | \ (4) | | | | 185 + | (1) | \ Authz| | | | 186 + | Authz| \ Code | | | Authz | 187 + | Request| \ | | | Server | 188 + | | \ | | | | 189 + | | \ | | | | 190 + | v \ | | | | 191 + | +----------------------------+ | | | 192 + | | | | (3) Authz Code | | 193 + | | Operating System/ |<--------------------| | 194 + | | Browser |-------------------->| | 195 + | | | | (2) Authz Request | | 196 + | +----------------------------+ | +----------+ 197 + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ 198 + 199 + Figure 1: Authorization Code Interception Attack 200 + 201 + A number of pre-conditions need to hold for this attack to work: 202 + 203 + 1. The attacker manages to register a malicious application on the 204 + client device and registers a custom URI scheme that is also used 205 + by another application. The operating systems must allow a custom 206 + URI scheme to be registered by multiple applications. 207 + 208 + 2. The OAuth 2.0 authorization code grant is used. 209 + 210 + 3. The attacker has access to the OAuth 2.0 [RFC6749] "client_id" and 211 + "client_secret" (if provisioned). All OAuth 2.0 native app 212 + client-instances use the same "client_id". Secrets provisioned in 213 + client binary applications cannot be considered confidential. 214 + 215 + 4. Either one of the following condition is met: 216 + 217 + 4a. The attacker (via the installed application) is able to 218 + observe only the responses from the authorization endpoint. 219 + When "code_challenge_method" value is "plain", only this 220 + attack is mitigated. 221 + 222 + 223 + 224 + 225 + 226 + Sakimura, et al. Standards Track [Page 4] 227 + 228 + RFC 7636 OAUTH PKCE September 2015 229 + 230 + 231 + 4b. A more sophisticated attack scenario allows the attacker to 232 + observe requests (in addition to responses) to the 233 + authorization endpoint. The attacker is, however, not able to 234 + act as a man in the middle. This was caused by leaking http 235 + log information in the OS. To mitigate this, 236 + "code_challenge_method" value must be set either to "S256" or 237 + a value defined by a cryptographically secure 238 + "code_challenge_method" extension. 239 + 240 + While this is a long list of pre-conditions, the described attack has 241 + been observed in the wild and has to be considered in OAuth 2.0 242 + deployments. While the OAuth 2.0 threat model (Section 4.4.1 of 243 + [RFC6819]) describes mitigation techniques, they are, unfortunately, 244 + not applicable since they rely on a per-client instance secret or a 245 + per-client instance redirect URI. 246 + 247 + To mitigate this attack, this extension utilizes a dynamically 248 + created cryptographically random key called "code verifier". A 249 + unique code verifier is created for every authorization request, and 250 + its transformed value, called "code challenge", is sent to the 251 + authorization server to obtain the authorization code. The 252 + authorization code obtained is then sent to the token endpoint with 253 + the "code verifier", and the server compares it with the previously 254 + received request code so that it can perform the proof of possession 255 + of the "code verifier" by the client. This works as the mitigation 256 + since the attacker would not know this one-time key, since it is sent 257 + over TLS and cannot be intercepted. 258 + 259 + 1.1. Protocol Flow 260 + 261 + +-------------------+ 262 + | Authz Server | 263 + +--------+ | +---------------+ | 264 + | |--(A)- Authorization Request ---->| | | 265 + | | + t(code_verifier), t_m | | Authorization | | 266 + | | | | Endpoint | | 267 + | |<-(B)---- Authorization Code -----| | | 268 + | | | +---------------+ | 269 + | Client | | | 270 + | | | +---------------+ | 271 + | |--(C)-- Access Token Request ---->| | | 272 + | | + code_verifier | | Token | | 273 + | | | | Endpoint | | 274 + | |<-(D)------ Access Token ---------| | | 275 + +--------+ | +---------------+ | 276 + +-------------------+ 277 + 278 + Figure 2: Abstract Protocol Flow 279 + 280 + 281 + 282 + Sakimura, et al. Standards Track [Page 5] 283 + 284 + RFC 7636 OAUTH PKCE September 2015 285 + 286 + 287 + This specification adds additional parameters to the OAuth 2.0 288 + Authorization and Access Token Requests, shown in abstract form in 289 + Figure 2. 290 + 291 + A. The client creates and records a secret named the "code_verifier" 292 + and derives a transformed version "t(code_verifier)" (referred to 293 + as the "code_challenge"), which is sent in the OAuth 2.0 294 + Authorization Request along with the transformation method "t_m". 295 + 296 + B. The Authorization Endpoint responds as usual but records 297 + "t(code_verifier)" and the transformation method. 298 + 299 + C. The client then sends the authorization code in the Access Token 300 + Request as usual but includes the "code_verifier" secret generated 301 + at (A). 302 + 303 + D. The authorization server transforms "code_verifier" and compares 304 + it to "t(code_verifier)" from (B). Access is denied if they are 305 + not equal. 306 + 307 + An attacker who intercepts the authorization code at (B) is unable to 308 + redeem it for an access token, as they are not in possession of the 309 + "code_verifier" secret. 310 + 311 + 2. Notational Conventions 312 + 313 + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 314 + "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 315 + "OPTIONAL" in this document are to be interpreted as described in 316 + "Key words for use in RFCs to Indicate Requirement Levels" [RFC2119]. 317 + If these words are used without being spelled in uppercase, then they 318 + are to be interpreted with their natural language meanings. 319 + 320 + This specification uses the Augmented Backus-Naur Form (ABNF) 321 + notation of [RFC5234]. 322 + 323 + STRING denotes a sequence of zero or more ASCII [RFC20] characters. 324 + 325 + OCTETS denotes a sequence of zero or more octets. 326 + 327 + ASCII(STRING) denotes the octets of the ASCII [RFC20] representation 328 + of STRING where STRING is a sequence of zero or more ASCII 329 + characters. 330 + 331 + BASE64URL-ENCODE(OCTETS) denotes the base64url encoding of OCTETS, 332 + per Appendix A, producing a STRING. 333 + 334 + 335 + 336 + 337 + 338 + Sakimura, et al. Standards Track [Page 6] 339 + 340 + RFC 7636 OAUTH PKCE September 2015 341 + 342 + 343 + BASE64URL-DECODE(STRING) denotes the base64url decoding of STRING, 344 + per Appendix A, producing a sequence of octets. 345 + 346 + SHA256(OCTETS) denotes a SHA2 256-bit hash [RFC6234] of OCTETS. 347 + 348 + 3. Terminology 349 + 350 + In addition to the terms defined in OAuth 2.0 [RFC6749], this 351 + specification defines the following terms: 352 + 353 + code verifier 354 + A cryptographically random string that is used to correlate the 355 + authorization request to the token request. 356 + 357 + code challenge 358 + A challenge derived from the code verifier that is sent in the 359 + authorization request, to be verified against later. 360 + 361 + code challenge method 362 + A method that was used to derive code challenge. 363 + 364 + Base64url Encoding 365 + Base64 encoding using the URL- and filename-safe character set 366 + defined in Section 5 of [RFC4648], with all trailing '=' 367 + characters omitted (as permitted by Section 3.2 of [RFC4648]) and 368 + without the inclusion of any line breaks, whitespace, or other 369 + additional characters. (See Appendix A for notes on implementing 370 + base64url encoding without padding.) 371 + 372 + 3.1. Abbreviations 373 + 374 + ABNF Augmented Backus-Naur Form 375 + 376 + Authz Authorization 377 + 378 + PKCE Proof Key for Code Exchange 379 + 380 + MITM Man-in-the-middle 381 + 382 + MTI Mandatory To Implement 383 + 384 + 385 + 386 + 387 + 388 + 389 + 390 + 391 + 392 + 393 + 394 + Sakimura, et al. Standards Track [Page 7] 395 + 396 + RFC 7636 OAUTH PKCE September 2015 397 + 398 + 399 + 4. Protocol 400 + 401 + 4.1. Client Creates a Code Verifier 402 + 403 + The client first creates a code verifier, "code_verifier", for each 404 + OAuth 2.0 [RFC6749] Authorization Request, in the following manner: 405 + 406 + code_verifier = high-entropy cryptographic random STRING using the 407 + unreserved characters [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~" 408 + from Section 2.3 of [RFC3986], with a minimum length of 43 characters 409 + and a maximum length of 128 characters. 410 + 411 + ABNF for "code_verifier" is as follows. 412 + 413 + code-verifier = 43*128unreserved 414 + unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" 415 + ALPHA = %x41-5A / %x61-7A 416 + DIGIT = %x30-39 417 + 418 + NOTE: The code verifier SHOULD have enough entropy to make it 419 + impractical to guess the value. It is RECOMMENDED that the output of 420 + a suitable random number generator be used to create a 32-octet 421 + sequence. The octet sequence is then base64url-encoded to produce a 422 + 43-octet URL safe string to use as the code verifier. 423 + 424 + 4.2. Client Creates the Code Challenge 425 + 426 + The client then creates a code challenge derived from the code 427 + verifier by using one of the following transformations on the code 428 + verifier: 429 + 430 + plain 431 + code_challenge = code_verifier 432 + 433 + S256 434 + code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier))) 435 + 436 + If the client is capable of using "S256", it MUST use "S256", as 437 + "S256" is Mandatory To Implement (MTI) on the server. Clients are 438 + permitted to use "plain" only if they cannot support "S256" for some 439 + technical reason and know via out-of-band configuration that the 440 + server supports "plain". 441 + 442 + The plain transformation is for compatibility with existing 443 + deployments and for constrained environments that can't use the S256 444 + transformation. 445 + 446 + 447 + 448 + 449 + 450 + Sakimura, et al. Standards Track [Page 8] 451 + 452 + RFC 7636 OAUTH PKCE September 2015 453 + 454 + 455 + ABNF for "code_challenge" is as follows. 456 + 457 + code-challenge = 43*128unreserved 458 + unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" 459 + ALPHA = %x41-5A / %x61-7A 460 + DIGIT = %x30-39 461 + 462 + 4.3. Client Sends the Code Challenge with the Authorization Request 463 + 464 + The client sends the code challenge as part of the OAuth 2.0 465 + Authorization Request (Section 4.1.1 of [RFC6749]) using the 466 + following additional parameters: 467 + 468 + code_challenge 469 + REQUIRED. Code challenge. 470 + 471 + code_challenge_method 472 + OPTIONAL, defaults to "plain" if not present in the request. Code 473 + verifier transformation method is "S256" or "plain". 474 + 475 + 4.4. Server Returns the Code 476 + 477 + When the server issues the authorization code in the authorization 478 + response, it MUST associate the "code_challenge" and 479 + "code_challenge_method" values with the authorization code so it can 480 + be verified later. 481 + 482 + Typically, the "code_challenge" and "code_challenge_method" values 483 + are stored in encrypted form in the "code" itself but could 484 + alternatively be stored on the server associated with the code. The 485 + server MUST NOT include the "code_challenge" value in client requests 486 + in a form that other entities can extract. 487 + 488 + The exact method that the server uses to associate the 489 + "code_challenge" with the issued "code" is out of scope for this 490 + specification. 491 + 492 + 4.4.1. Error Response 493 + 494 + If the server requires Proof Key for Code Exchange (PKCE) by OAuth 495 + public clients and the client does not send the "code_challenge" in 496 + the request, the authorization endpoint MUST return the authorization 497 + error response with the "error" value set to "invalid_request". The 498 + "error_description" or the response of "error_uri" SHOULD explain the 499 + nature of error, e.g., code challenge required. 500 + 501 + 502 + 503 + 504 + 505 + 506 + Sakimura, et al. Standards Track [Page 9] 507 + 508 + RFC 7636 OAUTH PKCE September 2015 509 + 510 + 511 + If the server supporting PKCE does not support the requested 512 + transformation, the authorization endpoint MUST return the 513 + authorization error response with "error" value set to 514 + "invalid_request". The "error_description" or the response of 515 + "error_uri" SHOULD explain the nature of error, e.g., transform 516 + algorithm not supported. 517 + 518 + 4.5. Client Sends the Authorization Code and the Code Verifier to the 519 + Token Endpoint 520 + 521 + Upon receipt of the Authorization Code, the client sends the Access 522 + Token Request to the token endpoint. In addition to the parameters 523 + defined in the OAuth 2.0 Access Token Request (Section 4.1.3 of 524 + [RFC6749]), it sends the following parameter: 525 + 526 + code_verifier 527 + REQUIRED. Code verifier 528 + 529 + The "code_challenge_method" is bound to the Authorization Code when 530 + the Authorization Code is issued. That is the method that the token 531 + endpoint MUST use to verify the "code_verifier". 532 + 533 + 4.6. Server Verifies code_verifier before Returning the Tokens 534 + 535 + Upon receipt of the request at the token endpoint, the server 536 + verifies it by calculating the code challenge from the received 537 + "code_verifier" and comparing it with the previously associated 538 + "code_challenge", after first transforming it according to the 539 + "code_challenge_method" method specified by the client. 540 + 541 + If the "code_challenge_method" from Section 4.3 was "S256", the 542 + received "code_verifier" is hashed by SHA-256, base64url-encoded, and 543 + then compared to the "code_challenge", i.e.: 544 + 545 + BASE64URL-ENCODE(SHA256(ASCII(code_verifier))) == code_challenge 546 + 547 + If the "code_challenge_method" from Section 4.3 was "plain", they are 548 + compared directly, i.e.: 549 + 550 + code_verifier == code_challenge. 551 + 552 + If the values are equal, the token endpoint MUST continue processing 553 + as normal (as defined by OAuth 2.0 [RFC6749]). If the values are not 554 + equal, an error response indicating "invalid_grant" as described in 555 + Section 5.2 of [RFC6749] MUST be returned. 556 + 557 + 558 + 559 + 560 + 561 + 562 + Sakimura, et al. Standards Track [Page 10] 563 + 564 + RFC 7636 OAUTH PKCE September 2015 565 + 566 + 567 + 5. Compatibility 568 + 569 + Server implementations of this specification MAY accept OAuth2.0 570 + clients that do not implement this extension. If the "code_verifier" 571 + is not received from the client in the Authorization Request, servers 572 + supporting backwards compatibility revert to the OAuth 2.0 [RFC6749] 573 + protocol without this extension. 574 + 575 + As the OAuth 2.0 [RFC6749] server responses are unchanged by this 576 + specification, client implementations of this specification do not 577 + need to know if the server has implemented this specification or not 578 + and SHOULD send the additional parameters as defined in Section 4 to 579 + all servers. 580 + 581 + 6. IANA Considerations 582 + 583 + IANA has made the following registrations per this document. 584 + 585 + 6.1. OAuth Parameters Registry 586 + 587 + This specification registers the following parameters in the IANA 588 + "OAuth Parameters" registry defined in OAuth 2.0 [RFC6749]. 589 + 590 + o Parameter name: code_verifier 591 + o Parameter usage location: token request 592 + o Change controller: IESG 593 + o Specification document(s): RFC 7636 (this document) 594 + 595 + o Parameter name: code_challenge 596 + o Parameter usage location: authorization request 597 + o Change controller: IESG 598 + o Specification document(s): RFC 7636 (this document) 599 + 600 + o Parameter name: code_challenge_method 601 + o Parameter usage location: authorization request 602 + o Change controller: IESG 603 + o Specification document(s): RFC 7636 (this document) 604 + 605 + 6.2. PKCE Code Challenge Method Registry 606 + 607 + This specification establishes the "PKCE Code Challenge Methods" 608 + registry. The new registry should be a sub-registry of the "OAuth 609 + Parameters" registry. 610 + 611 + Additional "code_challenge_method" types for use with the 612 + authorization endpoint are registered using the Specification 613 + Required policy [RFC5226], which includes review of the request by 614 + one or more Designated Experts (DEs). The DEs will ensure that there 615 + 616 + 617 + 618 + Sakimura, et al. Standards Track [Page 11] 619 + 620 + RFC 7636 OAUTH PKCE September 2015 621 + 622 + 623 + is at least a two-week review of the request on the oauth-ext- 624 + review@ietf.org mailing list and that any discussion on that list 625 + converges before they respond to the request. To allow for the 626 + allocation of values prior to publication, the Designated Expert(s) 627 + may approve registration once they are satisfied that an acceptable 628 + specification will be published. 629 + 630 + Registration requests and discussion on the oauth-ext-review@ietf.org 631 + mailing list should use an appropriate subject, such as "Request for 632 + PKCE code_challenge_method: example"). 633 + 634 + The Designated Expert(s) should consider the discussion on the 635 + mailing list, as well as the overall security properties of the 636 + challenge method when evaluating registration requests. New methods 637 + should not disclose the value of the code_verifier in the request to 638 + the Authorization endpoint. Denials should include an explanation 639 + and, if applicable, suggestions as to how to make the request 640 + successful. 641 + 642 + 6.2.1. Registration Template 643 + 644 + Code Challenge Method Parameter Name: 645 + The name requested (e.g., "example"). Because a core goal of this 646 + specification is for the resulting representations to be compact, 647 + it is RECOMMENDED that the name be short -- not to exceed 8 648 + characters without a compelling reason to do so. This name is 649 + case-sensitive. Names may not match other registered names in a 650 + case-insensitive manner unless the Designated Expert(s) states 651 + that there is a compelling reason to allow an exception in this 652 + particular case. 653 + 654 + Change Controller: 655 + For Standards Track RFCs, state "IESG". For others, give the name 656 + of the responsible party. Other details (e.g., postal address, 657 + email address, and home page URI) may also be included. 658 + 659 + Specification Document(s): 660 + Reference to the document(s) that specifies the parameter, 661 + preferably including URI(s) that can be used to retrieve copies of 662 + the document(s). An indication of the relevant sections may also 663 + be included but is not required. 664 + 665 + 666 + 667 + 668 + 669 + 670 + 671 + 672 + 673 + 674 + Sakimura, et al. Standards Track [Page 12] 675 + 676 + RFC 7636 OAUTH PKCE September 2015 677 + 678 + 679 + 6.2.2. Initial Registry Contents 680 + 681 + Per this document, IANA has registered the Code Challenge Method 682 + Parameter Names defined in Section 4.2 in this registry. 683 + 684 + o Code Challenge Method Parameter Name: plain 685 + o Change Controller: IESG 686 + o Specification Document(s): Section 4.2 of RFC 7636 (this document) 687 + 688 + o Code Challenge Method Parameter Name: S256 689 + o Change Controller: IESG 690 + o Specification Document(s): Section 4.2 of RFC 7636 (this document) 691 + 692 + 7. Security Considerations 693 + 694 + 7.1. Entropy of the code_verifier 695 + 696 + The security model relies on the fact that the code verifier is not 697 + learned or guessed by the attacker. It is vitally important to 698 + adhere to this principle. As such, the code verifier has to be 699 + created in such a manner that it is cryptographically random and has 700 + high entropy that it is not practical for the attacker to guess. 701 + 702 + The client SHOULD create a "code_verifier" with a minimum of 256 bits 703 + of entropy. This can be done by having a suitable random number 704 + generator create a 32-octet sequence. The octet sequence can then be 705 + base64url-encoded to produce a 43-octet URL safe string to use as a 706 + "code_challenge" that has the required entropy. 707 + 708 + 7.2. Protection against Eavesdroppers 709 + 710 + Clients MUST NOT downgrade to "plain" after trying the "S256" method. 711 + Servers that support PKCE are required to support "S256", and servers 712 + that do not support PKCE will simply ignore the unknown 713 + "code_verifier". Because of this, an error when "S256" is presented 714 + can only mean that the server is faulty or that a MITM attacker is 715 + trying a downgrade attack. 716 + 717 + The "S256" method protects against eavesdroppers observing or 718 + intercepting the "code_challenge", because the challenge cannot be 719 + used without the verifier. With the "plain" method, there is a 720 + chance that "code_challenge" will be observed by the attacker on the 721 + device or in the http request. Since the code challenge is the same 722 + as the code verifier in this case, the "plain" method does not 723 + protect against the eavesdropping of the initial request. 724 + 725 + The use of "S256" protects against disclosure of the "code_verifier" 726 + value to an attacker. 727 + 728 + 729 + 730 + Sakimura, et al. Standards Track [Page 13] 731 + 732 + RFC 7636 OAUTH PKCE September 2015 733 + 734 + 735 + Because of this, "plain" SHOULD NOT be used and exists only for 736 + compatibility with deployed implementations where the request path is 737 + already protected. The "plain" method SHOULD NOT be used in new 738 + implementations, unless they cannot support "S256" for some technical 739 + reason. 740 + 741 + The "S256" code challenge method or other cryptographically secure 742 + code challenge method extension SHOULD be used. The "plain" code 743 + challenge method relies on the operating system and transport 744 + security not to disclose the request to an attacker. 745 + 746 + If the code challenge method is "plain" and the code challenge is to 747 + be returned inside authorization "code" to achieve a stateless 748 + server, it MUST be encrypted in such a manner that only the server 749 + can decrypt and extract it. 750 + 751 + 7.3. Salting the code_challenge 752 + 753 + To reduce implementation complexity, salting is not used in the 754 + production of the code challenge, as the code verifier contains 755 + sufficient entropy to prevent brute-force attacks. Concatenating a 756 + publicly known value to a code verifier (containing 256 bits of 757 + entropy) and then hashing it with SHA256 to produce a code challenge 758 + would not increase the number of attempts necessary to brute force a 759 + valid value for code verifier. 760 + 761 + While the "S256" transformation is like hashing a password, there are 762 + important differences. Passwords tend to be relatively low-entropy 763 + words that can be hashed offline and the hash looked up in a 764 + dictionary. By concatenating a unique though public value to each 765 + password prior to hashing, the dictionary space that an attacker 766 + needs to search is greatly expanded. 767 + 768 + Modern graphics processors now allow attackers to calculate hashes in 769 + real time faster than they could be looked up from a disk. This 770 + eliminates the value of the salt in increasing the complexity of a 771 + brute-force attack for even low-entropy passwords. 772 + 773 + 7.4. OAuth Security Considerations 774 + 775 + All the OAuth security analysis presented in [RFC6819] applies, so 776 + readers SHOULD carefully follow it. 777 + 778 + 779 + 780 + 781 + 782 + 783 + 784 + 785 + 786 + Sakimura, et al. Standards Track [Page 14] 787 + 788 + RFC 7636 OAUTH PKCE September 2015 789 + 790 + 791 + 7.5. TLS Security Considerations 792 + 793 + Current security considerations can be found in "Recommendations for 794 + Secure Use of Transport Layer Security (TLS) and Datagram Transport 795 + Layer Security (DTLS)" [BCP195]. This supersedes the TLS version 796 + recommendations in OAuth 2.0 [RFC6749]. 797 + 798 + 8. References 799 + 800 + 8.1. Normative References 801 + 802 + [BCP195] Sheffer, Y., Holz, R., and P. Saint-Andre, 803 + "Recommendations for Secure Use of Transport Layer 804 + Security (TLS) and Datagram Transport Layer Security 805 + (DTLS)", BCP 195, RFC 7525, May 2015, 806 + <http://www.rfc-editor.org/info/bcp195>. 807 + 808 + [RFC20] Cerf, V., "ASCII format for network interchange", STD 80, 809 + RFC 20, DOI 10.17487/RFC0020, October 1969, 810 + <http://www.rfc-editor.org/info/rfc20>. 811 + 812 + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 813 + Requirement Levels", BCP 14, RFC 2119, 814 + DOI 10.17487/RFC2119, March 1997, 815 + <http://www.rfc-editor.org/info/rfc2119>. 816 + 817 + [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform 818 + Resource Identifier (URI): Generic Syntax", STD 66, RFC 819 + 3986, DOI 10.17487/RFC3986, January 2005, 820 + <http://www.rfc-editor.org/info/rfc3986>. 821 + 822 + [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data 823 + Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006, 824 + <http://www.rfc-editor.org/info/rfc4648>. 825 + 826 + [RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an 827 + IANA Considerations Section in RFCs", BCP 26, RFC 5226, 828 + DOI 10.17487/RFC5226, May 2008, 829 + <http://www.rfc-editor.org/info/rfc5226>. 830 + 831 + [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax 832 + Specifications: ABNF", STD 68, RFC 5234, 833 + DOI 10.17487/RFC5234, January 2008, 834 + <http://www.rfc-editor.org/info/rfc5234>. 835 + 836 + 837 + 838 + 839 + 840 + 841 + 842 + Sakimura, et al. Standards Track [Page 15] 843 + 844 + RFC 7636 OAUTH PKCE September 2015 845 + 846 + 847 + [RFC6234] Eastlake 3rd, D. and T. Hansen, "US Secure Hash Algorithms 848 + (SHA and SHA-based HMAC and HKDF)", RFC 6234, 849 + DOI 10.17487/RFC6234, May 2011, 850 + <http://www.rfc-editor.org/info/rfc6234>. 851 + 852 + [RFC6749] Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", 853 + RFC 6749, DOI 10.17487/RFC6749, October 2012, 854 + <http://www.rfc-editor.org/info/rfc6749>. 855 + 856 + 8.2. Informative References 857 + 858 + [RFC6819] Lodderstedt, T., Ed., McGloin, M., and P. Hunt, "OAuth 2.0 859 + Threat Model and Security Considerations", RFC 6819, 860 + DOI 10.17487/RFC6819, January 2013, 861 + <http://www.rfc-editor.org/info/rfc6819>. 862 + 863 + 864 + 865 + 866 + 867 + 868 + 869 + 870 + 871 + 872 + 873 + 874 + 875 + 876 + 877 + 878 + 879 + 880 + 881 + 882 + 883 + 884 + 885 + 886 + 887 + 888 + 889 + 890 + 891 + 892 + 893 + 894 + 895 + 896 + 897 + 898 + Sakimura, et al. Standards Track [Page 16] 899 + 900 + RFC 7636 OAUTH PKCE September 2015 901 + 902 + 903 + Appendix A. Notes on Implementing Base64url Encoding without Padding 904 + 905 + This appendix describes how to implement a base64url-encoding 906 + function without padding, based upon the standard base64-encoding 907 + function that uses padding. 908 + 909 + To be concrete, example C# code implementing these functions is shown 910 + below. Similar code could be used in other languages. 911 + 912 + static string base64urlencode(byte [] arg) 913 + { 914 + string s = Convert.ToBase64String(arg); // Regular base64 encoder 915 + s = s.Split('=')[0]; // Remove any trailing '='s 916 + s = s.Replace('+', '-'); // 62nd char of encoding 917 + s = s.Replace('/', '_'); // 63rd char of encoding 918 + return s; 919 + } 920 + 921 + An example correspondence between unencoded and encoded values 922 + follows. The octet sequence below encodes into the string below, 923 + which when decoded, reproduces the octet sequence. 924 + 925 + 3 236 255 224 193 926 + 927 + A-z_4ME 928 + 929 + Appendix B. Example for the S256 code_challenge_method 930 + 931 + The client uses output of a suitable random number generator to 932 + create a 32-octet sequence. The octets representing the value in 933 + this example (using JSON array notation) are: 934 + 935 + [116, 24, 223, 180, 151, 153, 224, 37, 79, 250, 96, 125, 216, 173, 936 + 187, 186, 22, 212, 37, 77, 105, 214, 191, 240, 91, 88, 5, 88, 83, 937 + 132, 141, 121] 938 + 939 + Encoding this octet sequence as base64url provides the value of the 940 + code_verifier: 941 + 942 + dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk 943 + 944 + The code_verifier is then hashed via the SHA256 hash function to 945 + produce: 946 + 947 + [19, 211, 30, 150, 26, 26, 216, 236, 47, 22, 177, 12, 76, 152, 46, 948 + 8, 118, 168, 120, 173, 109, 241, 68, 86, 110, 225, 137, 74, 203, 949 + 112, 249, 195] 950 + 951 + 952 + 953 + 954 + Sakimura, et al. Standards Track [Page 17] 955 + 956 + RFC 7636 OAUTH PKCE September 2015 957 + 958 + 959 + Encoding this octet sequence as base64url provides the value of the 960 + code_challenge: 961 + 962 + E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM 963 + 964 + The authorization request includes: 965 + 966 + code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM 967 + &code_challenge_method=S256 968 + 969 + The authorization server then records the code_challenge and 970 + code_challenge_method along with the code that is granted to the 971 + client. 972 + 973 + In the request to the token_endpoint, the client includes the code 974 + received in the authorization response as well as the additional 975 + parameter: 976 + 977 + code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk 978 + 979 + The authorization server retrieves the information for the code 980 + grant. Based on the recorded code_challenge_method being S256, it 981 + then hashes and base64url-encodes the value of code_verifier: 982 + 983 + BASE64URL-ENCODE(SHA256(ASCII(code_verifier))) 984 + 985 + The calculated value is then compared with the value of 986 + "code_challenge": 987 + 988 + BASE64URL-ENCODE(SHA256(ASCII(code_verifier))) == code_challenge 989 + 990 + If the two values are equal, then the authorization server can 991 + provide the tokens as long as there are no other errors in the 992 + request. If the values are not equal, then the request must be 993 + rejected, and an error returned. 994 + 995 + 996 + 997 + 998 + 999 + 1000 + 1001 + 1002 + 1003 + 1004 + 1005 + 1006 + 1007 + 1008 + 1009 + 1010 + Sakimura, et al. Standards Track [Page 18] 1011 + 1012 + RFC 7636 OAUTH PKCE September 2015 1013 + 1014 + 1015 + Acknowledgements 1016 + 1017 + The initial draft version of this specification was created by the 1018 + OpenID AB/Connect Working Group of the OpenID Foundation. 1019 + 1020 + This specification is the work of the OAuth Working Group, which 1021 + includes dozens of active and dedicated participants. In particular, 1022 + the following individuals contributed ideas, feedback, and wording 1023 + that shaped and formed the final specification: 1024 + 1025 + Anthony Nadalin, Microsoft 1026 + Axel Nenker, Deutsche Telekom 1027 + Breno de Medeiros, Google 1028 + Brian Campbell, Ping Identity 1029 + Chuck Mortimore, Salesforce 1030 + Dirk Balfanz, Google 1031 + Eduardo Gueiros, Jive Communications 1032 + Hannes Tschonfenig, ARM 1033 + James Manger, Telstra 1034 + Justin Richer, MIT Kerberos 1035 + Josh Mandel, Boston Children's Hospital 1036 + Lewis Adam, Motorola Solutions 1037 + Madjid Nakhjiri, Samsung 1038 + Michael B. Jones, Microsoft 1039 + Paul Madsen, Ping Identity 1040 + Phil Hunt, Oracle 1041 + Prateek Mishra, Oracle 1042 + Ryo Ito, mixi 1043 + Scott Tomilson, Ping Identity 1044 + Sergey Beryozkin 1045 + Takamichi Saito 1046 + Torsten Lodderstedt, Deutsche Telekom 1047 + William Denniss, Google 1048 + 1049 + 1050 + 1051 + 1052 + 1053 + 1054 + 1055 + 1056 + 1057 + 1058 + 1059 + 1060 + 1061 + 1062 + 1063 + 1064 + 1065 + 1066 + Sakimura, et al. Standards Track [Page 19] 1067 + 1068 + RFC 7636 OAUTH PKCE September 2015 1069 + 1070 + 1071 + Authors' Addresses 1072 + 1073 + Nat Sakimura (editor) 1074 + Nomura Research Institute 1075 + 1-6-5 Marunouchi, Marunouchi Kitaguchi Bldg. 1076 + Chiyoda-ku, Tokyo 100-0005 1077 + Japan 1078 + 1079 + Phone: +81-3-5533-2111 1080 + Email: n-sakimura@nri.co.jp 1081 + URI: http://nat.sakimura.org/ 1082 + 1083 + 1084 + John Bradley 1085 + Ping Identity 1086 + Casilla 177, Sucursal Talagante 1087 + Talagante, RM 1088 + Chile 1089 + 1090 + Phone: +44 20 8133 3718 1091 + Email: ve7jtb@ve7jtb.com 1092 + URI: http://www.thread-safe.com/ 1093 + 1094 + 1095 + Naveen Agarwal 1096 + Google 1097 + 1600 Amphitheatre Parkway 1098 + Mountain View, CA 94043 1099 + United States 1100 + 1101 + Phone: +1 650-253-0000 1102 + Email: naa@google.com 1103 + URI: http://google.com/ 1104 + 1105 + 1106 + 1107 + 1108 + 1109 + 1110 + 1111 + 1112 + 1113 + 1114 + 1115 + 1116 + 1117 + 1118 + 1119 + 1120 + 1121 + 1122 + Sakimura, et al. Standards Track [Page 20] 1123 +
+4
test/dune
··· 34 34 (name test_rfc9421_vectors) 35 35 (libraries requests alcotest base64 digestif fmt fmt.tty logs logs.fmt mirage-crypto-rng.unix mirage-crypto-ec)) 36 36 37 + (executable 38 + (name test_oauth) 39 + (libraries requests requests.oauth alcotest astring fmt fmt.tty logs logs.fmt mirage-crypto-rng.unix ptime ptime.clock.os)) 40 + 37 41 (cram 38 42 (deps %{bin:ocurl}))
+325
test/test_oauth.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 + SPDX-License-Identifier: ISC 4 + ---------------------------------------------------------------------------*) 5 + 6 + (** Tests for OAuth 2.0 implementation (RFC 6749) *) 7 + 8 + let () = Mirage_crypto_rng_unix.use_default () 9 + 10 + (** {1 Test Utilities} *) 11 + 12 + let test_case name fn = 13 + Alcotest.test_case name `Quick fn 14 + 15 + (** {1 PKCE Tests} *) 16 + 17 + let test_pkce_generation () = 18 + let pkce = Requests_oauth.Oauth.generate_pkce () in 19 + (* Verifier should be URL-safe base64 without padding *) 20 + Alcotest.(check bool) "verifier not empty" true (String.length pkce.verifier > 0); 21 + Alcotest.(check bool) "verifier >= 43 chars" true (String.length pkce.verifier >= 43); 22 + (* Challenge should be different from verifier for S256 *) 23 + Alcotest.(check bool) "challenge differs from verifier" 24 + true (pkce.challenge <> pkce.verifier); 25 + (* Challenge method should be S256 by default *) 26 + Alcotest.(check string) "default method is S256" 27 + "S256" (Requests_oauth.Oauth.pkce_method_to_string pkce.method_) 28 + 29 + let test_pkce_plain () = 30 + let pkce = Requests_oauth.Oauth.generate_pkce ~method_:Plain () in 31 + (* For plain method, challenge equals verifier *) 32 + Alcotest.(check string) "plain: challenge equals verifier" 33 + pkce.verifier pkce.challenge; 34 + Alcotest.(check string) "method is plain" 35 + "plain" (Requests_oauth.Oauth.pkce_method_to_string pkce.method_) 36 + 37 + let test_pkce_s256_deterministic () = 38 + (* S256 challenge should be deterministic for the same verifier *) 39 + (* This tests the challenge computation, not the random generation *) 40 + let pkce1 = Requests_oauth.Oauth.generate_pkce () in 41 + let pkce2 = Requests_oauth.Oauth.generate_pkce () in 42 + (* Different verifiers should produce different challenges *) 43 + Alcotest.(check bool) "different verifiers -> different challenges" 44 + true (pkce1.challenge <> pkce2.challenge) 45 + 46 + (** {1 State Parameter Tests} *) 47 + 48 + let test_state_generation () = 49 + let state = Requests_oauth.Oauth.generate_state () in 50 + Alcotest.(check bool) "state not empty" true (String.length state > 0); 51 + (* State should be URL-safe *) 52 + String.iter (fun c -> 53 + let is_url_safe = 54 + (c >= 'A' && c <= 'Z') || 55 + (c >= 'a' && c <= 'z') || 56 + (c >= '0' && c <= '9') || 57 + c = '-' || c = '_' 58 + in 59 + Alcotest.(check bool) "state is URL-safe" true is_url_safe 60 + ) state 61 + 62 + let test_state_validation () = 63 + let state = "test-state-123" in 64 + Alcotest.(check bool) "valid state matches" 65 + true (Requests_oauth.Oauth.validate_state ~expected:state ~received:state); 66 + Alcotest.(check bool) "invalid state does not match" 67 + false (Requests_oauth.Oauth.validate_state ~expected:state ~received:"other-state") 68 + 69 + (** {1 Configuration Tests} *) 70 + 71 + let test_make_config () = 72 + let config = Requests_oauth.Oauth.make_config 73 + ~client_id:"my-client" 74 + ~client_secret:"my-secret" 75 + ~token_endpoint:"https://auth.example.com/token" 76 + ~authorization_endpoint:"https://auth.example.com/authorize" 77 + ~redirect_uri:"https://app.example.com/callback" 78 + ~scopes:["read"; "write"] 79 + () in 80 + Alcotest.(check string) "client_id" "my-client" config.client_id; 81 + Alcotest.(check (option string)) "client_secret" (Some "my-secret") config.client_secret; 82 + Alcotest.(check string) "token_endpoint" 83 + "https://auth.example.com/token" config.token_endpoint; 84 + Alcotest.(check (option string)) "authorization_endpoint" 85 + (Some "https://auth.example.com/authorize") config.authorization_endpoint; 86 + Alcotest.(check (list string)) "scopes" ["read"; "write"] config.scopes 87 + 88 + let test_make_config_minimal () = 89 + let config = Requests_oauth.Oauth.make_config 90 + ~client_id:"public-client" 91 + ~token_endpoint:"https://auth.example.com/token" 92 + () in 93 + Alcotest.(check string) "client_id" "public-client" config.client_id; 94 + Alcotest.(check (option string)) "client_secret (public)" None config.client_secret; 95 + Alcotest.(check (option string)) "authorization_endpoint" None config.authorization_endpoint; 96 + Alcotest.(check (list string)) "scopes (empty)" [] config.scopes 97 + 98 + (** {1 Authorization URL Tests} *) 99 + 100 + let test_authorization_url () = 101 + let config = Requests_oauth.Oauth.make_config 102 + ~client_id:"my-client" 103 + ~token_endpoint:"https://auth.example.com/token" 104 + ~authorization_endpoint:"https://auth.example.com/authorize" 105 + ~redirect_uri:"https://app.example.com/callback" 106 + ~scopes:["read"; "write"] 107 + () in 108 + let state = "random-state-123" in 109 + let url = Requests_oauth.Oauth.authorization_url ~config ~state () in 110 + (* Check URL contains expected components *) 111 + let contains sub = Astring.String.find_sub ~sub url |> Option.is_some in 112 + Alcotest.(check bool) "contains response_type=code" true (contains "response_type=code"); 113 + Alcotest.(check bool) "contains client_id" true (contains "client_id=my-client"); 114 + Alcotest.(check bool) "contains state" true (contains "state=random-state-123"); 115 + Alcotest.(check bool) "contains scope" true (contains "scope=read") 116 + 117 + let test_authorization_url_with_pkce () = 118 + let config = Requests_oauth.Oauth.make_config 119 + ~client_id:"my-client" 120 + ~token_endpoint:"https://auth.example.com/token" 121 + ~authorization_endpoint:"https://auth.example.com/authorize" 122 + () in 123 + let state = "random-state" in 124 + let pkce = Requests_oauth.Oauth.generate_pkce () in 125 + let url = Requests_oauth.Oauth.authorization_url ~config ~state ~pkce () in 126 + Alcotest.(check bool) "contains code_challenge" 127 + true (Astring.String.find_sub ~sub:"code_challenge=" url |> Option.is_some); 128 + Alcotest.(check bool) "contains code_challenge_method=S256" 129 + true (Astring.String.find_sub ~sub:"code_challenge_method=S256" url |> Option.is_some) 130 + 131 + let test_authorization_url_no_endpoint () = 132 + let config = Requests_oauth.Oauth.make_config 133 + ~client_id:"my-client" 134 + ~token_endpoint:"https://auth.example.com/token" 135 + () in 136 + let state = "random-state" in 137 + Alcotest.check_raises "raises without authorization_endpoint" 138 + (Invalid_argument "authorization_endpoint is required for authorization URL") 139 + (fun () -> ignore (Requests_oauth.Oauth.authorization_url ~config ~state ())) 140 + 141 + (** {1 Error Code Tests} *) 142 + 143 + let test_error_code_to_string () = 144 + let codes = [ 145 + (Requests_oauth.Oauth.Invalid_request, "invalid_request"); 146 + (Requests_oauth.Oauth.Invalid_client, "invalid_client"); 147 + (Requests_oauth.Oauth.Invalid_grant, "invalid_grant"); 148 + (Requests_oauth.Oauth.Unauthorized_client, "unauthorized_client"); 149 + (Requests_oauth.Oauth.Unsupported_grant_type, "unsupported_grant_type"); 150 + (Requests_oauth.Oauth.Invalid_scope, "invalid_scope"); 151 + (Requests_oauth.Oauth.Unknown_error "custom", "custom"); 152 + ] in 153 + List.iter (fun (code, expected) -> 154 + Alcotest.(check string) ("to_string: " ^ expected) 155 + expected (Requests_oauth.Oauth.error_code_to_string code) 156 + ) codes 157 + 158 + (** {1 Token Tests} *) 159 + 160 + let test_token_accessors () = 161 + (* Test token accessor functions with a mock token *) 162 + let token : Requests_oauth.Oauth.token = { 163 + access_token = "test-access-token"; 164 + token_type = "Bearer"; 165 + expires_at = None; 166 + refresh_token = Some "test-refresh-token"; 167 + scope = Some "read write"; 168 + } in 169 + Alcotest.(check string) "get_access_token" 170 + "test-access-token" (Requests_oauth.Oauth.get_access_token token); 171 + Alcotest.(check (option string)) "get_refresh_token" 172 + (Some "test-refresh-token") (Requests_oauth.Oauth.get_refresh_token token) 173 + 174 + let test_token_expiry_no_expiry () = 175 + (* Token without expiry should not be expired *) 176 + let token : Requests_oauth.Oauth.token = { 177 + access_token = "test-token"; 178 + token_type = "Bearer"; 179 + expires_at = None; 180 + refresh_token = None; 181 + scope = None; 182 + } in 183 + Alcotest.(check bool) "no expiry -> not expired" 184 + false (Requests_oauth.Oauth.is_expired token); 185 + Alcotest.(check bool) "no expiry -> not expires_within" 186 + false (Requests_oauth.Oauth.expires_within (Ptime.Span.of_int_s 3600) token) 187 + 188 + let test_token_expiry_expired () = 189 + (* Create a token that expired 1 hour ago *) 190 + let one_hour_ago = 191 + Ptime.sub_span (Ptime_clock.now ()) (Ptime.Span.of_int_s 3600) 192 + |> Option.get 193 + in 194 + let token : Requests_oauth.Oauth.token = { 195 + access_token = "test-token"; 196 + token_type = "Bearer"; 197 + expires_at = Some one_hour_ago; 198 + refresh_token = None; 199 + scope = None; 200 + } in 201 + Alcotest.(check bool) "expired token is_expired" true (Requests_oauth.Oauth.is_expired token) 202 + 203 + let test_token_expires_within () = 204 + (* Create a token that expires in 15 seconds *) 205 + let expires_in_15s = 206 + Ptime.add_span (Ptime_clock.now ()) (Ptime.Span.of_int_s 15) 207 + |> Option.get 208 + in 209 + let token : Requests_oauth.Oauth.token = { 210 + access_token = "test-token"; 211 + token_type = "Bearer"; 212 + expires_at = Some expires_in_15s; 213 + refresh_token = None; 214 + scope = None; 215 + } in 216 + (* 30 second window should include it *) 217 + Alcotest.(check bool) "expires within 30s" 218 + true (Requests_oauth.Oauth.expires_within (Ptime.Span.of_int_s 30) token); 219 + (* 10 second window should not include it *) 220 + Alcotest.(check bool) "not expires within 10s" 221 + false (Requests_oauth.Oauth.expires_within (Ptime.Span.of_int_s 10) token) 222 + 223 + (** {1 Error Formatting Tests} *) 224 + 225 + let test_pp_error () = 226 + let err : Requests_oauth.Oauth.error = { 227 + code = Requests_oauth.Oauth.Invalid_grant; 228 + description = Some "The token has expired"; 229 + uri = Some "https://example.com/errors"; 230 + } in 231 + let buf = Buffer.create 128 in 232 + let ppf = Format.formatter_of_buffer buf in 233 + Requests_oauth.Oauth.pp_error ppf err; 234 + Format.pp_print_flush ppf (); 235 + let output = Buffer.contents buf in 236 + Alcotest.(check bool) "contains error code" 237 + true (Astring.String.find_sub ~sub:"invalid_grant" output |> Option.is_some); 238 + Alcotest.(check bool) "contains description" 239 + true (Astring.String.find_sub ~sub:"The token has expired" output |> Option.is_some) 240 + 241 + (** {1 Auth Module Integration Tests} *) 242 + 243 + let test_auth_requires_https () = 244 + (* Basic and Bearer auth should require HTTPS *) 245 + let basic = Requests.Auth.basic ~username:"user" ~password:"pass" in 246 + let bearer = Requests.Auth.bearer ~token:"token" in 247 + Alcotest.(check bool) "basic requires https" true (Requests.Auth.requires_https basic); 248 + Alcotest.(check bool) "bearer requires https" true (Requests.Auth.requires_https bearer) 249 + 250 + (** {1 Error Module Integration Tests} *) 251 + 252 + let test_error_oauth_types () = 253 + let err = Requests.Error.Oauth_error { 254 + error_code = "invalid_grant"; 255 + description = Some "Token expired"; 256 + uri = None; 257 + } in 258 + Alcotest.(check bool) "is_oauth_error" true (Requests.Error.is_oauth_error err); 259 + Alcotest.(check bool) "is_retryable" false (Requests.Error.is_retryable err) 260 + 261 + let test_error_token_expired () = 262 + let err = Requests.Error.Token_expired in 263 + Alcotest.(check bool) "is_oauth_error" true (Requests.Error.is_oauth_error err) 264 + 265 + let test_error_token_refresh_failed () = 266 + let err = Requests.Error.Token_refresh_failed { reason = "No refresh token" } in 267 + Alcotest.(check bool) "is_oauth_error" true (Requests.Error.is_oauth_error err) 268 + 269 + (** {1 Test Runner} *) 270 + 271 + let pkce_tests = [ 272 + test_case "PKCE generation (S256)" test_pkce_generation; 273 + test_case "PKCE generation (plain)" test_pkce_plain; 274 + test_case "PKCE S256 deterministic" test_pkce_s256_deterministic; 275 + ] 276 + 277 + let state_tests = [ 278 + test_case "State generation" test_state_generation; 279 + test_case "State validation" test_state_validation; 280 + ] 281 + 282 + let config_tests = [ 283 + test_case "Make config with all options" test_make_config; 284 + test_case "Make config minimal" test_make_config_minimal; 285 + ] 286 + 287 + let auth_url_tests = [ 288 + test_case "Authorization URL" test_authorization_url; 289 + test_case "Authorization URL with PKCE" test_authorization_url_with_pkce; 290 + test_case "Authorization URL without endpoint" test_authorization_url_no_endpoint; 291 + ] 292 + 293 + let error_code_tests = [ 294 + test_case "Error code to_string" test_error_code_to_string; 295 + ] 296 + 297 + let token_tests = [ 298 + test_case "Token accessors" test_token_accessors; 299 + test_case "Token expiry - no expiry" test_token_expiry_no_expiry; 300 + test_case "Token expiry - expired" test_token_expiry_expired; 301 + test_case "Token expires_within" test_token_expires_within; 302 + ] 303 + 304 + let error_format_tests = [ 305 + test_case "Error pretty printing" test_pp_error; 306 + ] 307 + 308 + let integration_tests = [ 309 + test_case "Auth requires HTTPS" test_auth_requires_https; 310 + test_case "Error OAuth types" test_error_oauth_types; 311 + test_case "Error token expired" test_error_token_expired; 312 + test_case "Error token refresh failed" test_error_token_refresh_failed; 313 + ] 314 + 315 + let () = 316 + Alcotest.run "OAuth 2.0 (RFC 6749)" [ 317 + ("PKCE (RFC 7636)", pkce_tests); 318 + ("State Parameter", state_tests); 319 + ("Client Configuration", config_tests); 320 + ("Authorization URL", auth_url_tests); 321 + ("Error Codes", error_code_tests); 322 + ("Token Management", token_tests); 323 + ("Error Formatting", error_format_tests); 324 + ("Integration", integration_tests); 325 + ]