9898 // stsEnabled determines if STS token exchange should be performed
9999 stsEnabled bool
100100
101+ // clientID and clientSecret for static client credentials
102+ clientID string
103+ clientSecret string
104+
101105 // The local address our application will run on to handle the redirect.
102106 redirectHost = "http://127.0.0.1:8080"
103107 redirectPath = "/auth/callback"
@@ -118,15 +122,23 @@ var (
118122// --- Main Application Logic ---
119123
120124func main () {
121- // Setup and parse the -idp flag for the issuer URL .
125+ // Setup and parse the flags .
122126 flag .StringVar (& issuerURL , "idp" , "" , "The issuer URL of the OpenID Connect provider (e.g., https://accounts.google.com)" )
123127 flag .BoolVar (& stsEnabled , "sts" , false , "Enable STS token exchange using urn:ietf:params:oauth:grant-type:token-exchange" )
128+ flag .StringVar (& clientID , "client_id" , "" , "Static client ID (if not provided, will use dynamic client registration)" )
129+ flag .StringVar (& clientSecret , "client_secret" , "" , "Static client secret (if not provided, will use dynamic client registration)" )
124130 flag .Parse ()
125131 if issuerURL == "" {
126132 fmt .Println ("Error: The -idp flag is required. Please provide the issuer URL of your OIDC provider." )
127133 os .Exit (1 )
128134 }
129135
136+ // Validate that both client_id and client_secret are provided together or neither
137+ if (clientID == "" ) != (clientSecret == "" ) {
138+ fmt .Println ("Error: Both -client_id and -client_secret must be provided together, or neither should be provided." )
139+ os .Exit (1 )
140+ }
141+
130142 ctx := context .Background ()
131143
132144 // Step 1: Fetch provider metadata from .well-known/openid-configuration
@@ -139,14 +151,25 @@ func main() {
139151 }
140152 fmt .Printf ("✅ Success. Authorization Endpoint: %s\n " , providerMetadata .AuthorizationEndpoint )
141153
142- // Step 2: Register a new client using Dynamic Client Registration
143- fmt .Println ("\n Step 2: Dynamically registering a new client..." )
144- clientCreds , err = registerDynamicClient (ctx , providerMetadata .RegistrationEndpoint )
145- if err != nil {
146- fmt .Printf ("Failed to register dynamic client: %v. \n NOTE: Your provider might not support Dynamic Client Registration. If so, configure client_id/secret manually." , err )
147- os .Exit (1 )
154+ // Step 2: Setup client credentials (either static or dynamic registration)
155+ if clientID != "" && clientSecret != "" {
156+ // Use static client credentials
157+ fmt .Println ("\n Step 2: Using provided client credentials..." )
158+ clientCreds = & ClientCredentials {
159+ ClientID : clientID ,
160+ ClientSecret : clientSecret ,
161+ }
162+ fmt .Printf ("✅ Success. Using Client ID: %s\n " , clientCreds .ClientID )
163+ } else {
164+ // Register a new client using Dynamic Client Registration
165+ fmt .Println ("\n Step 2: Dynamically registering a new client..." )
166+ clientCreds , err = registerDynamicClient (ctx , providerMetadata .RegistrationEndpoint )
167+ if err != nil {
168+ fmt .Printf ("Failed to register dynamic client: %v. \n NOTE: Your provider might not support Dynamic Client Registration. If so, configure client_id/secret manually using -client_id and -client_secret flags." , err )
169+ os .Exit (1 )
170+ }
171+ fmt .Printf ("✅ Success. Registered Client ID: %s\n " , clientCreds .ClientID )
148172 }
149- fmt .Printf ("✅ Success. Registered Client ID: %s\n " , clientCreds .ClientID )
150173
151174 // Step 3: Generate Authorization URL and attempt automated fetch.
152175 fmt .Println ("\n Step 3: Awaiting user authorization..." )
0 commit comments