Is a Security Token Service (STS) a standard component in security architectures to realize operations such as authentication, identity mapping, token validation and conversion. The concept of an STS comes from the OASIS specification WS-Trust which describes a secure model for establishing, managing and evaluating "trust" relationships between applications. The security model is mainly based on 3 players: consumer, provider and a Security Token Service (STS) where the STS is the most central player as it issues tokens that all providers can trust.
This
STS is available in FSS, users are authenticated to on-prem Active Directory.
This
STS does not perform any additional access control or role checks.
The service definitions are based on specifications in these references:
The OAuth 2.0 Authorization Framework
Starting point for .well-known endpoint
Test: https://security-token-service-t4.nais.preprod.local
Development: https://security-token-service.nais.preprod.local
Prod: https://security-token-service.nais.adeo.no
For local Development https://security-token-service.dev.adeo.no
is exposed in naisdevice
/api
Type | Endpoint |
---|---|
Retrieve public keys for validating the oidc token issued by STS | /jwks |
Configuration info | /.well-known/openid-configuration |
From | To | Endpoint | Extra |
---|---|---|---|
client_credentials | OIDC | /rest/v1/sts/token |
|
client_credentials | OIDC | /rest/v1/sts/token2 |
For Stormaskin |
client_credentials | SAML | /rest/v1/sts/samltoken |
|
OIDC (Issued by TokenX, This STS, AzureAD) |
SAML | /rest/v1/sts/token/exchange |
|
SAML token (Issued by STS(Datapower) or This STS) |
OIDC | /rest/v1/sts/token/exchange |
../rest/v1/sts/token
You send: Your srvUser credentials i Authorization header
You get: An OIDC-Token
with which you can make further actions.
Request:
POST /rest/v1/sts/token
HTTP/1.1
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Authorization: Basic aGVsbG86eW91
grant_type=client_credentials&
scope=openid
Successful Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token": "eY........",
"token_type": "Bearer",
"expires_in": 3600
}
The validity period of the token is specified in seconds. The OIDC token is a B64 URL-encoded JWT.
Failed Response:
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
"error": "invalid_client",
"error_description": "Unauthorised: Full authentication is required to access this resource"
}
HTTP/1.1 400 BadRequest
Content-Type: application/json
{
"error": "invalid_request",
"error_description": "Some message"
}
...rest/v1/sts/token/exchange
The service validates the received SAML token, generates a new OIDC token with content retrieved from the SAML token.
Request:
POST /rest/v1/sts/token/exchange
HTTP/1.1
Accept: application/x-www-form-urlencoded
Content-Type: application/x-www-form-urlencoded
Authorization: Basic aGVsbG86eW91
grant_type=urn:ietf:params:oauth:grant-type:token-exchange&
requested_token_type=urn:ietf:params:oauth:token-type:access_token&
subject_token_type=urn:ietf:params:oauth:token-type:saml2&
subject_token=BASE64URL encoded SAML token
Successful Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token": "eY........",
"issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
"token_type": "Bearer",
"expires_in": "30 sek more then expiry for SAML-tokenet"
}
Failed Response:
HTTP/1.1 400 BadRequest
Content-Type: application/json
{
"error": "invalid_request",
"error_description": "Some message"
}
The validity period of the token is specified in seconds. The OIDC token is a B64 URL-encoded JWT.
...rest/v1/sts/token/exchange
Request:
POST /rest/v1/sts/token/exchange
HTTP/1.1
Accept: application/x-www-form-urlencoded
Content-Type: application/x-www-form-urlencoded
Authorization: Basic aGVsbG86eW91
grant_type=urn:ietf:params:oauth:grant-type:token-exchange&
requested_token_type=urn:ietf:params:oauth:token-type:saml2&
subject_token_type=urn:ietf:params:oauth:token-type:access_token&
subject_token=BASE64URL encoded OIDC token
Successful Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token": "eY........",
"issued_token_type": "urn:ietf:params:oauth:token-type:saml2",
"token_type": "Bearer",
"expires_in": "expiry for SAML-token"
}
Failed Response:
HTTP/1.1 400 BadRequest
Content-Type: application/json
{
"error": "invalid_request",
"error_description": "Some message"
}
Run GandalfApplicationLocal in test/kotlin/no/nav/gandalf
Runnable endpoints:
/rest/v1/sts/token
/rest/v1/sts/token2
/rest/v1/sts/token/exchange
/rest/v1/sts/samltoken
/.well-known/openid-configuration
/jwks
- Kotlin
- Nimbus
- Snyk
- Spring Boot
Plattformsikkerhet: youssef.bel.mekki@nav.no
++
Slack: #pig_sikkerhet
- Add more endpoints to be run local testing
- Expose
dev.adeo.no
for local development - Describe the Swagger Objects and values
- Refactoring of code for better readability