Titel ohne Applikationsname (Ausnahme: Bei Erwähnung in Komponentenname. Z.B. ZSR-Web)
Titel ohne Version bei fortlaufenden Dokumentationen (Ausnahme: Parallele Versionen der gleichen Komponentendokumentation wird publiziert).
| Release Information | 1.0 |
|---|---|
| Target audience | This documentation is intended for developers and system integrators which enable customer systems for interaction with the SASIS Register API. |
| Summary | The SASIS Register API is the public API to connect customer specific solutions to the SASIS register in a well structured an secured manner. |
Verwendung von Headings nach Standard-Paragraphen ohne Überschriftsnummern.
Code blocks werden mit dem Macro 'Code Block' dargestellt. Das Syntax Highlighting muss dem Inhalt entsprechend gewählt werden. Settings: collaps = true, linenumbers = true.
// C# program to print Hello World!
using System;
// namespace declaration
namespace HelloWorldApp {
// Class declaration
class Geeks {
// Main Method
static void Main(string[] args) {
// statement
// printing Hello World!
Console.WriteLine("Hello World!");
// To prevents the screen from
// running and closing quickly
Console.ReadKey();
}
}
} |
Folgende Info-Blöcke sollen für die beschriebenen Zwecke verwendet werden:
Info-Text für Informationen, welche hervorgehoben werden müssen. |
Weiterführende Informationen zu einem Thema werden in einer Notizbox erfasst. |
Muss der Leser auf eine bestimmte Gegebenheit besonders achten, so soll dies in einer Warnung dargestellt werden. |
Referenzen auf Attachments und andere Ressourcen können global im Panel rechts oben aufgelistet werden, aber auch eingebunden im Text:
<div class="references"> |
</div> |
Diagramme werden direkt als draw.io Inhalte im Confluence erfasst.
<div class="references"> |
Globale Referenzen für diese Dokumentationsseite: - Links auf Attachments der Seite, Display Text des Links entspricht normalerweise unverändert dem Namen des Attachments. Normalerweise soll die Confluence-Versionierung für Attachments verwendet werden (Ausnahme: Publikation von parallelen Versionen). - Links auf externe Seiten - Links auf andere Confluence-Einträge |
</div> |
API Specification
|
The SASIS Register API uses standard http status codes.
The following status codes will generally be used by the API:
| Status Code | Description |
|---|---|
| 200 | Success |
| 202 | Accepted; Request is valid and business process could be triggered successfully. |
| 400 | Bad Request; The request data is invalid. |
| 401 | Unauthorized; The caller does not have sufficient privileges to perform the call. |
| 403 | Forbidden; The server is refusing the action. |
| 500 | Internal Server Error; Any unexpected internal failure. |
|
|
The authentication is based on OpenID Connect, an identity layer on top of OAuth 2.0 and its corresponding flows/grants. For application integration, the resource owner password flow using the OAuth 2.0 password grant is to be used.
The SASIS IAM infrastructure acts a OpenID provider / auth server.

'Authorization: Bearer <access token>''Authorization: Bearer <access token>'The access token response contains additional information:
{
"access_token": "MTQ0NjOkZmQ5OTM5NDE9ZTZjNGZmZjI3",
"refresh_token": "GEbRxBNZmQOTM0NjOkZ5NDE9ZedjnXbL",
"token_type": "bearer",
"expires_in": 300,
"scope": "openid profile email offline_access roles c1s_profile cpr"
} |
The token itself is a JWT and can therefore be decoded on the JWT website.
The expires_in field defines the validity period of the token in seconds. Afterwards, a new token must be retrieved.
A complete c# sample shows how to access one specific API resource (numbers):
<div class="references"> |
</div> |
Authentication in other languages follows the same procedure.
The following code snippets explain the procedure on a step-by-step basis:
/// <summary>
/// Loads the IAM configuration.
/// </summary>
private async Task<DiscoveryResponse> GetDiscoveryDocumentAsync(CancellationToken ct)
{
using (var client = new HttpClient())
{
var discoveryResponse = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
{
Address = "[AuthorityUrl]"
}, ct).ConfigureAwait(false);
if (discoveryResponse.IsError)
throw new Exception(discoveryResponse.Error);
return discoveryResponse;
}
} |
/// <summary>
/// Gets a new token response with a username and password.
/// </summary>
private async Task<TokenResponse> RequestTokenAsync(CancellationToken ct)
{
using (var client = new HttpClient())
{
var discoveryResponse = await GetDiscoveryDocumentAsync(ct).ConfigureAwait(false);
var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
{
ClientId = "[ClientId]",
ClientSecret = "[ClientSecret]",
UserName = "[UserName]",
Password = "[Password]",
Address = discoveryResponse.TokenEndpoint,
GrantType = OidcConstants.GrantTypes.Password,
Scope = string.Join(" ", _scopes),
}, ct).ConfigureAwait(false);
if (tokenResponse.IsError)
throw new Exception(tokenResponse.Error);
return tokenResponse;
}
} |
/// <summary>
/// Gets the access token by either requesting a new token or by using the refresh token of an already existing token.
/// </summary>
private async Task<string> GetAccessTokenAsync(CancellationToken ct)
{
if (_tokenResponse == null)
{
// Creates a new token response
_tokenResponse = await RequestTokenAsync(ct).ConfigureAwait(false);
}
else
{
var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
// Parses JWT access token
var jwtSecurityToken = jwtSecurityTokenHandler.ReadToken(_tokenResponse.AccessToken) as JwtSecurityToken;
// The access token might be valid now, but expired the very next millisecond.
// Thus, add a reasonable reserve in minutes for the validity time comparison below.
var comparisionCorrectionInMinutes = 1;
// Compares the access token life time with the current time, modified by the comparison correction value.
if (jwtSecurityToken.ValidTo < DateTime.UtcNow.AddMinutes(comparisionCorrectionInMinutes))
{
// Updates the existing token response
_tokenResponse = await RefreshTokenAsync(_tokenResponse.RefreshToken, ct).ConfigureAwait(false);
}
}
return _tokenResponse.AccessToken;
}
/// <summary>
/// Gets an updated token response by using a refresh token.
/// </summary>
private async Task<TokenResponse> RefreshTokenAsync(string refreshToken, CancellationToken ct)
{
using (var client = new HttpClient())
{
var discoveryResponse = await GetDiscoveryDocumentAsync(ct).ConfigureAwait(false);
var tokenResponse = await client.RequestTokenAsync(new TokenRequest
{
ClientId = "[ClientId]",
ClientSecret = "[ClientSecret]",
Address = discoveryResponse.TokenEndpoint,
ClientCredentialStyle = ClientCredentialStyle.AuthorizationHeader,
GrantType = OidcConstants.GrantTypes.RefreshToken,
Parameters =
{
{ "refresh_token", refreshToken },
{ "scope", string.Join(" ", _scopes) }
}
});
if (tokenResponse.IsError)
throw new Exception(tokenResponse.Error);
return tokenResponse;
}
}
|
/// <summary>
/// A simple CPR API number search request.
/// </summary>
private async Task<BulkResponse> CprApiSampleRequestAsync(string accessToken, CancellationToken ct)
{
BulkResponse bulkResponse = new BulkResponse();
using (var client = new HttpClient())
{
client.SetBearerToken(accessToken);
var response = await client.GetAsync($"https://[CprBaseUrl]/ApiGateway/api/v1/numbers?searchOptions=Okp&offset=0&limit=10", ct).ConfigureAwait(false);
if (!response.IsSuccessStatusCode)
throw new Exception("There was a problem with the request");
string content = await response.Content.ReadAsStringAsync();
if (content != null && content.Length > 0)
{
bulkResponse = JsonConvert.DeserializeObject<BulkResponse>(content);
}
}
return bulkResponse;
} |
var accessToken = await GetAccessTokenAsync(ct).ConfigureAwait(false);
var cprApiResponse = await CprApiSampleRequestAsync(accessToken, ct).ConfigureAwait(false); |
| Setting | Test Environment | Live Environment |
|---|---|---|
| AuthorityUrl | https://sas-auth.itsense.ch | https://openid.santesuisse.com |
| CprBaseUrl | https://stagecurrent.zsrnext.ch/ | https://www.zsrnext.ch |
| ClientId | 1) | 1) |
| ClientSecret | 1) | 1) |
| UserName | 1) | 1) |
| Password | 1) | 1) |
1) To be provided individually by SASIS. Please contact: support@sasis.ch