MFA Credential Provider for WindowsのMFAに関する問題のトラブルシューティング

このトピックでは、MFA Credential Provider for Windowsのトラブルシューティングのシナリオと解決策について説明します。

サインイン中にMFAバイパス(MFA Bypass)ダイアログが表示される

症状:

サインイン時にMFAバイパス(MFA Bypass)ダイアログが表示されます。

解決策:

ユーザーがMFAポリシーに含まれていることをOktaで確認します。

サインイン中に表示に失敗しました(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を無効にします。

  1. 管理者としてホストサーバーにアクセスできる別のコンピューターにログオンします。

  2. レジストリエディター(Registry Editor)を開きます。

  3. ネットワークレジストリに接続(Connect Network Registry)を選択します。

  4. Windows Credential ProviderのMFAがインストールされているリモートサーバーのホスト名を入力します。

  5. 名前の確認(Check Names)をクリックします。しばらくすると、ホスト名が検証されます。

  6. OK(Ok)をクリックします。リモートレジストリが開きます。

  7. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Provider Filtersに移動します。

  8. Okta Credential ProviderのCLSID(またはフォルダー名)を書き留めます。

  9. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providersで、前の手順で書き留めたCLSIDを特定します。

  10. 右クリックして、名前がDisabled、値が1の新しいDWORDを作成します。

  11. サーバーを再起動します。再起動すると、資格情報プロバイダーは非アクティブになります。

ユーザーがロックアウトされ、PSExecを使用している資格情報プロバイダーが無効になる

症状:

エンドユーザーがWindows Credential ProviderのMFAとリモートデスクトッププロトコルを使ってWindowsホストにアクセスできなくなりました。エンドユーザーは事実上ロックアウトされます。

さらに、Windowsレジストリエディターをリモートで使用するなどの他のソリューションも使用できません。

解決策:

psexecを使用して、Windows Credential ProviderのMFAを実行しているサーバーのレジストリをクエリして変更し、プロバイダーを無効にします。

  1. 管理者としてコマンドプロンプトを開きます。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}.
    
  2. 表示された各結果についてクエリを実行し、どれが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
  3. 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.
  4. 前のクエリを再実行すると、新しく追加された要素を示す、次のような結果が返されます。
    HKEY_LOCAL_MACHINE\software\microsoft\windows\currentversion\authentication\Credential Provider Filters\{6D269AEA-...-02AA9C14F310}
    (Default)    REG_SZ    OktaCredentialProvider
                 REG_DWORD Disabled 1
  5. psexecとshutdownコマンドを使用して、リモートコンピューターを再起動します。
    psexec \\ipaddress -u username -p password shutdown -f -r -t 0
    ここで、-fは実行中のプログラムを警告なしで強制終了します。-rは完全にシャットダウンし、再起動します。-t 0はシャットダウン前のタイムアウトをゼロ秒に設定します。

再起動すると、資格情報プロバイダーは非アクティブになります。

根本原因が特定されたら、次のようなコマンドを使って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以降が必要です。

問題を修正するには、次の手順を実行します。

  1. プロキシが使用され、TLSがプロキシで終了している場合は、SslPinningEnabledを無効にします。Okta Credential Provider for Windowsをインストールする追加のプロパティを変更するを参照してください。
  2. レジストリで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."
    }