implementing-passwordless-auth-with-microsoft-entra について
組織向けのMicrosoft Entraパスワードレス認証導入ガイドです。FIDO2、Windows Hello for Business、ポリシー設定、展開、利用状況の監視を扱います。
主な機能
- 01認証方法の設定
- 02条件付きアクセス強度の設定
- 03IntuneによるWindows Hello展開
- 04TAPを使ったFIDO2キー登録
- 05パスワードレス利用状況の監視
活用シーン
- 01企業のパスワードレス移行計画
- 02フィッシング耐性MFAの必須化
- 03SMSや音声認証の置き換え
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill implementing-passwordless-auth-with-microsoft-entraインストール後、Claude Code で/implementing-passwordless-auth-with-microsoft-entraを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEreferences/api-reference.mdscripts/agent.py詳細
Microsoft Entra を使ったパスワードレス認証の実装
使用するタイミング
- 組織がパスワードを狙った攻撃(フィッシング、資格情報スタッフィング、総当たり攻撃)を排除したい場合
- 規制または社内規定でフィッシング耐性のある MFA が求められている場合(大統領令 14028、CISA のガイダンス)
- エンタープライズ全体で FIDO2 セキュリティキーまたは Windows Hello for Business を展開する場合
- レガシーな MFA(SMS、電話通話)からフィッシング耐性のある認証方式へ移行する場合
- ハイブリッドまたはクラウド参加型の Windows デバイスでパスキーをサポートする場合
- パスワードリセット依頼によるヘルプデスクのコストを削減したい場合
使用しないでください 最新の認証プロトコルをサポートできない環境では使用しないでください。NTLM や基本認証を使用するレガシーアプリケーションは、先に移行する必要があります。
前提条件
- Microsoft Entra ID P1 または P2 ライセンス(Azure AD Premium)
- Windows Hello for Business を展開する場合は Windows 10/11 22H2 以降
- FIDO2 準拠のセキュリティキー(YubiKey 5 Series、Feitian BioPass、Google Titan)
- iOS 16 以降/Android 14 以降でパスキーをサポートするための Microsoft Authenticator アプリ 6.8 以降
- Windows デバイス向けに構成されたハイブリッド Azure AD 参加または Azure AD 参加
- 認証強度のために構成された条件付きアクセスポリシー
ワークフロー
ステップ 1: 認証方法ポリシーを構成する
Microsoft Entra でパスワードレス認証方法を有効にします:
# Connect to Microsoft Graph
Connect-MgGraph -Scopes "Policy.ReadWrite.AuthenticationMethod", "User.ReadWrite.All"
# Enable FIDO2 Security Key authentication method
$fido2Policy = @{
"@odata.type" = "#microsoft.graph.fido2AuthenticationMethodConfiguration"
state = "enabled"
isAttestationEnforced = $true
isSelfServiceRegistrationAllowed = $true
keyRestrictions = @{
isEnforced = $true
enforcementType = "allow"
aaGuids = @(
"cb69481e-8ff7-4039-93ec-0a2729a154a8", # YubiKey 5 Series
"ee882879-721c-4913-9775-3dfcce97072a", # YubiKey 5 NFC
"fa2b99dc-9e39-4257-8f92-4a30d23c4118", # YubiKey 5C NFC
"2fc0579f-8113-47ea-b116-bb5a8db9202a", # YubiKey Bio
"73bb0cd4-e502-49b8-9c6f-b59445bf720b" # Google Titan
)
}
includeTargets = @(
@{
targetType = "group"
id = "all_users" # Or specific security group ID
}
)
}
Update-MgPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration `
-AuthenticationMethodConfigurationId "fido2" `
-BodyParameter $fido2Policy
# Enable Microsoft Authenticator with passkey support
$authenticatorPolicy = @{
"@odata.type" = "#microsoft.graph.microsoftAuthenticatorAuthenticationMethodConfiguration"
state = "enabled"
featureSettings = @{
displayAppInformationRequiredState = @{
state = "enabled"
includeTarget = @{
targetType = "group"
id = "all_users"
}
}
displayLocationInformationRequiredState = @{
state = "enabled"
includeTarget = @{
targetType = "group"
id = "all_users"
}
}
companionAppAllowedState = @{
state = "enabled"
}
}
includeTargets = @(
@{
targetType = "group"
id = "all_users"
authenticationMode = "any"
}
)
}
Update-MgPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration `
-AuthenticationMethodConfigurationId "microsoftAuthenticator" `
-BodyParameter $authenticatorPolicy
# Enable Windows Hello for Business
$whfbPolicy = @{
"@odata.type" = "#microsoft.graph.windowsHelloForBusinessAuthenticationMethodConfiguration"
state = "enabled"
pinMinimumLength = 6
pinMaximumLength = 127
pinLowercaseCharactersUsage = "allowed"
pinUppercaseCharactersUsage = "allowed"
pinSpecialCharactersUsage = "allowed"
securityKeyForSignIn = "enabled"
includeTargets = @(
@{
targetType = "group"
id = "all_users"
}
)
}
Update-MgPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration `
-AuthenticationMethodConfigurationId "windowsHelloForBusiness" `
-BodyParameter $whfbPolicy
Write-Host "Passwordless authentication methods enabled successfully"
ステップ 2: 認証強度の条件付きアクセスを構成する
フィッシング耐性のある認証を要求する条件付きアクセスポリシーを作成します:
# Create custom authentication strength for phishing-resistant MFA
$authStrength = @{
displayName = "Phishing-Resistant Passwordless"
description = "Requires FIDO2, WHfB, or certificate-based authentication"
allowedCombinations = @(
"fido2",
"windowsHelloForBusiness",
"x509CertificateMultiFactor"
)
requirementsSatisfied = "mfa"
}
$strengthPolicy = New-MgPolicyAuthenticationStrengthPolicy -BodyParameter $authStrength
# Create Conditional Access policy requiring phishing-resistant auth
$caPolicy = @{
displayName = "Require Phishing-Resistant Auth for All Apps"
state = "enabledForReportingButNotEnforced" # Start in report-only
conditions = @{
users = @{
includeUsers = @("All")
excludeGroups = @("Passwordless-Exclusion-Group")
}
applications = @{
includeApplications = @("All")
}
clientAppTypes = @("browser", "mobileAppsAndDesktopClients")
}
grantControls = @{
operator = "OR"
authenticationStrength = @{
id = $strengthPolicy.Id
}
}
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $caPolicy
# Create stricter policy for admin portals
$adminPolicy = @{
displayName = "Require Security Key for Admin Access"
state = "enabled"
conditions = @{
users = @{
includeRoles = @(
"62e90394-69f5-4237-9190-012177145e10", # Global Admin
"194ae4cb-b126-40b2-bd5b-6091b380977d", # Security Admin
"f28a1f50-f6e7-4571-818b-6a12f2af6b6c", # SharePoint Admin
"29232cdf-9323-42fd-ade2-1d097af3e4de" # Exchange Admin
)
}
applications = @{
includeApplications = @(
"797f4846-ba00-4fd7-ba43-dac1f8f63013", # Azure Portal
"00000006-0000-0ff1-ce00-000000000000", # Microsoft 365 Admin
"0000000a-0000-0000-c000-000000000000" # Entra Admin Center
)
}
}
grantControls = @{
operator = "OR"
authenticationStrength = @{
id = $strengthPolicy.Id
}
}
sessionControls = @{
signInFrequency = @{
value = 4
type = "hours"
isEnabled = $true
}
}
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $adminPolicy
ステップ 3: Intune で Windows Hello for Business を展開する
Microsoft Intune MDM を通じて WHfB の展開を構成します:
# Create Windows Hello for Business configuration profile in Intune
$whfbProfile = @{
"@odata.type" = "#microsoft.graph.windowsIdentityProtectionConfiguration"
displayName = "WHfB - Enterprise Deployment"
description = "Windows Hello for Business configuration for all managed devices"
useSecurityKeyForSignin = $true
windowsHelloForBusinessBlocked = $false
pinMinimumLength = 6
pinMaximumLength = 127
pinUppercaseCharactersUsage = "allowed"
pinLowercaseCharactersUsage = "allowed"
pinSpecialCharactersUsage = "allowed"
enhancedAntiSpoofingForFacialFeaturesEnabled = $true
pinRecoveryEnabled = $true
securityDeviceRequired = $true # Require TPM
unlockWithBiometricsEnabled = $true
useCertificatesForOnPremisesAuthEnabled = $true # For hybrid scenarios
# Cloud Kerberos Trust for hybrid join (recommended over key trust)
windowsHelloForBusinessAuthenticationMethod = "cloudKerberosTrust"
}
# Create the configuration profile
$profile = New-MgDeviceManagementDeviceConfiguration -BodyParameter $whfbProfile
# Assign to all Windows devices
$assignment = @{
target = @{
"@odata.type" = "#microsoft.graph.allDevicesAssignmentTarget"
}
}
New-MgDeviceManagementDeviceConfigurationAssignment `
-DeviceConfigurationId $profile.Id `
-BodyParameter $assignment
# Configure Cloud Kerberos Trust (for hybrid Azure AD joined devices)
# This eliminates the need for PKI infrastructure
# Requires Azure AD Kerberos module
Import-Module AzureADHybridAuthenticationManagement
# Create Azure AD Kerberos Server object in on-premises AD
$domain = "corp.local"
$cloudCredential = Get-Credential -Message "Enter Azure AD Global Admin credentials"
$domainCredential = Get-Credential -Message "Enter on-premises Domain Admin credentials"
Set-AzureADKerberosServer `
-Domain $domain `
-CloudCredential $cloudCredential `
-DomainCredential $domainCredential
# Verify Kerberos Server object
Get-AzureADKerberosServer -Domain $domain -CloudCredential $cloudCredential `
-DomainCredential $domainCredential
Write-Host "Cloud Kerberos Trust configured for hybrid WHfB deployment"
ステップ 4: ユーザー向けに FIDO2 セキュリティキーを登録する
セキュリティキーの登録ワークフローを実装します:
# Bulk FIDO2 security key registration via Temporary Access Pass
# Step 1: Issue Temporary Access Pass for key registration
function Issue-TemporaryAccessPass {
param(
[string]$UserId,
[int]$LifetimeMinutes = 60,
[bool]$IsUsableOnce = $true
)
$tap = @{
"@odata.type" = "#microsoft.graph.temporaryAccessPassAuthenticationMethod"
lifetimeInMinutes = $LifetimeMinutes
isUsableOnce = $IsUsableOnce
}
$result = New-MgUserAuthenticationTemporaryAccessPassMethod `
-UserId $UserId `
-BodyParameter $tap
return @{
UserId = $UserId
TemporaryAccessPass = $result.TemporaryAccessPass
ExpiresAt = $result.CreatedDateTime.AddMinutes($LifetimeMinutes)
}
}
# Bulk issue TAPs for security key registration event
$registrationUsers = Import-Csv "security_key_registration_list.csv"
$tapResults = foreach ($user in $registrationUsers) {
$tap = Issue-TemporaryAccessPass -UserId $user.UserPrincipalName
[PSCustomObject]@{
User = $user.UserPrincipalName
TAP = $tap.TemporaryAccessPass
Expires = $tap.ExpiresAt
KeySerial = $user.AssignedKeySerial
}
}
# Export TAPs for secure distribution to registration team
$tapResults | Export-Csv "tap_assignments.csv" -NoTypeInformation
# Monitor FIDO2 registration progress
function Get-Fido2RegistrationStatus {
$allUsers = Get-MgUser -All -Property "id,userPrincipalName,department"
$registrationStatus = foreach ($user in $allUsers) {
$methods = Get-MgUserAuthenticationFido2Method -UserId $user.Id
[PSCustomObject]@{
UserPrincipalName = $user.UserPrincipalName
Department = $user.Department
Fido2KeyCount = $methods.Count
KeyModels = ($methods.Model -join ", ")
RegistrationDates = ($methods.CreatedDateTime -join ", ")
HasBackupKey = $methods.Count -ge 2
}
}
return $registrationStatus
}
$status = Get-Fido2RegistrationStatus
$total = $status.Count
$registered = ($status | Where-Object { $_.Fido2KeyCount -gt 0 }).Count
$withBackup = ($status | Where-Object { $_.HasBackupKey }).Count
Write-Host "FIDO2 Registration Progress"
Write-Host " Total Users: $total"
Write-Host " Registered: $registered ($([math]::Round($registered/$total*100,1))%)"
Write-Host " With Backup: $withBackup ($([math]::Round($withBackup/$total*100,1))%)"
ステップ 5: レガシーな認証方法を無効にする
フィッシングされやすい認証要素を段階的に廃止します:
# Disable SMS and voice call authentication
$smsPolicy = @{
"@odata.type" = "#microsoft.graph.smsAuthenticationMethodConfiguration"
state = "disabled"
}
Update-MgPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration `
-AuthenticationMethodConfigurationId "sms" `
-BodyParameter $smsPolicy
$voicePolicy = @{
"@odata.type" = "#microsoft.graph.voiceAuthenticationMethodConfiguration"
state = "disabled"
}
Update-MgPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration `
-AuthenticationMethodConfigurationId "voice" `
-BodyParameter $voicePolicy
# Block legacy authentication protocols via Conditional Access
$blockLegacyPolicy = @{
displayName = "Block Legacy Authentication"
state = "enabled"
conditions = @{
users = @{ includeUsers = @("All") }
applications = @{ includeApplications = @("All") }
clientAppTypes = @(
"exchangeActiveSync",
"other"
)
}
grantControls = @{
operator = "OR"
builtInControls = @("block")
}
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $blockLegacyPolicy
# Audit users still using legacy authentication
$legacyAuthReport = Get-MgAuditLogSignIn -Filter "clientAppUsed ne 'Browser' and clientAppUsed ne 'Mobile Apps and Desktop clients'" `
-Top 1000 | Group-Object userPrincipalName | Select-Object Count, Name |
Sort-Object Count -Descending
Write-Host "Users with Legacy Auth (last 30 days):"
$legacyAuthReport | Format-Table -AutoSize
ステップ 6: パスワードレス導入の指標を監視する
展開の進捗と認証方法の使用状況を追跡します:
# Generate passwordless adoption dashboard data
function Get-PasswordlessAdoptionMetrics {
# Authentication method registration statistics
$registrationReport = Get-MgReportAuthenticationMethodUserRegistrationDetail -All
$metrics = @{
TotalUsers = $registrationReport.Count
PasswordlessCapable = ($registrationReport | Where-Object { $_.IsPasswordlessCapable }).Count
MfaRegistered = ($registrationReport | Where-Object { $_.IsMfaRegistered }).Count
Fido2Registered = ($registrationReport | Where-Object { "fido2" -in $_.MethodsRegistered }).Count
WhfbRegistered = ($registrationReport | Where-Object { "windowsHelloForBusiness" -in $_.MethodsRegistered }).Count
AuthenticatorRegistered = ($registrationReport | Where-Object { "microsoftAuthenticator" -in $_.MethodsRegistered }).Count
SmsOnly = ($registrationReport | Where-Object {
"sms" -in $_.MethodsRegistered -and
"fido2" -notin $_.MethodsRegistered -and
"windowsHelloForBusiness" -notin $_.MethodsRegistered
}).Count
}
# Authentication method usage from sign-in logs
$signInLogs = Get-MgAuditLogSignIn -Top 10000 -Filter "createdDateTime ge $((Get-Date).AddDays(-30).ToString('yyyy-MM-ddTHH:mm:ssZ'))"
$authMethodUsage = $signInLogs |
Group-Object { $_.AuthenticationMethodsUsed -join "," } |
Select-Object Count, Name | Sort-Object Count -Descending
return @{
Registration = $metrics
Usage = $authMethodUsage
}
}
$adoption = Get-PasswordlessAdoptionMetrics
$reg = $adoption.Registration
Write-Host "PASSWORDLESS ADOPTION REPORT"
Write-Host "============================"
Write-Host "Total Users: $($reg.TotalUsers)"
Write-Host "Passwordless Capable: $($reg.PasswordlessCapable) ($([math]::Round($reg.PasswordlessCapable/$reg.TotalUsers*100,1))%)"
Write-Host " FIDO2 Keys: $($reg.Fido2Registered)"
Write-Host " Windows Hello: $($reg.WhfbRegistered)"
Write-Host " Authenticator: $($reg.AuthenticatorRegistered)"
Write-Host "MFA Registered: $($reg.MfaRegistered) ($([math]::Round($reg.MfaRegistered/$reg.TotalUsers*100,1))%)"
Write-Host "SMS Only (needs upgrade): $($reg.SmsOnly)"
主要な概念
| 用語 | 定義 |
|---|---|
| FIDO2 | Fast Identity Online 2 の標準規格。ハードウェア認証器またはプラットフォーム資格情報に紐付けられた公開鍵暗号を用いてパスワードレス認証を可能にします |
| パスキー | デバイスに紐付けられた(セキュリティキーなど)、またはデバイス間で同期される FIDO2 資格情報。パスワードなしでフィッシング耐性のある認証を提供します |
| Windows Hello for Business | PIN、指紋、顔認証を使用する Windows のプラットフォーム認証器。TPM で保護された非対称鍵に基づき、パスワードレスサインインを実現します |
| Cloud Kerberos Trust | ハイブリッド WHfB のための展開モデル。PKI 証明書基盤を必要とせず、Azure AD Kerberos を使ってオンプレミスリソースに認証します |
| 一時アクセスパス | 管理者が発行する有効期限付きのパスコード。ユーザーがパスワードレス方式を登録したり、主要な方式が利用できないときにアクセスを回復したりできるようにします |
| 認証強度 | Microsoft Entra の条件付きアクセス機能。特定のポリシーにおいて、どの認証方式の組み合わせが MFA 要件を満たすかを指定します |
ツールとシステム
- Microsoft Entra 管理センター: 認証方法、条件付きアクセスポリシーの構成、およびサインイン分析の監視を行うポータル
- Microsoft Intune: 管理対象デバイスに Windows Hello for Business の構成プロファイルを展開するための MDM/MAM プラットフォーム
- Microsoft Graph API: 認証方法とポリシーの管理、および導入レポートの生成を行うためのプログラム可能なインターフェース
- FIDO2 セキュリティキー: フィッシング耐性のある認証のための暗号資格情報を保存するハードウェア認証器(YubiKey、Feitian、Google Titan)
一般的なシナリオ
シナリオ:全社規模のパスワードレス移行
背景: 5,000 人のユーザーを抱える組織が、フィッシング攻撃により 47 件のアカウントが侵害された後、12 か月以内にパスワードを廃止する計画を立てています。現状:60% が SMS MFA を使用、30% が Authenticator アプリを使用、10% が MFA を未設定。
アプローチ:
- フェーズ 1(1~2 か月目):レポート専用の条件付きアクセスで FIDO2 および WHfB 認証方法を有効化
- フェーズ 2(2~3 か月目):Cloud Kerberos Trust を使用して、Intune 経由ですべての管理対象 Windows デバイスに WHfB を展開
- フェーズ 3(3~5 か月目):経営幹部、IT 管理者、財務部門に FIDO2 セキュリティキーを配布(リスクが最も高いユーザーを優先)
- フェーズ 4(5~8 か月目):モバイル中心のユーザーとフィールドワーカー向けに Authenticator のパスキーを有効化
- フェーズ 5(8~10 か月目):フィッシング耐性のある認証について、条件付きアクセスをレポート専用から強制に切り替え
- フェーズ 6(10~12 か月目):SMS および音声通話の方法を無効化し、レガシー認証プロトコルをブロック
- 継続的対応:採用指標を監視し、未移行のユーザーに対して TAP を発行し、緊急アクセス用アカウントを維持
落とし穴:
- Cloud Kerberos Trust を展開しないと、ハイブリッド環境でオンプレミスのリソースにアクセスする際に WHfB が失敗します
- すべてのアプリケーションが最新の認証に対応していることを確認せずにパスワードレスを強制すると、アクセスが壊れます
- バックアップなしでユーザーに 1 本だけセキュリティキーを発行すると、キーを紛失した場合にロックアウトのリスクが生じます
- パスワードベースのサインインを無効化する前に、Temporary Access Pass を回復方法として設定していないと問題が起きます
出力形式
PASSWORDLESS AUTHENTICATION DEPLOYMENT REPORT
================================================
Tenant: corp.onmicrosoft.com
Users: 5,247
Deployment Phase: Phase 4 (Authenticator Passkeys)
AUTHENTICATION METHOD REGISTRATION
Passwordless Capable: 4,103 / 5,247 (78.2%)
FIDO2 Security Keys: 892 (17.0%)
Windows Hello: 2,847 (54.3%)
Authenticator Passkey: 1,234 (23.5%)
Certificate-Based: 312 (5.9%)
LEGACY METHOD STATUS
SMS-Only Users: 387 (7.4%) -- migration in progress
Voice-Only Users: 0 (disabled)
No MFA Users: 42 (0.8%) -- TAPs issued
CONDITIONAL ACCESS
Phishing-Resistant Policy: ENFORCED (all users except exclusion group)
Legacy Auth Block: ENABLED
Admin Portal Policy: SECURITY KEY REQUIRED
SIGN-IN ANALYTICS (Last 30 Days)
Total Sign-Ins: 847,293
Passwordless: 623,891 (73.6%)
Password + MFA: 198,402 (23.4%)
Password Only: 0 (blocked)
Legacy Protocol: 0 (blocked)
SECURITY IMPACT
Phishing Incidents: 0 (down from 47 pre-deployment)
Password Reset Tickets: -82% reduction
Avg Sign-In Time: 8.2s (passwordless) vs 24.1s (password)
コメント
Markdown 対応