User
Identifying an end user in UI/SSO scenarios — who is this person?
Authentication in the Untis Platform covers three distinct concerns depending on who is making the request.
User
Identifying an end user in UI/SSO scenarios — who is this person?
Application
Identifying your backend for server-to-server API access — which application is making this request?
Request
Verifying that an incoming webhook actually came from Untis Platform — is this request legitimate?
What a token allows you to access (scopes and permissions) is a separate concern — see Authorization Model.
User sign-in uses OpenID Connect Authorization Code flow. For platform applications, Untis Platform acts as the identity provider — users authenticate with Untis Platform and your app receives tokens to establish a session.
| Flow | OIDC Authorization Code |
| Authorize endpoint | v3 authorize endpoint |
| Token endpoint | v3 token endpoint |
| API version | v3 only — earlier endpoints not supported |
Server-to-server integrations obtain access tokens using the OAuth Client Credentials grant.
| Flow | OAuth Client Credentials |
| Token endpoint | v3 token endpoint with grant_type=client_credentials |
| Auth method | Basic Auth — username = OIDC client ID, password = platform-generated password (not the OIDC client secret) |
| Token lifetime | Short-lived (3 minutes) — use expires_in and cache tokens |
The OneRosterClient handles token acquisition via the Client Credentials grant internally. Construct it with the tenant ID, client ID, and platform-generated password — the token is fetched and applied automatically.
8 collapsed lines
import org.springframework.http.HttpHeaders;import org.springframework.http.MediaType;import org.springframework.util.LinkedMultiValueMap;import org.springframework.util.MultiValueMap;import org.springframework.web.client.RestClient;import java.nio.charset.StandardCharsets;import java.util.Base64;import java.util.Map;
public class OneRosterClient {
private static final String API_URL = "https://api.integration.webuntis.dev";
private final RestClient http;
public OneRosterClient(String tenantId, String clientId, String password) { String accessToken = fetchAccessToken(tenantId, clientId, password); this.http = RestClient.builder() .baseUrl(API_URL) .defaultHeader(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken) .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) .build(); }
private String fetchAccessToken(String tenantId, String clientId, String password) { String credentials = Base64.getEncoder() .encodeToString((clientId + ":" + password).getBytes(StandardCharsets.UTF_8));
MultiValueMap<String, String> form = new LinkedMultiValueMap<>(); form.add("grant_type", "client_credentials");
Map<String, Object> response = RestClient.create().post() .uri(API_URL + "/WebUntis/api/sso/v3/" + tenantId + "/token") .header(HttpHeaders.AUTHORIZATION, "Basic " + credentials) .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE) .body(form) .retrieve() .body(Map.class);
if (response == null || !(response.get("access_token") instanceof String token)) { throw new IllegalStateException("Token endpoint did not return an access_token"); } return token; }}When Untis Platform calls your endpoints (webhooks), requests are authenticated via RSA request signing — not OAuth tokens. Your endpoint must verify the signature on every incoming request.
| Method | RSA request signing |
| Direction | Untis Platform → Your App |
| Required action | Verify signature before processing any webhook payload |