MFA Credential Provider for WindowsのMFAに関する問題のトラブルシューティング
このトピックでは、MFA Credential Provider for Windowsのトラブルシューティングのシナリオと解決策について説明します。
Sign-In Widget (第3世代)はサードパーティエージェントの多要素認証をサポートしません。
サインイン中にMFAバイパス(MFA Bypass)ダイアログが表示される
症状:
サインイン時にMFAバイパス(MFA Bypass)ダイアログが表示されます。
解決策:
ユーザーがMFAポリシーに含まれていることをOktaで確認します。
App-SignOnポリシーは、Microsoft RDPアプリに関連する唯一のポリシーです。
サインイン中に表示に失敗しました(Display Failed)ダイアログが表示される
症状:
サインイン時に表示に失敗しました(Display Failed)ダイアログが表示されます。
以下を検証します。
- クライアントID、クライアントシークレット、Okta URLが正しく構成されている。
- Windowsサインインに入力したユーザー名がOktaのユーザー名と一致する。
サーバーにRDPを接続できない
症状:
エンドユーザーがRDPクライアントを使用してOkta Credential Provider for Windows対応のワークステーションまたはサーバーに接続できません。
解決策:
システムのプロパティ(System Properties)(Allow remote connections to this computer)ダイアログに表示されるように、このコンピューターへのリモート接続を許可する(Allow remote connections to this computer)(Allow connections only from computers running Remote Desktop with Network Level Authentication)とネットワークレベル認証でリモートデスクトップを実行しているコンピューターからのみ接続を許可する(Allow connections only from computers running Remote Desktop with Network Level Authentication)(System Properties)が有効になっていることを確認します。
System.Net.WebExceptionが表示される
症状:
以下のような例外が表示されます。TLSのバージョンが古い可能性があります。OktaではTLS 1.2以降が必要です。
System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send.
. . .
System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
. . .
System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host.
解決策:
管理者としてPowerShellターミナルを開き、次のスクリプトを実行します。
$is64bit = [IntPtr]::Size * 8 -eq 64
Write-Host "Is 64-bit script: $is64bit"
#helper function to check for if 0x800 bit is set
function checkTls12Bit([Int] $regValue) {
return ($regValue -band 0x800) -ne 0x800
}
function setRegKeyToBitValue([string] $regBranch, [string] $regKey) {
$current = Get-ItemProperty -Path $regBranch -ErrorAction SilentlyContinue
if ($current -eq $null) {
Write-Host "$regBranch\$regKey does not exist. No change."
return $false
}
$regValue = $current.$regKey
if ($regValue -eq $null -or (checkTls12Bit $regValue) ) {
if ($regValue -eq $null) {
$regValue = 0x800
} else {
$regValue = $regValue -bor 0x800
}
$p = New-ItemProperty $regBranch -Name $regKey -PropertyType DWord -Value $regValue -ErrorAction Stop -Force
Write-Host "Updated $regBranch\$regKey value to $regValue"
return $true
}
Write-Host "$regBranch\$regKey value is $regValue. No change."
return $false
}
function setRegKeyToValueOfOne([string] $regBranch, [string] $regKey) {
$current = Get-ItemProperty -Path $regBranch -ErrorAction SilentlyContinue
if ($current -eq $null) {
Write-Host "$regBranch\$regKey does not exist. No change."
return $false
}
if ($current.$regKey -ne 1) {
$p = New-ItemProperty $regBranch -Name $regKey -PropertyType DWord -Value 1 -ErrorAction Stop -Force
Write-Host "Updated $regBranch\$regKey value to 1"
return $true
}
Write-Host "$regBranch\$regKey value is 1. No change."
return $false
}
#setup .net tls settings
function setupTls4NET([boolean]$is64bit, [string]$regBranch, [string]$reg32bitBranch) {
# https://docs.microsoft.com/ja-jp/dotnet/framework/network-programming/tls
$updated = setRegKeyToValueOfOne $regBranch "SchUseStrongCrypto"
$updated = (setRegKeyToValueOfOne $regBranch "SystemDefaultTlsVersions") -or $updated
if ($is64bit) {
$updated = (setRegKeyToValueOfOne $reg32bitBranch "SchUseStrongCrypto") -or $updated
$updated = (setRegKeyToValueOfOne $reg32bitBranch "SystemDefaultTlsVersions") -or $updated
}
return $updated
}
# https://docs.microsoft.com/ja-jp/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed
$version = Get-ItemProperty -Path "HKLM:\Software\Microsoft\NET Framework Setup\NDP\v4\Full" -Name Release
# 394254 - .NET Framework 4.6.1, which is the current target of the installer
if ($version.Release -ge 394254) {
$ev = [environment]::Version
$v = "v" + $ev.Major + "." + $ev.Minor + "." + $ev.Build
$updated = setupTls4NET $is64bit "HKLM:\SOFTWARE\Microsoft\.NETFramework\$v" "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\$v"
# https://support.microsoft.com/en-ca/help/3140245/update-to-enable-tls-1-1-and-tls-1-2-as-a-default-secure-protocols-in
$updated = (setRegKeyToBitValue "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp" "DefaultSecureProtocols") -or $updated
$updated = (setRegKeyToBitValue "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings" "SecureProtocols") -or $updated
# updated the 32-bit branches if we are on 64-bit machine
if ($is64bit) {
$updated = (setRegKeyToBitValue "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp" "DefaultSecureProtocols") -or $updated
$updated = (setRegKeyToBitValue "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Internet Settings" "SecureProtocols") -or $updated
}
# current user settings
$updated = (setRegKeyToBitValue "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings" "SecureProtocols") -or $updated
# local system account
$userSid = ".DEFAULT"
$updated = (setRegKeyToBitValue "Registry::HKEY_USERS\$userSid\Software\Microsoft\Windows\CurrentVersion\Internet Settings" "SecureProtocols") -or $updated
if ($updated) {
Write-Host "Done. Updated required settings."
}
else
{
Write-Host "Done. No updates are required."
}
}
else
{
Write-Host "No changes were made. Your version of .NET Framework is earlier version than 4.6.1, please upgrade."
}
ユーザーがロックアウトされ、レジストリエディターを使用している資格情報プロバイダーが無効になる
症状:
エンドユーザーがWindows Credential ProviderのMFAとリモートデスクトッププロトコルを使ってWindowsホストにアクセスできなくなりました。エンドユーザーは事実上ロックアウトされます。
解決策:
Windowsレジストリエディター(Windows Registry editor)を使ってリモートサーバーのレジストリを参照し、Windows資格情報プロバイダーのMFAを無効にします。
このソリューションは、すべてのユーザーのWindows資格情報プロバイダーのMFAを無効にします。管理者は、ロックされたサーバーのレジストリにリモートでアクセスできる必要があります。Windowsレジストリの編集には、細心の注意を払ってください。
-
管理者としてホストサーバーにアクセスできる別のコンピューターにログオンします。
-
レジストリエディター(Registry Editor)を開きます。
-
ネットワークレジストリに接続(Connect Network Registry)を選択します。
-
Windows Credential ProviderのMFAがインストールされているリモートサーバーのホスト名を入力します。
-
名前の確認(Check Names)をクリックします。しばらくすると、ホスト名が検証されます。
-
OK(Ok)をクリックします。リモートレジストリが開きます。
-
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Provider Filtersに移動します。 -
Okta Credential ProviderのCLSID(またはフォルダー名)を書き留めます。
-
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providersで、前の手順で書き留めたCLSIDを特定します。 -
右クリックして、名前が
Disabled、値が1の新しいDWORDを作成します。 -
サーバーを再起動します。再起動すると、資格情報プロバイダーは非アクティブになります。
ユーザーがロックアウトされ、PSExecを使用している資格情報プロバイダーが無効になる
症状:
エンドユーザーがWindows Credential ProviderのMFAとリモートデスクトッププロトコルを使ってWindowsホストにアクセスできなくなりました。エンドユーザーは事実上ロックアウトされます。
さらに、Windowsレジストリエディターをリモートで使用するなどの他のソリューションも使用できません。
解決策:
psexecを使用して、Windows Credential ProviderのMFAを実行しているサーバーのレジストリをクエリして変更し、プロバイダーを無効にします。
このソリューションでは、System Internals PsExecアプリケーションを使用する必要があります。https://docs.microsoft.com/ja-jp/sysinternals/downloads/psexecからダウンロードできます。
Enter-PSSessionは、psexecの代わりに使用できます。Enter-PSSessionを参照してください。
- 管理者としてコマンドプロンプトを開きます。psexecとWindows regクエリコマンドを使用して、
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Provider Filtersで検出された値を一覧表示します。例:
ここで、psexec \\ipaddress -u username -p password reg query "hklm\software\microsoft\windows\currentversion\authentication\Credential Provider Filters"\\ipaddressはWindows Credential ProviderのMFAを実行しているサーバーのIPアドレスを指します。例:\\192.168.1.199-u usernameは、\\ipaddressで表されるリモートサーバー上の有効なユーザーを指します。例:-u validuser- p passwordは、-uパラメーターで指定されたユーザーのパスワードを指します。例:-p pwdforValiduserWhichは次のような結果を返します。HKEY_LOCAL_MACHINE\software\microsoft\windows\currentversion\authentication\Credential Provider Filters\{6D269AEA-...-02AA9C14F310} HKEY_LOCAL_MACHINE\software\microsoft\windows\currentversion\authentication\Credential Provider Filters\{DDC0EED2-...-EDE16A79A0DE}. - 表示された各結果についてクエリを実行し、どれがOktaCredentialProviderなのか特定します。
次のような結果が返されます。psexec \\ipaddress -u username -p password reg query "hklm\software\microsoft\windows\currentversion\authentication\Credential Provider Filters\{6D269AEA-...-02AA9C14F310}"HKEY_LOCAL_MACHINE\software\microsoft\windows\currentversion\authentication\Credential Provider Filters\{6D269AEA-...-02AA9C14F310} (Default) REG_SZ OktaCredentialProvider - psexecとreg addコマンド、およびOkta Credential ProviderのクラスIDを使用して、名前が
Disabled、値が1の新しいDWord値を作成します。
ここで、psexec \\ipaddress -u username -p password reg add "hklm\software\microsoft\windows\currentversion\authentication\Credential Provider Filters\{value from prior step}" /f /v Disabled /t REG_DWORD /d 1/fは強制上書き、/v {name of new entry}は追加される新規エントリの名前、Disabled。/t {type}は追加された新規エントリのタイプ、REG_DWORD。/d {value}は新規エントリの値、1。次のような結果が返されます。The operation completed successfully. - 前のクエリを再実行すると、新しく追加された要素を示す、次のような結果が返されます。
HKEY_LOCAL_MACHINE\software\microsoft\windows\currentversion\authentication\Credential Provider Filters\{6D269AEA-...-02AA9C14F310} (Default) REG_SZ OktaCredentialProvider REG_DWORD Disabled 1 - psexecとshutdownコマンドを使用して、リモートコンピューターを再起動します。
ここで、psexec \\ipaddress -u username -p password shutdown -f -r -t 0-fは実行中のプログラムを警告なしで強制終了します。-rは完全にシャットダウンし、再起動します。-t0はシャットダウン前のタイムアウトをゼロ秒に設定します。
再起動すると、資格情報プロバイダーは非アクティブになります。
根本原因が特定されたら、次のようなコマンドを使ってDisabledの値を削除できます。
psexec \\ipaddress -u username -p password reg delete "hklm\software\microsoft\windows\currentversion\authentication\Credential Provider Filters\{class id from prior step}" /f /v Disabled
資格情報プロバイダーがOktaにアクセスできない
症状:資格情報プロバイダーがOktaにアクセスできません。これは、プロキシの有無にかかわらず発生する可能性があります。以下に示すような例外がスローされます。System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send.
CompletionException
exception thrown is - System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. --->
System.IO.IOException: Authentication failed because the remote party has closed the transport stream.
at System.Net.Security.SslState.StartReadFrame (Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication (Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.ConnectStream.WritHeaders (Boolean async)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.GetResponse()
at OktaWidget.JwtService.GetStateTokenUsingJwt(String username)
at OktaWidget.OktaWidgetForm..ctor(String username, Int64 parent, Int64 widgetFlow)
at OktaWidget.OktaWidgetClass.displayWidget(Int64 parent, String username, Int64 flow)
解決策:
TLSが正しく有効化されていない可能性があります。OktaではTLS 1.2以降が必要です。
問題を修正するには、次の手順を実行します。
- プロキシが使用され、TLSがプロキシで終了している場合は、SslPinningEnabledを無効にします。Okta Credential Provider for Windowsをインストールするの追加のプロパティを変更するを参照してください。
- レジストリでTLS 1.2を有効にします。管理者としてPowerShellターミナルを開き、次のスクリプトを実行します。
$is64bit = [IntPtr]::Size * 8 -eq 64 Write-Host "Is 64-bit script: $is64bit" #helper function to check for if 0x800 bit is set function checkTls12Bit([Int] $regValue) { return ($regValue -band 0x800) -ne 0x800 } function setRegKeyToBitValue([string] $regBranch, [string] $regKey) { $current = Get-ItemProperty -Path $regBranch -ErrorAction SilentlyContinue if ($current -eq $null) { Write-Host "$regBranch\$regKey does not exist. No change." return $false } $regValue = $current.$regKey if ($regValue -eq $null -or (checkTls12Bit $regValue) ) { if ($regValue -eq $null) { $regValue = 0x800 } else { $regValue = $regValue -bor 0x800 } $p = New-ItemProperty $regBranch -Name $regKey -PropertyType DWord -Value $regValue -ErrorAction Stop -Force Write-Host "Updated $regBranch\$regKey value to $regValue" return $true } Write-Host "$regBranch\$regKey value is $regValue. No change." return $false } function setRegKeyToValueOfOne([string] $regBranch, [string] $regKey) { $current = Get-ItemProperty -Path $regBranch -ErrorAction SilentlyContinue if ($current -eq $null) { Write-Host "$regBranch\$regKey does not exist. No change." return $false } if ($current.$regKey -ne 1) { $p = New-ItemProperty $regBranch -Name $regKey -PropertyType DWord -Value 1 -ErrorAction Stop -Force Write-Host "Updated $regBranch\$regKey value to 1" return $true } Write-Host "$regBranch\$regKey value is 1. No change." return $false } #setup .net tls settings function setupTls4NET([boolean]$is64bit, [string]$regBranch, [string]$reg32bitBranch) { # https://docs.microsoft.com/ja-jp/dotnet/framework/network-programming/tls $updated = setRegKeyToValueOfOne $regBranch "SchUseStrongCrypto" $updated = (setRegKeyToValueOfOne $regBranch "SystemDefaultTlsVersions") -or $updated if ($is64bit) { $updated = (setRegKeyToValueOfOne $reg32bitBranch "SchUseStrongCrypto") -or $updated $updated = (setRegKeyToValueOfOne $reg32bitBranch "SystemDefaultTlsVersions") -or $updated } return $updated } # https://docs.microsoft.com/ja-jp/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed $version = Get-ItemProperty -Path "HKLM:\Software\Microsoft\NET Framework Setup\NDP\v4\Full" -Name Release # 394254 - .NET Framework 4.6.1, which is the current target of the installer if ($version.Release -ge 394254) { $ev = [environment]::Version $v = "v" + $ev.Major + "." + $ev.Minor + "." + $ev.Build $updated = setupTls4NET $is64bit "HKLM:\SOFTWARE\Microsoft\.NETFramework\$v" "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\$v" # https://support.microsoft.com/en-ca/help/3140245/update-to-enable-tls-1-1-and-tls-1-2-as-a-default-secure-protocols-in $updated = (setRegKeyToBitValue "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp" "DefaultSecureProtocols") -or $updated $updated = (setRegKeyToBitValue "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings" "SecureProtocols") -or $updated # updated the 32-bit branches if we are on 64-bit machine if ($is64bit) { $updated = (setRegKeyToBitValue "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp" "DefaultSecureProtocols") -or $updated $updated = (setRegKeyToBitValue "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Internet Settings" "SecureProtocols") -or $updated } # current user settings $updated = (setRegKeyToBitValue "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings" "SecureProtocols") -or $updated # local system account $userSid = ".DEFAULT" $updated = (setRegKeyToBitValue "Registry::HKEY_USERS\$userSid\Software\Microsoft\Windows\CurrentVersion\Internet Settings" "SecureProtocols") -or $updated if ($updated) { Write-Host "Done. Updated required settings." } else { Write-Host "Done. No updates are required." } } else { Write-Host "No changes were made. Your version of .NET Framework is earlier version than 4.6.1, please upgrade." }