2FA¶
UCloud supports 2FA for all users using a TOTP backend.
Rationale¶
UCloud, for the most part, relies on the user’s organization to enforce best practices. UCloud can be configured to require additional factors of authentication via WAYF. On top of this UCloud allows you to optionally add TOTP based two-factor authentication.
https://cloud.sdu.dk uses this by enforcing 2FA of all users authenticated via the password backend.
Table of Contents¶
1. Examples
| Description |
|---|
| Creating 2FA credentials |
2. Remote Procedure Calls
| Name | Description |
|---|---|
answerChallenge |
Answers a challenge previously issued by createCredentials |
createCredentials |
Creates initial 2FA credentials and bootstraps a challenge for those credentials |
twoFactorStatus |
Retrieves the 2FA status of the currently authenticated user |
3. Data Models
| Name | Description |
|---|---|
AnswerChallengeRequest |
No description |
Create2FACredentialsResponse |
No description |
TwoFactorStatusResponse |
No description |
Example: Creating 2FA credentials¶
| Frequency of use | Common |
|---|---|
| Actors |
|
Communication Flow: Kotlin
TwoFactorAuthDescriptions.twoFactorStatus.call(
Unit,
user
).orThrow()
/*
TwoFactorStatusResponse(
connected = false,
)
*/
TwoFactorAuthDescriptions.createCredentials.call(
Unit,
user
).orThrow()
/*
Create2FACredentialsResponse(
challengeId = "CHALLENGE ID",
otpAuthUri = "OTP URI",
qrCodeB64Data = "QR CODE BASE64 ENCODED",
secret = "SECRET",
)
*/
TwoFactorAuthDescriptions.answerChallenge.call(
AnswerChallengeRequest(
challengeId = "CHALLENGE ID",
verificationCode = 999999,
),
user
).orThrow()
/*
Unit
*/
TwoFactorAuthDescriptions.twoFactorStatus.call(
Unit,
user
).orThrow()
/*
TwoFactorStatusResponse(
connected = true,
)
*/
Communication Flow: Curl
# ------------------------------------------------------------------------------------------------------
# $host is the UCloud instance to contact. Example: 'http://localhost:8080' or 'https://cloud.sdu.dk'
# $accessToken is a valid access-token issued by UCloud
# ------------------------------------------------------------------------------------------------------
# Authenticated as user
curl -XGET -H "Authorization: Bearer $accessToken" "$host/auth/2fa/status"
# {
# "connected": false
# }
curl -XPOST -H "Authorization: Bearer $accessToken" "$host/auth/2fa"
# {
# "otpAuthUri": "OTP URI",
# "qrCodeB64Data": "QR CODE BASE64 ENCODED",
# "secret": "SECRET",
# "challengeId": "CHALLENGE ID"
# }
curl -XPOST -H "Authorization: Bearer $accessToken" -H "Content-Type: content-type: application/json; charset=utf-8" "$host/auth/2fa/challenge" -d '{
"challengeId": "CHALLENGE ID",
"verificationCode": 999999
}'
# {
# }
curl -XGET -H "Authorization: Bearer $accessToken" "$host/auth/2fa/status"
# {
# "connected": true
# }
Communication Flow: Visual

Remote Procedure Calls¶
answerChallenge¶
Answers a challenge previously issued by createCredentials
| Request | Response | Error |
|---|---|---|
AnswerChallengeRequest |
Unit |
CommonErrorMessage |
createCredentials¶
Creates initial 2FA credentials and bootstraps a challenge for those credentials
| Request | Response | Error |
|---|---|---|
Unit |
Create2FACredentialsResponse |
CommonErrorMessage |
twoFactorStatus¶
Retrieves the 2FA status of the currently authenticated user
| Request | Response | Error |
|---|---|---|
Unit |
TwoFactorStatusResponse |
CommonErrorMessage |
Data Models¶
AnswerChallengeRequest¶
data class AnswerChallengeRequest(
val challengeId: String,
val verificationCode: Int,
)
Create2FACredentialsResponse¶
data class Create2FACredentialsResponse(
val otpAuthUri: String,
val qrCodeB64Data: String,
val secret: String,
val challengeId: String,
)
TwoFactorStatusResponse¶
data class TwoFactorStatusResponse(
val connected: Boolean,
)
Properties
connected: Boolean
Boolean