SaaSアプリケーションへの多要素認証(MFA)の実装サンプルについて説明します。
それぞれのAPIの詳細はAPIドキュメントをご確認ください。
MFAの実装サンプル
1.フロントエンド実装
1.1.追加コンポーネント
MFAの認証設定を管理するために、以下のコンポーネントを追加。
1.1.1.MFA設定ダイアログ
- Reactの実装サンプル
→ ユーザーがMFAを有効化・無効化し、MFAのステータスを確認するダイアログコンポーネント。
1.1.2.ヘッダーユーザーメニュー
- Reactの実装サンプル
→ ユーザーメニュー内にMFA設定ダイアログを開くための項目を追加。
1.2.実装サンプルの使い方
2.バックエンド実装
MFA機能を実装するために、以下のエンドポイントを追加しました。
2.1.追加したエンドポイント
2.1.1.MFA設定取得API
- Go
- Python
- Java
- C#(.Net8)
- C#(.Netfw4.8)
e.GET("/mfa_status", getMfaStatus, authMiddleware)
// MFAの状態を取得 (有効/無効の確認)
func getMfaStatus(c echo.Context) error {
// コンテキストからユーザー情報を取得
userInfo, ok := c.Get(string(ctxlib.UserInfoKey)).(*authapi.UserInfo)
if !ok {
c.Logger().Error("Failed to get user info")
return c.JSON(http.StatusInternalServerError, map[string]string{"error": "Failed to retrieve user information"})
}
// SaaSus の API を使用してユーザーの MFA 設定を取得
response, err := authClient.GetUserMfaPreferenceWithResponse(context.Background(), userInfo.Id)
if err != nil || response.JSON200 == nil {
c.Logger().Errorf("failed to get MFA status: %v", err)
return c.JSON(http.StatusInternalServerError, map[string]string{"error": "Failed to retrieve MFA status"})
}
// MFA の有効/無効の状態を返す
return c.JSON(http.StatusOK, map[string]bool{"enabled": response.JSON200.Enabled})
}
@app.get("/mfa_status")
# MFAの状態を取得
def get_mfa_status(auth_user: dict = Depends(fastapi_auth), request: Request = None):
try:
# SaaSus の API を使用してユーザーの MFA 設定を取得
response = SaasUserApi(api_client=api_client).get_user_mfa_preference(user_id=auth_user.id)
# MFA の有効/無効の状態を返す
return {"enabled": response.enabled}
except Exception as e:
print(e)
raise HTTPException(status_code=500, detail=str(e))
@GetMapping(value = "/mfa_status", produces = "application/json")
/**
* MFAの状態を取得 (有効/無効の確認)
*/
public ResponseEntity<?> getMfaStatus(HttpServletRequest request) {
try {
// SaaSus APIクライアントを初期化
AuthApiClient apiClient = new Configuration().getAuthApiClient();
apiClient.setReferer(request.getHeader("X-Saasus-Referer"));
// ユーザー情報を取得
UserInfoApi userInfoApi = new UserInfoApi(apiClient);
UserInfo userInfo = userInfoApi.getUserInfo(getIDToken(request));
// MFAの有効状態を取得
SaasUserApi saasUserApi = new SaasUserApi(apiClient);
Boolean enabled = saasUserApi.getUserMfaPreference(userInfo.getId()).getEnabled();
Map<String, Boolean> result = new HashMap<>();
result.put("enabled", enabled);
return ResponseEntity.ok(result);
} catch (ApiException e) {
System.err.println("API Exception: " + e.getMessage());
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage(), e);
} catch (Exception e) {
System.err.println("Unexpected Exception: " + e.getMessage());
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage(), e);
}
}
app.MapGet("/mfa_status")
app.MapGet("/mfa_status", async (HttpContext context) =>
{
// AuthorizationヘッダーからBearerトークンを取得
var token = GetBearerToken(context);
if (string.IsNullOrEmpty(token))
{
return Results.Unauthorized();
}
try
{
// APIクライアントを初期化し、ユーザー情報を取得
var authApiClientConfig = CreateClientConfiguration(c => c.GetAuthApiClientConfig(), context);
var userInfoApi = new UserInfoApi(authApiClientConfig);
var userInfo = await userInfoApi.GetUserInfoAsync(token);
// MFAステータスを取得
var saasUserApi = new SaasUserApi(authApiClientConfig);
var mfaPref = await saasUserApi.GetUserMfaPreferenceAsync(userInfo.Id);
// JSON形式で返却
return Results.Json(new { enabled = mfaPref.Enabled });
}
catch (Exception ex)
{
return HandleApiException(ex);
}
});
[HttpGet, Route("mfa_status")]
// MFA ステータス確認エンドポイント
public async Task<IHttpActionResult> GetMfaStatus()
{
try
{
// IDトークン(Bearerトークン)を取得
var token = GetBearerToken(Request);
// 認証APIクライアントを初期化
var authApiClientConfig = CreateClientConfiguration(c => c.GetAuthApiClientConfig());
// ユーザー情報を取得
var userInfoApi = new UserInfoApi(authApiClientConfig);
var userInfo = await userInfoApi.GetUserInfoAsync(token);
// MFA設定を取得
var saasUserApi = new SaasUserApi(authApiClientConfig);
var mfaPref = await saasUserApi.GetUserMfaPreferenceAsync(userInfo.Id);
// MFAの有効状態を返す
return Ok(new { enabled = mfaPref.Enabled });
}
catch (Exception ex)
{
return HandleApiException(ex);
}
}