1package oidc_test 2 3import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "net/http" 8 "time" 9 10 "github.com/hashicorp/cap/oidc" 11) 12 13func Example() { 14 ctx := context.Background() 15 // Create a new Config 16 pc, err := oidc.NewConfig( 17 "http://your-issuer.com/", 18 "your_client_id", 19 "your_client_secret", 20 []oidc.Alg{oidc.RS256}, 21 []string{"http://your_redirect_url"}, 22 ) 23 if err != nil { 24 // handle error 25 } 26 27 // Create a provider 28 p, err := oidc.NewProvider(pc) 29 if err != nil { 30 // handle error 31 } 32 defer p.Done() 33 34 // Create a Request for a user's authentication attempt that will use the 35 // authorization code flow. (See NewRequest(...) using the WithPKCE and 36 // WithImplicit options for creating a Request that uses those flows.) 37 oidcRequest, err := oidc.NewRequest(2*time.Minute, "http://your_redirect_url/callback") 38 if err != nil { 39 // handle error 40 } 41 42 // Create an auth URL 43 authURL, err := p.AuthURL(ctx, oidcRequest) 44 if err != nil { 45 // handle error 46 } 47 fmt.Println("open url to kick-off authentication: ", authURL) 48 49 // Create a http.Handler for OIDC authentication response redirects 50 callbackHandler := func(w http.ResponseWriter, r *http.Request) { 51 // Exchange a successful authentication's authorization code and 52 // authorization state (received in a callback) for a verified Token. 53 t, err := p.Exchange(ctx, oidcRequest, r.FormValue("state"), r.FormValue("code")) 54 if err != nil { 55 // handle error 56 } 57 var claims map[string]interface{} 58 if err := t.IDToken().Claims(&claims); err != nil { 59 // handle error 60 } 61 62 // Get the user's claims via the provider's UserInfo endpoint 63 var infoClaims map[string]interface{} 64 err = p.UserInfo(ctx, t.StaticTokenSource(), claims["sub"].(string), &infoClaims) 65 if err != nil { 66 // handle error 67 } 68 resp := struct { 69 IDTokenClaims map[string]interface{} 70 UserInfoClaims map[string]interface{} 71 }{claims, infoClaims} 72 enc := json.NewEncoder(w) 73 if err := enc.Encode(resp); err != nil { 74 // handle error 75 } 76 } 77 http.HandleFunc("/callback", callbackHandler) 78} 79 80func ExampleNewConfig() { 81 // Create a new Config 82 pc, err := oidc.NewConfig( 83 "http://your_issuer/", 84 "your_client_id", 85 "your_client_secret", 86 []oidc.Alg{oidc.RS256}, 87 []string{"http://your_redirect_url/callback"}, 88 ) 89 if err != nil { 90 // handle error 91 } 92 fmt.Println(pc) 93 94 // Output: 95 // &{your_client_id [REDACTED: client secret] [openid] http://your_issuer/ [RS256] [http://your_redirect_url/callback] [] <nil>} 96} 97 98func ExampleNewProvider() { 99 // Create a new Config 100 pc, err := oidc.NewConfig( 101 "http://your_issuer/", 102 "your_client_id", 103 "your_client_secret", 104 []oidc.Alg{oidc.RS256}, 105 []string{"http://your_redirect_url/callback"}, 106 ) 107 if err != nil { 108 // handle error 109 } 110 111 // Create a provider 112 p, err := oidc.NewProvider(pc) 113 if err != nil { 114 // handle error 115 } 116 defer p.Done() 117} 118 119func ExampleProvider_AuthURL() { 120 ctx := context.Background() 121 // Create a new Config 122 pc, err := oidc.NewConfig( 123 "http://your_issuer/", 124 "your_client_id", 125 "your_client_secret", 126 []oidc.Alg{oidc.RS256}, 127 []string{"http://your_redirect_url/callback"}, 128 ) 129 if err != nil { 130 // handle error 131 } 132 133 // Create a provider 134 p, err := oidc.NewProvider(pc) 135 if err != nil { 136 // handle error 137 } 138 defer p.Done() 139 140 // Create a Request for a user's authentication attempt that will use the 141 // authorization code flow. (See NewRequest(...) using the WithPKCE and 142 // WithImplicit options for creating a Request that uses those flows.) 143 oidcRequest, err := oidc.NewRequest(2*time.Minute, "http://your_redirect_url/callback") 144 if err != nil { 145 // handle error 146 } 147 148 // Create an auth URL 149 authURL, err := p.AuthURL(ctx, oidcRequest) 150 if err != nil { 151 // handle error 152 } 153 fmt.Println("open url to kick-off authentication: ", authURL) 154} 155 156func ExampleProvider_Exchange() { 157 ctx := context.Background() 158 159 // Create a new Config 160 pc, err := oidc.NewConfig( 161 "http://your-issuer.com/", 162 "your_client_id", 163 "your_client_secret", 164 []oidc.Alg{oidc.RS256}, 165 []string{"http://your_redirect_url"}, 166 ) 167 if err != nil { 168 // handle error 169 } 170 171 // Create a provider 172 p, err := oidc.NewProvider(pc) 173 if err != nil { 174 // handle error 175 } 176 defer p.Done() 177 178 // Create a Request for a user's authentication attempt that will use the 179 // authorization code flow. (See NewRequest(...) using the WithPKCE and 180 // WithImplicit options for creating a Request that uses those flows.) 181 oidcRequest, err := oidc.NewRequest(2*time.Minute, "http://your_redirect_url/callback") 182 if err != nil { 183 // handle error 184 } 185 186 // Create an auth URL 187 authURL, err := p.AuthURL(ctx, oidcRequest) 188 if err != nil { 189 // handle error 190 } 191 fmt.Println("open url to kick-off authentication: ", authURL) 192 193 // Create a http.Handler for OIDC authentication response redirects 194 callbackHandler := func(w http.ResponseWriter, r *http.Request) { 195 // Exchange a successful authentication's authorization code and 196 // authorization state (received in a callback) for a verified Token. 197 t, err := p.Exchange(ctx, oidcRequest, r.FormValue("state"), r.FormValue("code")) 198 if err != nil { 199 // handle error 200 } 201 var claims map[string]interface{} 202 if err := t.IDToken().Claims(&claims); err != nil { 203 // handle error 204 } 205 206 // Get the user's claims via the provider's UserInfo endpoint 207 var infoClaims map[string]interface{} 208 err = p.UserInfo(ctx, t.StaticTokenSource(), claims["sub"].(string), &infoClaims) 209 if err != nil { 210 // handle error 211 } 212 resp := struct { 213 IDTokenClaims map[string]interface{} 214 UserInfoClaims map[string]interface{} 215 }{claims, infoClaims} 216 enc := json.NewEncoder(w) 217 if err := enc.Encode(resp); err != nil { 218 // handle error 219 } 220 } 221 http.HandleFunc("/callback", callbackHandler) 222} 223 224func ExampleProvider_UserInfo() { 225 ctx := context.Background() 226 227 // Create a new Config 228 pc, err := oidc.NewConfig( 229 "http://your-issuer.com/", 230 "your_client_id", 231 "your_client_secret", 232 []oidc.Alg{oidc.RS256}, 233 []string{"http://your_redirect_url"}, 234 ) 235 if err != nil { 236 // handle error 237 } 238 239 // Create a provider 240 p, err := oidc.NewProvider(pc) 241 if err != nil { 242 // handle error 243 } 244 defer p.Done() 245 246 // Create a Request for a user's authentication attempt that will use the 247 // authorization code flow. (See NewRequest(...) using the WithPKCE and 248 // WithImplicit options for creating a Request that uses those flows.) 249 oidcRequest, err := oidc.NewRequest(2*time.Minute, "http://your_redirect_url/callback") 250 if err != nil { 251 // handle error 252 } 253 254 // Create an auth URL 255 authURL, err := p.AuthURL(ctx, oidcRequest) 256 if err != nil { 257 // handle error 258 } 259 fmt.Println("open url to kick-off authentication: ", authURL) 260 261 // Create a http.Handler for OIDC authentication response redirects 262 callbackHandler := func(w http.ResponseWriter, r *http.Request) { 263 // Exchange a successful authentication's authorization code and 264 // authorization state (received in a callback) for a verified Token. 265 t, err := p.Exchange(ctx, oidcRequest, r.FormValue("state"), r.FormValue("code")) 266 if err != nil { 267 // handle error 268 } 269 var claims map[string]interface{} 270 if err := t.IDToken().Claims(&claims); err != nil { 271 // handle error 272 } 273 274 // Get the user's claims via the provider's UserInfo endpoint 275 var infoClaims map[string]interface{} 276 err = p.UserInfo(ctx, t.StaticTokenSource(), claims["sub"].(string), &infoClaims) 277 if err != nil { 278 // handle error 279 } 280 resp := struct { 281 IDTokenClaims map[string]interface{} 282 UserInfoClaims map[string]interface{} 283 }{claims, infoClaims} 284 enc := json.NewEncoder(w) 285 if err := enc.Encode(resp); err != nil { 286 // handle error 287 } 288 } 289 http.HandleFunc("/callback", callbackHandler) 290} 291 292func ExampleNewRequest() { 293 // Create a Request for a user's authentication attempt that will use the 294 // authorization code flow. (See NewRequest(...) using the WithPKCE and 295 // WithImplicit options for creating a Request that uses those flows.) 296 ttl := 2 * time.Minute 297 oidcRequest, err := oidc.NewRequest(ttl, "http://your_redirect_url/callback") 298 if err != nil { 299 // handle error 300 } 301 fmt.Println(oidcRequest) 302 303 // Create a Request for a user's authentication attempt that will use the 304 // authorization code flow with PKCE 305 v, err := oidc.NewCodeVerifier() 306 if err != nil { 307 // handle error 308 } 309 oidcRequest, err = oidc.NewRequest(ttl, "http://your_redirect_url/callback", oidc.WithPKCE(v)) 310 if err != nil { 311 // handle error 312 } 313 fmt.Println(oidcRequest) 314 315 // Create a Request for a user's authentication attempt that will use the 316 // implicit flow. 317 oidcRequest, err = oidc.NewRequest(ttl, "http://your_redirect_url/callback", oidc.WithImplicitFlow()) 318 if err != nil { 319 // handle error 320 } 321 fmt.Println(oidcRequest) 322 323 // Create a Request for a user's authentication attempt that will use the 324 // authorization code flow and require a auth_time with a max_age of 0 325 // seconds. 326 ttl = 2 * time.Minute 327 oidcRequest, err = oidc.NewRequest(ttl, "http://your_redirect_url/callback", oidc.WithMaxAge(0)) 328 if err != nil { 329 // handle error 330 } 331 fmt.Println(oidcRequest) 332} 333