@@ -45,6 +45,7 @@ func main() {
4545 " passcode Retrieve user passcode from X509 user authentication. Need user_tls for user authentication.\n " +
4646 " idp_token Retrieve trusted IdP token. Need assertion for user trust and client authentication.\n " +
4747 " introspect Perform OAuth2 Introspection Endpoint Call. Need token input parameter.\n " +
48+ " sso Perform sso token flow to create a new web session in IAS.\n " +
4849 " version Show version.\n " +
4950 " help Show this help for more details.\n " +
5051 "\n " +
@@ -85,6 +86,10 @@ func main() {
8586 " -subject_type Token-Exchange subject type. Type of input assertion.\n " +
8687 " -resource Token-Exchange custom resource parameter.\n " +
8788 " -requested_type Token-Exchange requested type.\n " +
89+ " -redirect_uri Redirect URL for the sso command only.\n " +
90+ " -sp Service provider name parameter for sso command only.\n " +
91+ " -sso Token-Exchange resource SSO flow. Set true to get static parameter resource=urn:sap:identity:sso. Useful only in token-exchange.\n " +
92+ " -sso_token Opaque one time token to create a web session in IAS. Useful only in commands sso and authorization_code.\n " +
8893 " -provider_name Provider name for token-exchange.\n " +
8994 " -k Skip TLS server certificate verification and skip OIDC issuer check from well-known.\n " +
9095 " -v Verbose. Show more details about calls.\n " +
@@ -129,8 +134,12 @@ func main() {
129134 var subjectType = flag .String ("subject_type" , "" , "Token input type" )
130135 var requestedType = flag .String ("requested_type" , "" , "Token-Exchange requested type" )
131136 var providerName = flag .String ("provider_name" , "" , "Provider name for token-exchange" )
137+ var redirectUri = flag .String ("redirect_uri" , "" , "Redirect URL for sso" )
138+ var resourceSso = flag .Bool ("sso" , false , "Adds static parameter resource=urn:sap:identity:sso to token-exchange." )
132139 var resourceParam = flag .String ("resource" , "" , "Additional resource" )
133140 var skipTlsVerification = flag .Bool ("k" , false , "Skip TLS server certificate verification and issuer." )
141+ var ssoTokenValue = flag .String ("sso_token" , "" , "Opaque one time token for sso command." )
142+ var spName = flag .String ("sp" , "" , "Service provider name parameter for sso command only." )
134143 var mTLS = false
135144 var privateKeyJwt = ""
136145 var arguments []string
@@ -153,7 +162,7 @@ func main() {
153162 case "version" :
154163 showVersion ()
155164 return
156- case "client_credentials" , "password" , "token-exchange" , "jwt-bearer" , "saml-bearer" , "idp_token" , "" :
165+ case "client_credentials" , "password" , "token-exchange" , "jwt-bearer" , "saml-bearer" , "idp_token" , "sso" , " " :
157166 case "passcode" , "introspect" :
158167 * clientID = os .Getenv ("OPENID_ID" )
159168 if * clientID == "" {
@@ -380,7 +389,12 @@ func main() {
380389 originParam , _ := json .Marshal (originStruct )
381390 requestMap .Set ("login_hint" , url .QueryEscape (string (originParam )))
382391 }
383- if * providerName != "" {
392+ if * resourceSso {
393+ requestMap .Set ("resource" , "urn:sap:identity:sso" )
394+ requestMap .Set ("requested_token_type" , "urn:ietf:params:oauth:token-type:access_token" )
395+ // Set the requestedType to "access_token" so the caller knows which token type was requested.
396+ * requestedType = "access_token"
397+ } else if * providerName != "" {
384398 requestMap .Set ("resource" , "urn:sap:identity:application:provider:name:" + * providerName )
385399 }
386400 if * resourceParam != "" {
@@ -430,7 +444,7 @@ func main() {
430444 }
431445 }
432446 if * requestedType == "" {
433- log .Fatal ("assertion parameter not set. Needed to pass it to subject_token for token-exchange " )
447+ log .Fatal ("requested_type parameter not set. Supported parameters for token-exchange are, id_token, access_token, saml2, saml2-header " )
434448 } else {
435449 if strings .Contains (* requestedType , "saml2-header" ) || strings .Contains (* requestedType , "saml-header" ) {
436450 requestMap .Set ("requested_token_type" , "urn:sap:identity:oauth:token-type:saml2-header" )
@@ -509,6 +523,8 @@ func main() {
509523 requestMap .Del ("client_id" )
510524 }
511525 client .HandleTokenIntrospect (requestMap , * tokenInput , claims .IntroSpectEndpoint , * tlsClient , verbose )
526+ } else if * command == "sso" {
527+ client .HandleSsoFlow (* ssoTokenValue , * redirectUri , * spName , * provider )
512528 } else if * command == "jwks" {
513529 }
514530 } else {
@@ -522,7 +538,11 @@ func main() {
522538 if * maxAgeParameter != "" {
523539 requestMap .Set ("max_age" , * maxAgeParameter )
524540 }
525- var idToken , refreshToken = client .HandleOpenIDFlow (requestMap , verbose , callbackURL , * scopeParameter , * tokenFormatParameter , * portParameter , claims .EndSessionEndpoint , privateKeyJwt , * provider , * tlsClient )
541+ if * ssoTokenValue != "" {
542+ requestMap .Set ("sso_token" , * ssoTokenValue )
543+ }
544+ var bSilent = * resourceSso && ! verbose
545+ var idToken , refreshToken = client .HandleOpenIDFlow (requestMap , verbose , bSilent , callbackURL , * scopeParameter , * tokenFormatParameter , * portParameter , claims .EndSessionEndpoint , privateKeyJwt , * provider , * tlsClient )
526546 if * doRefresh {
527547 if refreshToken == "" {
528548 log .Println ("No refresh token received." )
@@ -550,6 +570,13 @@ func main() {
550570 }
551571 fmt .Println (string (data ))
552572 }
573+ if * resourceSso {
574+ // Set the requestedType to "access_token" so the caller knows which token type was requested.
575+ * requestedType = "access_token"
576+ * resourceParam = ""
577+ requestMap .Set ("resource" , "urn:sap:identity:sso" )
578+ requestMap .Set ("requested_token_type" , "urn:ietf:params:oauth:token-type:access_token" )
579+ }
553580 if * requestedType != "" && idToken != "" {
554581 requestMap .Set ("grant_type" , "urn:ietf:params:oauth:grant-type:token-exchange" )
555582 requestMap .Set ("subject_token_type" , "urn:ietf:params:oauth:token-type:id_token" )
@@ -567,7 +594,11 @@ func main() {
567594 }
568595
569596 var exchangedTokenResponse = client .HandleTokenExchangeGrant (requestMap , claims .TokenEndPoint , * tlsClient , verbose )
570- fmt .Println (exchangedTokenResponse )
597+ if exchangedTokenResponse .AccessToken != "" {
598+ fmt .Println (exchangedTokenResponse .AccessToken )
599+ } else {
600+ fmt .Println (exchangedTokenResponse .IdToken )
601+ }
571602 }
572603 if * doIntrospect && idToken != "" && claims .IntroSpectEndpoint != "" {
573604 requestMap := url.Values {}
0 commit comments