WinBioSetCredential 함수(winbio.h)
현재 사용자의 생체 인식 로그온 자격 증명을 저장합니다. Windows 10 빌드 1607부터 이 함수를 모바일 이미지와 함께 사용할 수 있습니다.
구문
HRESULT WinBioSetCredential(
[in] WINBIO_CREDENTIAL_TYPE Type,
[in] PUCHAR Credential,
[in] SIZE_T CredentialSize,
[in] WINBIO_CREDENTIAL_FORMAT Format
);
매개 변수
[in] Type
자격 증명 형식을 지정하는 WINBIO_CREDENTIAL_TYPE 값입니다. 현재 WINBIO_CREDENTIAL_PASSWORD 수 있습니다.
[in] Credential
자격 증명을 포함하는 바이트의 가변 길이 배열에 대한 포인터입니다. 형식은 형식 및 형식 매개 변수에 따라 달라집니다.
[in] CredentialSize
Credential 매개 변수에 지정된 값의 크기(바이트)입니다.
[in] Format
자격 증명의 형식을 지정하는 WINBIO_CREDENTIAL_FORMAT 열거형 값입니다. Type 매개 변수가 WINBIO_CREDENTIAL_PASSWORD 경우 다음 중 하나일 수 있습니다.
값 | 의미 |
---|---|
|
자격 증명은 일반 텍스트 NULL로 끝나는 유니코드 문자열입니다. |
|
CredProtect 함수를 사용하여 자격 증명을 래핑하고 CredPackAuthenticationBuffer 함수를 사용하여 압축했습니다. 권장됩니다. |
|
암호 자격 증명이 CredProtect로 래핑되었습니다. |
반환 값
함수가 성공하면 S_OK를 반환합니다. 함수가 실패하면 오류를 나타내는 HRESULT 값을 반환합니다. 가능한 값에는 다음 표에 있는 값이 포함되지만, 이에 국한되는 것은 아닙니다. 일반적인 오류 코드 목록은 일반 HRESULT 값을 참조하세요.
반환 코드 | 설명 |
---|---|
|
호출자에게 자격 증명을 설정할 수 있는 권한이 없습니다. |
|
사용자가 생체 인식 샘플을 등록하지 않았습니다. |
|
현재 사용자에 대해 자격 증명이 잘못되었습니다. |
|
현재 관리 정책은 자격 증명 공급자의 사용을 금지합니다. |
설명
현재 사용자에게 지정된 형식의 기존 로그온 자격 증명이 있는 경우 WinBioSetCredential 은 이를 덮어씁니다. 함수는 사용자 자격 증명 및 대화형 로그온 권한을 모두 확인하고 확인에 실패하면 실패합니다. 로그온 시도와 관련된 이벤트가 이벤트 로그에 배치됩니다. 도메인 계정에 대한 자격 증명은 그룹 정책 허용되는 경우에만 저장할 수 있습니다.
Format 매개 변수에 WINBIO_PASSWORD_PACKED 전달하는 경우 SecureZeroMemory를 호출하여 자격 증명을 안전하게 0으로 만들어야 합니다.
중간 이상의 무결성 프로세스만 자격 증명을 설정할 수 있습니다. 낮은 무결성 프로세스가 자격 증명을 설정하려고 하면 함수는 E_ACCESSDENIED 반환합니다.
예제
다음 함수는 현재 사용자의 ID 및 자격 증명을 검색한 다음 WinBioSetCredential 을 호출하여 자격 증명을 설정합니다. GetCredentials 및 GetCurrentUserIdentity의 두 도우미 함수도 포함됩니다. Winbio.lib 정적 라이브러리에 연결하고 다음 헤더 파일을 포함합니다.
- Windows.h
- Wincred.h
- Stdio.h
- Conio.h
- Winbio.h
HRESULT SetCredential()
{
// Declare variables.
HRESULT hr = S_OK;
PVOID pvAuthBlob = NULL;
ULONG cbAuthBlob = 0;
WINBIO_IDENTITY identity;
PSID pSid = NULL;
// Find the identity of the user.
wprintf_s(L"\n Finding user identity.\n");
hr = GetCurrentUserIdentity( &identity );
if (FAILED(hr))
{
wprintf_s(L"\n User identity not found. hr = 0x%x\n", hr);
return hr;
}
// Set a pointer to the security descriptor for the user.
pSid = identity.Value.AccountSid.Data;
// Retrieve a byte array that contains credential information.
hr = GetCredentials(pSid, &pvAuthBlob, &cbAuthBlob);
if (FAILED(hr))
{
wprintf_s(L"\n GetCredentials failed. hr = 0x%x\n", hr);
goto e_Exit;
}
// Set the credentials.
hr = WinBioSetCredential(
WINBIO_CREDENTIAL_PASSWORD, // Type of credential.
(PUCHAR)pvAuthBlob, // Credentials byte array
cbAuthBlob, // Size of credentials
WINBIO_PASSWORD_PACKED); // Credentials format
if (FAILED(hr))
{
wprintf_s(L"\n WinBioSetCredential failed. hr = 0x%x\n", hr);
goto e_Exit;
}
wprintf_s(L"\n Credentials successfully set.\n");
e_Exit:
// Delete the authentication byte array.
if (NULL != pvAuthBlob)
{
SecureZeroMemory(pvAuthBlob, cbAuthBlob);
CoTaskMemFree(pvAuthBlob);
pvAuthBlob = NULL;
}
wprintf_s(L"\n Press any key to exit...");
_getch();
return hr;
}
//------------------------------------------------------------------------
// The following function displays a dialog box to prompt a user
// for credentials.
//
HRESULT GetCredentials(PSID pSid, PVOID* ppvAuthBlob, ULONG* pcbAuthBlob)
{
HRESULT hr = S_OK;
DWORD dwResult;
WCHAR szUsername[MAX_PATH] = {0};
DWORD cchUsername = ARRAYSIZE(szUsername);
WCHAR szPassword[MAX_PATH] = {0};
WCHAR szDomain[MAX_PATH] = {0};
DWORD cchDomain = ARRAYSIZE(szDomain);
WCHAR szDomainAndUser[MAX_PATH] = {0};
DWORD cchDomainAndUser = ARRAYSIZE(szDomainAndUser);
PVOID pvInAuthBlob = NULL;
ULONG cbInAuthBlob = 0;
PVOID pvAuthBlob = NULL;
ULONG cbAuthBlob = 0;
CREDUI_INFOW ui;
ULONG ulAuthPackage = 0;
BOOL fSave = FALSE;
static const WCHAR WINBIO_CREDPROV_TEST_PASSWORD_PROMPT_MESSAGE[] =
L"Enter your current password to enable biometric logon.";
static const WCHAR WINBIO_CREDPROV_TEST_PASSWORD_PROMPT_CAPTION[] =
L"Biometric Log On Enrollment";
if (NULL == pSid || NULL == ppvAuthBlob || NULL == pcbAuthBlob)
{
return E_INVALIDARG;
}
// Retrieve the user name and domain name.
SID_NAME_USE SidUse;
DWORD cchTmpUsername = cchUsername;
DWORD cchTmpDomain = cchDomain;
if (!LookupAccountSidW(
NULL, // Local computer
pSid, // Security identifier for user
szUsername, // User name
&cchTmpUsername, // Size of user name
szDomain, // Domain name
&cchTmpDomain, // Size of domain name
&SidUse)) // Account type
{
dwResult = GetLastError();
hr = HRESULT_FROM_WIN32(dwResult);
wprintf_s(L"\n LookupAccountSidLocalW failed: hr = 0x%x\n", hr);
return hr;
}
// Combine the domain and user names.
swprintf_s(
szDomainAndUser,
cchDomainAndUser,
L"%s\\%s",
szDomain,
szUsername);
// Call CredPackAuthenticationBufferW once to determine the size,
// in bytes, of the authentication buffer.
if (!CredPackAuthenticationBufferW(
0, // Reserved
szDomainAndUser, // Domain\User name
szPassword, // User Password
NULL, // Packed credentials
&cbInAuthBlob) // Size, in bytes, of credentials
&& GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
dwResult = GetLastError();
hr = HRESULT_FROM_WIN32(dwResult);
wprintf_s(L"\n CredPackAuthenticationBufferW (1) failed: ");
wprintf_s(L"hr = 0x%x\n", hr);
}
// Allocate memory for the input buffer.
pvInAuthBlob = CoTaskMemAlloc(cbInAuthBlob);
if (!pvInAuthBlob)
{
cbInAuthBlob = 0;
wprintf_s(L"\n CoTaskMemAlloc() Out of memory %d\n");
return HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
}
// Call CredPackAuthenticationBufferW again to retrieve the
// authentication buffer.
if (!CredPackAuthenticationBufferW(
0,
szDomainAndUser,
szPassword,
(PBYTE)pvInAuthBlob,
&cbInAuthBlob))
{
dwResult = GetLastError();
hr = HRESULT_FROM_WIN32(dwResult);
wprintf_s(L"\n CredPackAuthenticationBufferW (2) failed: ");
wprintf_s(L"hr = 0x%x\n", hr);
goto e_Exit;
}
// Display a dialog box to request credentials.
ui.cbSize = sizeof(ui);
ui.hwndParent = GetConsoleWindow();
ui.pszMessageText = WINBIO_CREDPROV_TEST_PASSWORD_PROMPT_MESSAGE;
ui.pszCaptionText = WINBIO_CREDPROV_TEST_PASSWORD_PROMPT_CAPTION;
ui.hbmBanner = NULL;
dwResult = CredUIPromptForWindowsCredentialsW(
&ui, // Customizing information
0, // Error code to display
&ulAuthPackage, // Authorization package
pvInAuthBlob, // Credential byte array
cbInAuthBlob, // Size of credential input buffer
&pvAuthBlob, // Output credential byte array
&cbAuthBlob, // Size of credential byte array
&fSave, // Select the save check box.
CREDUIWIN_IN_CRED_ONLY |
CREDUIWIN_ENUMERATE_CURRENT_USER
);
if (dwResult != NO_ERROR)
{
hr = HRESULT_FROM_WIN32(dwResult);
wprintf_s(L"\n CredUIPromptForWindowsCredentials failed: ");
wprintf_s(L"0x%08x\n", dwResult);
goto e_Exit;
}
*ppvAuthBlob = pvAuthBlob;
*pcbAuthBlob = cbAuthBlob;
e_Exit:
// Delete the input authentication byte array.
if (pvInAuthBlob)
{
SecureZeroMemory(pvInAuthBlob, cbInAuthBlob);
CoTaskMemFree(pvInAuthBlob);
pvInAuthBlob = NULL;
};
return hr;
}
//------------------------------------------------------------------------
// The following function retrieves the identity of the current user.
// This is a helper function and is not part of the Windows Biometric
// Framework API.
//
HRESULT GetCurrentUserIdentity(__inout PWINBIO_IDENTITY Identity)
{
// Declare variables.
HRESULT hr = S_OK;
HANDLE tokenHandle = NULL;
DWORD bytesReturned = 0;
struct{
TOKEN_USER tokenUser;
BYTE buffer[SECURITY_MAX_SID_SIZE];
} tokenInfoBuffer;
// Zero the input identity and specify the type.
ZeroMemory( Identity, sizeof(WINBIO_IDENTITY));
Identity->Type = WINBIO_ID_TYPE_NULL;
// Open the access token associated with the
// current process
if (!OpenProcessToken(
GetCurrentProcess(), // Process handle
TOKEN_READ, // Read access only
&tokenHandle)) // Access token handle
{
DWORD win32Status = GetLastError();
wprintf_s(L"Cannot open token handle: %d\n", win32Status);
hr = HRESULT_FROM_WIN32(win32Status);
goto e_Exit;
}
// Zero the tokenInfoBuffer structure.
ZeroMemory(&tokenInfoBuffer, sizeof(tokenInfoBuffer));
// Retrieve information about the access token. In this case,
// retrieve a SID.
if (!GetTokenInformation(
tokenHandle, // Access token handle
TokenUser, // User for the token
&tokenInfoBuffer.tokenUser, // Buffer to fill
sizeof(tokenInfoBuffer), // Size of the buffer
&bytesReturned)) // Size needed
{
DWORD win32Status = GetLastError();
wprintf_s(L"Cannot query token information: %d\n", win32Status);
hr = HRESULT_FROM_WIN32(win32Status);
goto e_Exit;
}
// Copy the SID from the tokenInfoBuffer structure to the
// WINBIO_IDENTITY structure.
CopySid(
SECURITY_MAX_SID_SIZE,
Identity->Value.AccountSid.Data,
tokenInfoBuffer.tokenUser.User.Sid
);
// Specify the size of the SID and assign WINBIO_ID_TYPE_SID
// to the type member of the WINBIO_IDENTITY structure.
Identity->Value.AccountSid.Size = GetLengthSid(tokenInfoBuffer.tokenUser.User.Sid);
Identity->Type = WINBIO_ID_TYPE_SID;
e_Exit:
if (tokenHandle != NULL)
{
CloseHandle(tokenHandle);
}
return hr;
}
요구 사항
요구 사항 | 값 |
---|---|
지원되는 최소 클라이언트 | Windows 8.1 [데스크톱 앱만 해당] |
지원되는 최소 서버 | R2 Windows Server 2012 [데스크톱 앱만 해당] |
대상 플랫폼 | Windows |
헤더 | winbio.h(Winbio.h 포함) |
라이브러리 | Winbio.lib |
DLL | Winbio.dll |