github.com/gravitational/teleport/api@v0.0.0-20240507183017-3110591cbafc/types/saml.go (about) 1 /* 2 Copyright 2020-2021 Gravitational, Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package types 18 19 import ( 20 "slices" 21 "strings" 22 "time" 23 24 "github.com/gravitational/trace" 25 "golang.org/x/crypto/ssh" 26 27 "github.com/gravitational/teleport/api/constants" 28 "github.com/gravitational/teleport/api/defaults" 29 "github.com/gravitational/teleport/api/utils" 30 ) 31 32 // SAMLConnector specifies configuration for SAML 2.0 identity providers 33 type SAMLConnector interface { 34 // ResourceWithSecrets provides common methods for objects 35 ResourceWithSecrets 36 ResourceWithOrigin 37 38 // SetMetadata sets the connector metadata 39 SetMetadata(Metadata) 40 // GetDisplay returns display - friendly name for this provider. 41 GetDisplay() string 42 // SetDisplay sets friendly name for this provider. 43 SetDisplay(string) 44 // GetAttributesToRoles returns attributes to roles mapping 45 GetAttributesToRoles() []AttributeMapping 46 // SetAttributesToRoles sets attributes to roles mapping 47 SetAttributesToRoles(mapping []AttributeMapping) 48 // GetAttributes returns list of attributes expected by mappings 49 GetAttributes() []string 50 // GetTraitMappings converts gets all attribute mappings in the 51 // generic trait mapping format. 52 GetTraitMappings() TraitMappingSet 53 // SetIssuer sets issuer 54 SetIssuer(issuer string) 55 // GetIssuer returns issuer 56 GetIssuer() string 57 // GetSigningKeyPair returns signing key pair 58 GetSigningKeyPair() *AsymmetricKeyPair 59 // GetSigningKeyPair sets signing key pair 60 SetSigningKeyPair(k *AsymmetricKeyPair) 61 // GetSSO returns SSO service 62 GetSSO() string 63 // SetSSO sets SSO service 64 SetSSO(string) 65 // GetEntityDescriptor returns XML entity descriptor of the service 66 GetEntityDescriptor() string 67 // SetEntityDescriptor sets entity descriptor of the service 68 SetEntityDescriptor(v string) 69 // GetEntityDescriptorURL returns the URL to obtain the entity descriptor. 70 GetEntityDescriptorURL() string 71 // SetEntityDescriptorURL sets the entity descriptor url. 72 SetEntityDescriptorURL(string) 73 // GetCert returns identity provider checking x509 certificate 74 GetCert() string 75 // SetCert sets identity provider checking certificate 76 SetCert(string) 77 // GetServiceProviderIssuer returns service provider issuer 78 GetServiceProviderIssuer() string 79 // SetServiceProviderIssuer sets service provider issuer 80 SetServiceProviderIssuer(v string) 81 // GetAudience returns audience 82 GetAudience() string 83 // SetAudience sets audience 84 SetAudience(v string) 85 // GetAssertionConsumerService returns assertion consumer service URL 86 GetAssertionConsumerService() string 87 // SetAssertionConsumerService sets assertion consumer service URL 88 SetAssertionConsumerService(v string) 89 // GetProvider returns the identity provider. 90 GetProvider() string 91 // SetProvider sets the identity provider. 92 SetProvider(string) 93 // GetEncryptionKeyPair returns the key pair for SAML assertions. 94 GetEncryptionKeyPair() *AsymmetricKeyPair 95 // SetEncryptionKeyPair sets the key pair for SAML assertions. 96 SetEncryptionKeyPair(k *AsymmetricKeyPair) 97 // GetAllowIDPInitiated returns whether the identity provider can initiate a login or not. 98 GetAllowIDPInitiated() bool 99 // SetAllowIDPInitiated sets whether the identity provider can initiate a login or not. 100 SetAllowIDPInitiated(bool) 101 } 102 103 // NewSAMLConnector returns a new SAMLConnector based off a name and SAMLConnectorSpecV2. 104 func NewSAMLConnector(name string, spec SAMLConnectorSpecV2) (SAMLConnector, error) { 105 o := &SAMLConnectorV2{ 106 Metadata: Metadata{ 107 Name: name, 108 }, 109 Spec: spec, 110 } 111 if err := o.CheckAndSetDefaults(); err != nil { 112 return nil, trace.Wrap(err) 113 } 114 return o, nil 115 } 116 117 // GetVersion returns resource version 118 func (o *SAMLConnectorV2) GetVersion() string { 119 return o.Version 120 } 121 122 // GetKind returns resource kind 123 func (o *SAMLConnectorV2) GetKind() string { 124 return o.Kind 125 } 126 127 // GetSubKind returns resource sub kind 128 func (o *SAMLConnectorV2) GetSubKind() string { 129 return o.SubKind 130 } 131 132 // SetSubKind sets resource subkind 133 func (o *SAMLConnectorV2) SetSubKind(sk string) { 134 o.SubKind = sk 135 } 136 137 // GetResourceID returns resource ID 138 func (o *SAMLConnectorV2) GetResourceID() int64 { 139 return o.Metadata.ID 140 } 141 142 // SetResourceID sets resource ID 143 func (o *SAMLConnectorV2) SetResourceID(id int64) { 144 o.Metadata.ID = id 145 } 146 147 // GetRevision returns the revision 148 func (o *SAMLConnectorV2) GetRevision() string { 149 return o.Metadata.GetRevision() 150 } 151 152 // SetRevision sets the revision 153 func (o *SAMLConnectorV2) SetRevision(rev string) { 154 o.Metadata.SetRevision(rev) 155 } 156 157 // WithoutSecrets returns an instance of resource without secrets. 158 func (o *SAMLConnectorV2) WithoutSecrets() Resource { 159 k1 := o.GetSigningKeyPair() 160 k2 := o.GetEncryptionKeyPair() 161 o2 := *o 162 if k1 != nil { 163 q1 := *k1 164 q1.PrivateKey = "" 165 o2.SetSigningKeyPair(&q1) 166 } 167 if k2 != nil { 168 q2 := *k2 169 q2.PrivateKey = "" 170 o2.SetEncryptionKeyPair(&q2) 171 } 172 return &o2 173 } 174 175 // GetServiceProviderIssuer returns service provider issuer 176 func (o *SAMLConnectorV2) GetServiceProviderIssuer() string { 177 return o.Spec.ServiceProviderIssuer 178 } 179 180 // SetServiceProviderIssuer sets service provider issuer 181 func (o *SAMLConnectorV2) SetServiceProviderIssuer(v string) { 182 o.Spec.ServiceProviderIssuer = v 183 } 184 185 // GetAudience returns audience 186 func (o *SAMLConnectorV2) GetAudience() string { 187 return o.Spec.Audience 188 } 189 190 // SetAudience sets audience 191 func (o *SAMLConnectorV2) SetAudience(v string) { 192 o.Spec.Audience = v 193 } 194 195 // GetCert returns identity provider checking x509 certificate 196 func (o *SAMLConnectorV2) GetCert() string { 197 return o.Spec.Cert 198 } 199 200 // SetCert sets identity provider checking certificate 201 func (o *SAMLConnectorV2) SetCert(cert string) { 202 o.Spec.Cert = cert 203 } 204 205 // GetSSO returns SSO service 206 func (o *SAMLConnectorV2) GetSSO() string { 207 return o.Spec.SSO 208 } 209 210 // SetSSO sets SSO service 211 func (o *SAMLConnectorV2) SetSSO(sso string) { 212 o.Spec.SSO = sso 213 } 214 215 // GetEntityDescriptor returns XML entity descriptor of the service 216 func (o *SAMLConnectorV2) GetEntityDescriptor() string { 217 return o.Spec.EntityDescriptor 218 } 219 220 // SetEntityDescriptor sets entity descriptor of the service 221 func (o *SAMLConnectorV2) SetEntityDescriptor(v string) { 222 o.Spec.EntityDescriptor = v 223 } 224 225 // GetEntityDescriptorURL returns the URL to obtain the entity descriptor. 226 func (o *SAMLConnectorV2) GetEntityDescriptorURL() string { 227 return o.Spec.EntityDescriptorURL 228 } 229 230 // SetEntityDescriptorURL sets the entity descriptor url. 231 func (o *SAMLConnectorV2) SetEntityDescriptorURL(v string) { 232 o.Spec.EntityDescriptorURL = v 233 } 234 235 // GetAssertionConsumerService returns assertion consumer service URL 236 func (o *SAMLConnectorV2) GetAssertionConsumerService() string { 237 return o.Spec.AssertionConsumerService 238 } 239 240 // SetAssertionConsumerService sets assertion consumer service URL 241 func (o *SAMLConnectorV2) SetAssertionConsumerService(v string) { 242 o.Spec.AssertionConsumerService = v 243 } 244 245 // SetDisplay sets friendly name for this provider. 246 func (o *SAMLConnectorV2) SetDisplay(display string) { 247 o.Spec.Display = display 248 } 249 250 // GetMetadata returns object metadata 251 func (o *SAMLConnectorV2) GetMetadata() Metadata { 252 return o.Metadata 253 } 254 255 // SetMetadata sets object metadata 256 func (o *SAMLConnectorV2) SetMetadata(m Metadata) { 257 o.Metadata = m 258 } 259 260 // Origin returns the origin value of the resource. 261 func (o *SAMLConnectorV2) Origin() string { 262 return o.Metadata.Origin() 263 } 264 265 // SetOrigin sets the origin value of the resource. 266 func (o *SAMLConnectorV2) SetOrigin(origin string) { 267 o.Metadata.SetOrigin(origin) 268 } 269 270 // SetExpiry sets expiry time for the object 271 func (o *SAMLConnectorV2) SetExpiry(expires time.Time) { 272 o.Metadata.SetExpiry(expires) 273 } 274 275 // Expiry returns object expiry setting 276 func (o *SAMLConnectorV2) Expiry() time.Time { 277 return o.Metadata.Expiry() 278 } 279 280 // GetName returns the name of the connector 281 func (o *SAMLConnectorV2) GetName() string { 282 return o.Metadata.GetName() 283 } 284 285 // SetName sets client secret to some value 286 func (o *SAMLConnectorV2) SetName(name string) { 287 o.Metadata.SetName(name) 288 } 289 290 // SetIssuer sets issuer 291 func (o *SAMLConnectorV2) SetIssuer(issuer string) { 292 o.Spec.Issuer = issuer 293 } 294 295 // GetIssuer returns issuer 296 func (o *SAMLConnectorV2) GetIssuer() string { 297 return o.Spec.Issuer 298 } 299 300 // GetDisplay returns the friendly name for this provider. 301 func (o *SAMLConnectorV2) GetDisplay() string { 302 if o.Spec.Display != "" { 303 return o.Spec.Display 304 } 305 return o.GetName() 306 } 307 308 // GetAttributesToRoles returns attributes to roles mapping 309 func (o *SAMLConnectorV2) GetAttributesToRoles() []AttributeMapping { 310 return o.Spec.AttributesToRoles 311 } 312 313 // SetAttributesToRoles sets attributes to roles mapping 314 func (o *SAMLConnectorV2) SetAttributesToRoles(mapping []AttributeMapping) { 315 o.Spec.AttributesToRoles = mapping 316 } 317 318 // SetProvider sets the identity provider. 319 func (o *SAMLConnectorV2) SetProvider(identityProvider string) { 320 o.Spec.Provider = identityProvider 321 } 322 323 // GetProvider returns the identity provider. 324 func (o *SAMLConnectorV2) GetProvider() string { 325 return o.Spec.Provider 326 } 327 328 // GetAttributes returns list of attributes expected by mappings 329 func (o *SAMLConnectorV2) GetAttributes() []string { 330 var out []string 331 for _, mapping := range o.Spec.AttributesToRoles { 332 out = append(out, mapping.Name) 333 } 334 return utils.Deduplicate(out) 335 } 336 337 // GetTraitMappings returns the SAMLConnector's TraitMappingSet 338 func (o *SAMLConnectorV2) GetTraitMappings() TraitMappingSet { 339 tms := make([]TraitMapping, 0, len(o.Spec.AttributesToRoles)) 340 for _, mapping := range o.Spec.AttributesToRoles { 341 tms = append(tms, TraitMapping{ 342 Trait: mapping.Name, 343 Value: mapping.Value, 344 Roles: mapping.Roles, 345 }) 346 } 347 return TraitMappingSet(tms) 348 } 349 350 // GetSigningKeyPair returns signing key pair 351 func (o *SAMLConnectorV2) GetSigningKeyPair() *AsymmetricKeyPair { 352 return o.Spec.SigningKeyPair 353 } 354 355 // SetSigningKeyPair sets signing key pair 356 func (o *SAMLConnectorV2) SetSigningKeyPair(k *AsymmetricKeyPair) { 357 o.Spec.SigningKeyPair = k 358 } 359 360 // GetEncryptionKeyPair returns the key pair for SAML assertions. 361 func (o *SAMLConnectorV2) GetEncryptionKeyPair() *AsymmetricKeyPair { 362 return o.Spec.EncryptionKeyPair 363 } 364 365 // SetEncryptionKeyPair sets the key pair for SAML assertions. 366 func (o *SAMLConnectorV2) SetEncryptionKeyPair(k *AsymmetricKeyPair) { 367 o.Spec.EncryptionKeyPair = k 368 } 369 370 // GetAllowIDPInitiated returns whether the identity provider can initiate a login or not. 371 func (o *SAMLConnectorV2) GetAllowIDPInitiated() bool { 372 return o.Spec.AllowIDPInitiated 373 } 374 375 // SetAllowIDPInitiated sets whether the identity provider can initiate a login or not. 376 func (o *SAMLConnectorV2) SetAllowIDPInitiated(allow bool) { 377 o.Spec.AllowIDPInitiated = allow 378 } 379 380 // setStaticFields sets static resource header and metadata fields. 381 func (o *SAMLConnectorV2) setStaticFields() { 382 o.Kind = KindSAMLConnector 383 o.Version = V2 384 } 385 386 // CheckAndSetDefaults checks and sets default values 387 func (o *SAMLConnectorV2) CheckAndSetDefaults() error { 388 o.setStaticFields() 389 if err := o.Metadata.CheckAndSetDefaults(); err != nil { 390 return trace.Wrap(err) 391 } 392 393 if name := o.Metadata.Name; slices.Contains(constants.SystemConnectors, name) { 394 return trace.BadParameter("ID: invalid connector name, %v is a reserved name", name) 395 } 396 if o.Spec.AssertionConsumerService == "" { 397 return trace.BadParameter("missing acs - assertion consumer service parameter, set service URL that will receive POST requests from SAML") 398 } 399 if o.Spec.AllowIDPInitiated && !strings.HasSuffix(o.Spec.AssertionConsumerService, "/"+o.Metadata.Name) { 400 return trace.BadParameter("acs - assertion consumer service parameter must end with /%v when allow_idp_initiated is set to true, eg https://cluster.domain/webapi/v1/saml/acs/%v. Ensure this URI matches the one configured at the identity provider.", o.Metadata.Name, o.Metadata.Name) 401 } 402 if o.Spec.ServiceProviderIssuer == "" { 403 o.Spec.ServiceProviderIssuer = o.Spec.AssertionConsumerService 404 } 405 if o.Spec.Audience == "" { 406 o.Spec.Audience = o.Spec.AssertionConsumerService 407 } 408 // Issuer and SSO can be automatically set later if EntityDescriptor is provided 409 if o.Spec.EntityDescriptorURL == "" && o.Spec.EntityDescriptor == "" && (o.Spec.Issuer == "" || o.Spec.SSO == "") { 410 return trace.BadParameter("no entity_descriptor set, either provide entity_descriptor or entity_descriptor_url in spec") 411 } 412 // make sure claim mappings have either roles or a role template 413 for _, v := range o.Spec.AttributesToRoles { 414 if len(v.Roles) == 0 { 415 return trace.BadParameter("need roles field in attributes_to_roles") 416 } 417 } 418 return nil 419 } 420 421 // Check returns nil if all parameters are great, err otherwise 422 func (i *SAMLAuthRequest) Check() error { 423 if i.ConnectorID == "" { 424 return trace.BadParameter("ConnectorID: missing value") 425 } 426 if len(i.PublicKey) != 0 { 427 _, _, _, _, err := ssh.ParseAuthorizedKey(i.PublicKey) 428 if err != nil { 429 return trace.BadParameter("PublicKey: bad key: %v", err) 430 } 431 if (i.CertTTL > defaults.MaxCertDuration) || (i.CertTTL < defaults.MinCertDuration) { 432 return trace.BadParameter("CertTTL: wrong certificate TTL") 433 } 434 } 435 436 // we could collapse these two checks into one, but the error message would become ambiguous. 437 if i.SSOTestFlow && i.ConnectorSpec == nil { 438 return trace.BadParameter("ConnectorSpec cannot be nil when SSOTestFlow is true") 439 } 440 441 if !i.SSOTestFlow && i.ConnectorSpec != nil { 442 return trace.BadParameter("ConnectorSpec must be nil when SSOTestFlow is false") 443 } 444 445 return nil 446 }