다음을 통해 공유


IHttpUser::GetPassword 메서드

사용자 암호를 반환합니다.

구문

virtual PCWSTR GetPassword(  
   VOID  
) = 0;  

매개 변수

이 메서드는 매개 변수를 사용하지 않습니다.

반환 값

사용자 암호를 포함하는 null로 끝나는 상수 유니코드 문자열에 대한 포인터입니다.

설명

반환되는 값은 인증 유형에 따라 달라집니다. 인증 유형은 GetAuthenticationType 메서드에서 반환됩니다.

다음 표에는 연결된 암호 값이 있는 인증 유형이 나와 있습니다.

인증 유형 암호 값
Active Directory 암호화된 해시
익명 빈 문자열
Basic 암호화되지 않은 일반 텍스트
다이제스트 MD5(메시지 다이제스트 알고리즘 5) 해시
양식 SHA1(보안 해시 알고리즘 1) 또는 MD5를 사용하여 암호화되지 않은 일반 텍스트 또는 암호화
Windows 빈 문자열

주의

암호화되지 않은 암호는 사용자에게 표시되거나 반환되어서는 안 됩니다. Basic은 사용자 이름과 암호를 일반 텍스트 형식으로 모두 전달하므로 Basic 이외의 인증 체계를 사용하는 것이 좋습니다.

구현자에 대한 참고 사항

IHttpUser 구현자는 이 데이터로 메모리 관리를 담당합니다. 따라서 IHttpUser 동적 메모리 할당을 사용하는 구현자는 더 이상 필요하지 않은 경우 포인터를 PCWSTR 해제하거나 를 호출 delete 해야 합니다.

호출자 참고 사항

IHttpUser구현자는 이 데이터를 사용하여 메모리 관리를 담당합니다. 따라서 IHttpUser 클라이언트는 이 데이터가 더 이상 필요하지 않을 때 반환 PCWSTR 된 포인터를 해제하거나 를 호출 delete 해서는 안 됩니다. 또한 클라이언트는 이 데이터를 가 아닌 const 포인터로 캐스팅하거나 이 PCWSTR에서 참조하는 메모리의 상태를 변경해서는 안 됩니다. 그렇지 않으면 액세스 위반이 throw되거나 데이터가 무효화됩니다.

예제

다음 코드 예제에서는 응답 헤더 및 본문을 지우고 사용자 정보를 XML 문서로 클라이언트에 반환하는 HTTP 모듈을 만드는 방법을 보여 줍니다.

#pragma warning( disable : 4290 )
#pragma warning( disable : 4530 )

#define _WINSOCKAPI_
#include <windows.h>
#include <io.h>
#include <sal.h>
#include <httpserv.h>

#include <string>
using namespace std;

#import "msxml6.dll"
using namespace MSXML2;

// The CConvert class mirrors the Convert class that is 
// defined in the .NET Framework. It converts primitives 
// and other data types to wstring types.
class CConvert
{
public:
    // The ToByteString converts a double-byte 
    // character string to a single-byte string.
    // str: the double-byte string to convert.
    // return: a single-byte string copied from str.
    static string ToByteString(const wstring& str)
    {
        // Get the length of the 
        // double-byte string.
        size_t length = str.length();

        // Create a temporary char pointer.
        char* byteChar = new char[length+1];
        byteChar[0] = '\0';
        // Copy the double-byte character string
        // into the single-byte string.        
        size_t charsReturned = 0;
        wcstombs_s(&charsReturned, byteChar, 
                   length+1, str.c_str(), length+1);
        // Create a string to return.
        string retString = byteChar;
        // Delete the temporary string and
        // set that string to NULL.
        delete[] byteChar;
        byteChar = NULL;

        // Return the single-byte string.
        return retString;
    }

    // The ToString method converts 
    // a PCWSTR to a wstring.
    // pcwstr: the PCWSTR to convert.
    // return: L"NULL" if the pcwstr
    // parameter is NULL; otherwise, 
    // pcwstr converted to a wstring.
    static wstring ToString(PCWSTR pcwstr)
    {
        // If the pcwstr parameter
        // is NULL, return L"NULL".
        if (NULL == pcwstr)
        {
            return L"NULL";
        }

        // Implicitly convert the 
        // PCWSTR to a wstring.
        return pcwstr;
    }
};

// The CResponseWriter class writes 
// text to the response stream.
class CResponseWriter
{
public:
    // Creates the CResponseWriter class.
    // response: the IHttpResponse 
    // pointer to write to.
    // throws: a _com_error exception if
    // the IHttpResponse pointer is NULL.
    CResponseWriter(IHttpResponse* response)
        throw (_com_error)
    {
        // If the response is NULL,
        // throw an exception.
        if (NULL == response)
        {
            ThrowOnFail(E_INVALIDARG);            
        }

        // Set the internal response.
        m_response = response;
    }

    // The destructor for the CResponseWriter
    // class. The CResponseWriter method 
    // sets the IHttpResponse pointer to NULL.
    virtual ~CResponseWriter()
    {
        m_response = NULL;
    }

    // The Write method writes the 
    // PCSTR to the response stream.
    // pszValue: the PCSTR to write.
    // throws: a _com_error if the 
    // Write method fails.
    void Write
    (
        PCSTR pszValue        
    ) throw (_com_error)
    {
        // The string must not be 
        // NULL, and its length must 
        // be greater than 0.
        if ((NULL == pszValue) || 
            (strlen(pszValue) < 1))            
        {
            // Throw an invalid argument
            // exception.
            ThrowOnFail(E_INVALIDARG);                        
        }        

        // Create a data chunk structure.
        HTTP_DATA_CHUNK dataChunk;
        // Set the chunk to a chunk in memory.
        dataChunk.DataChunkType = 
            HttpDataChunkFromMemory;

        // Set the chunk to 
        // the pszValue parameter.
        dataChunk.FromMemory.pBuffer = 
            (PVOID)pszValue;
        // Set the chunk size 
        // to the pszValue length.
        dataChunk.FromMemory.BufferLength = 
            (USHORT)strlen(pszValue);
                
        // Declare and initialize OUT 
        // parameters for the WriteEntityChunks 
        // method.
        DWORD pcbSent = 0;
        BOOL pfCompletionExpected = FALSE;

        // Write the entity chunks to
        // the response stream.
        HRESULT hr =
            m_response->WriteEntityChunks
                (&dataChunk,
                 1,
                 FALSE,
                 FALSE,
                 &pcbSent,
                 &pfCompletionExpected);

        // Throw an exception if the call
        // to WriteEntityChunks is not a 
        // success.
        ThrowOnFail(hr);        
    }

    // Tests an HRESULT for success.
    // hr: the HRESULT value to inspect.
    // throws: a _com_error if the HRESULT
    // parameter is not S_OK.
    static void ThrowOnFail(HRESULT hr)
    {
        if (FAILED(hr))
        {
            _com_error ce(hr);
            throw ce;
        }
    }
private:
    // Specify the IHttpResponse
    // pointer to write to.
    IHttpResponse* m_response;
};

// The CUser class is the wrapper 
// class for an IHttpUser pointer.
class CUser
{
public:
    // Creates the CUser class.
    // user: the IHttpUser pointer to reference.
    // throws: a _com_error exception if 
    // the IHttpUser parameter is NULL.
    CUser(IHttpUser* user)
        throw (_com_error)
    {
        // Throw an exception if the 
        // IHttpUser parameter is NULL.
        if (NULL == user)
        {
            _com_error ce(E_INVALIDARG);
            throw ce;
        }

        // Call ReferenceUser, which increments
        // the reference count for the user.
        user->ReferenceUser();
        // Assign the user to m_user.
        m_user = user;
    }

    // The CUser method is the public 
    // destructor for the CUser class.
    // The destructor calls the DereferenceUser
    // method on the IHttpUser pointer, and
    // sets that pointer to NULL.
    virtual ~CUser()
    {
        // Call DereferenceUser on the m_user private 
        // data, which decrements the reference count
        // on m_user. An IHttpUser will be deleted when 
        // its reference count goes to 0.
        m_user->DereferenceUser();
        // Set the m_user data to NULL.
        m_user = NULL;
    }

    // The CreateElement method converts 
    // the internal IHttpUser pointer and 
    // descendant data into an XML element.
    // doc: the MSXML2::IXMLDOMDocument3Ptr to use 
    // for creating elements and attributes.
    // return: a new IXMLDOMElementPtr pointer.
    // throws: a _com_error exception.
    MSXML2::IXMLDOMElementPtr CreateElement
    (
        MSXML2::IXMLDOMDocument3Ptr doc
    ) const throw (_com_error)
    {
        // Create a new XML element to return.
        MSXML2::IXMLDOMElementPtr userElement = 
            doc->createElement(L"user");

        // Call the GetPassword method 
        // on the IHttpUser pointer.
        PCWSTR passWordPCWSTR = 
            m_user->GetPassword();

        // Convert the PCWSTR to a wstring.
        wstring passWord =
            CConvert::ToString(passWordPCWSTR);

        // Add an attribute to the
        // userElement element.
        AddAttribute(L"passWord", L"[hidden]", 
                     userElement, doc);

        // Return the XML element.
        return userElement;
    }
protected:
    // The AddAttribute method creates a new XML 
    // attribute and appends it to the element
    // parameter.
    // name: the name of the attribute.
    // text: the text value of the attribute.
    // element: the XML element to 
    // append the new attribute to.
    // doc: the XML document to use for
    // creating attributes.
    // return: a new IXMLDOMAttributePtr.
    // throws: a _com_error exception.
    static MSXML2::IXMLDOMAttributePtr AddAttribute
    (
        const wstring& name,
        const wstring& text,
        MSXML2::IXMLDOMElementPtr element,
        MSXML2::IXMLDOMDocument3Ptr doc
    ) throw (_com_error)
    {
        // Create an attribute with the name.
        MSXML2::IXMLDOMAttributePtr attribute = 
            doc->createAttribute(name.c_str());
        // Set the text of the attribute to the text value.
        attribute->text = text.c_str();
        // Add the attribute to the passed element.
        element->setAttributeNode(attribute);
        // Return the new attribute to the caller.
        return attribute;
    }
private:
    // Specify the IHttpUser pointer 
    // to authenticate and authorize.
    IHttpUser* m_user;
};

// The CHttpResponseModule is a CHttpModule 
// class that handles response processing
// by creating a custom user and writing that
// user information to the response stream.
class CHttpResponseModule : public CHttpModule
{
public:
    // The CHttpResponseModule method is the public
    // constructor for the CHttpResponseModule class.
    CHttpResponseModule()
    {

    }

    // The CHttpResponseModule method is 
    // the public virtual destructor for 
    // the CHttpResponseModule class.
    virtual ~CHttpResponseModule()
    {

    }

    // The OnSendResponse method is the method 
    // supporting the RQ_SEND_RESPONSE event type.
    // pHttpContext: the current IHttpContext pointer.
    // pProvider: the current IHttpEventProvider pointer.
    // return: RQ_NOTIFICATION_CONTINUE.
    virtual 
    REQUEST_NOTIFICATION_STATUS
    OnSendResponse
    (
        IN IHttpContext* pHttpContext,
        IN OUT ISendResponseProvider* pProvider
    )
    {
        // Call the UNREFERENCED_PARAMETER macro because
        // the ISendResponseProvider is never used.
        UNREFERENCED_PARAMETER(pProvider);

        // If the IHttpContext is NULL, 
        // return RQ_NOTIFICATION_CONTINUE.
        if (NULL == pHttpContext)
        {
            return RQ_NOTIFICATION_CONTINUE;
        }

        // Retrieve the IHttpUser pointer 
        // from the IHttpContext pointer.
        IHttpUser* user = 
            pHttpContext->GetUser();

        // Retrieve the IHttpResponse pointer 
        // from the IHttpContext pointer.
        IHttpResponse* response = 
            pHttpContext->GetResponse();

        // Both the IHttpUser and 
        // IHttpResponse pointers must 
        // not be NUL to continue
        // response processing.
        if ((NULL == user) || (NULL == response))
        {
            return RQ_NOTIFICATION_CONTINUE;
        }

        // Wrap calls in a try-catch 
        // statement as a _com_error 
        // exception might be thrown.
        try
        {
            // Create a CUser wrapper
            // for the IHttpUser pointer.
            CUser userWrapper(user);

            // Create a new XML document.
            MSXML2::IXMLDOMDocument3Ptr 
                doc(__uuidof(MSXML2::DOMDocument60));

            // Get the user XML element from
            // the CUser class, and append 
            // this element to the XML document.
            MSXML2::IXMLDOMElementPtr userElement =
                userWrapper.CreateElement(doc);
            doc->appendChild(userElement);
                        
            // Create the string for writing 
            // the XML to the response stream.
            _bstr_t bstrXml = doc->xml;
            string xmlString = 
                "<?xml version=\"1.0\"?>" + bstrXml;

            // Reset the header for text/xml so that
            // browsers will display the XML correctly.
            HRESULT hr = 
                response->SetHeader(HttpHeaderContentType, 
                                    "text/xml", 
                                    (USHORT)strlen("text/xml"), 
                                     TRUE);

            // Do not throw an exception here.
            // If the header cannot be set, then
            // the user should be able to view
            // the XML by selecting the
            // "View\Source" menu item.

            // Clear the response before writing
            // the XML data to the response.
            response->Clear();

            // Create a writer.
            CResponseWriter writer(response);

            // Write the XML to the 
            // response stream.
            writer.Write(xmlString.c_str());
        }
        catch (_com_error& ce)
        {
            // Attempt to get the 
            // description of the error.
            _bstr_t description = 
                ce.Description();

            // Print the description if 
            // it is not empty.
            if (0 == description.length())
            {
                description = ce.ErrorMessage();            
            }
            
            // Set an error status on the 
            // IHttpResponse pointer.
            response->SetStatus(500, description, 0, ce.Error());
        }

        // Return the RQ_NOTIFICATION_CONTINUE message.
        return RQ_NOTIFICATION_CONTINUE;
    }
};

// The CHttpResponseFactory class implements the 
// IHttpModuleFactory interface and creates and 
// sets a new CHttpResponseModule listener for 
// the RQ_SEND_RESPONSE event on the 
// IHttpModuleRegistrationInfo pointer.
class CHttpResponseFactory : public IHttpModuleFactory
{
public:
    // The RegisterCHttpModule method creates a new 
    // CHttpResponseFactory pointer and sets this new 
    // CHttpResponseFactory pointer as the IHttpModuleFactory 
    // pointer on the IHttpModuleRegistrationInfo pointer.
    // dwServerVersion: the current server version.
    // pModuleInfo: the current 
    // IHttpModuleRegistrationInfo pointer.
    // pGlobalInfo: the current IHttpServer pointer.
    // return: the value returned from the the call to 
    // the SetRequestNotifications on the 
    // IHttpModuleRegistrationInfo pointer.
    static HRESULT RegisterCHttpModule
    (
        DWORD dwServerVersion,
        IHttpModuleRegistrationInfo* pModuleInfo,
        IHttpServer* pGlobalInfo
    )
    {
        // Create a new CHttpResponseFactory pointer.
        CHttpResponseFactory* moduleFactory = 
            new CHttpResponseFactory;

        // Test for NULL on the new 
        // CHttpResponseFactory pointer.
        if (NULL == moduleFactory)
        {
            // Return an out-of-memory error 
            // code if moduleFactory is NULL.
            return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
        }

        // Set the request notifications for RQ_SEND_RESPONSE 
        // messages on the new CHttpResponseFactory pointer.
        return pModuleInfo->SetRequestNotifications
                (moduleFactory,
                 RQ_SEND_RESPONSE,
                 0); 
    }

    // The GetHttpModule method creates a new 
    // CHttpResponseModule pointer and sets the 
    // new CHttpResponseModule on the ppModule parameter.
    // ppModule: the new CHttpResponseModule pointer to return.
    // pAllocator: currently unused.
    // return: ERROR_NOT_ENOUGH_MEMORY if the 
    // heap is exhausted; otherwise, S_OK.
    virtual
    HRESULT
    GetHttpModule
    (
        OUT CHttpModule** ppModule, 
        IN IModuleAllocator* pAllocator
    )
    {
        // Call the UNREFERENCED_PARAMETER macro with 
        // the IModuleAllocator pointer, because this
        // parameter is currently unused.
        UNREFERENCED_PARAMETER(pAllocator);

        // Set the dereferenced ppModule 
        // to a new CHttpResponseModule pointer.
        (*ppModule) = new CHttpResponseModule;

        // If the new CHttpResponseModule is 
        // NULL, return an error indicating 
        // that heap memory is exhausted.
        if (NULL == (*ppModule))
        {
            return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
        }

        // Return S_OK.
        return S_OK;
    }

    // The Terminate method calls delete on this.
    virtual 
    void
    Terminate()
    {
        delete this;
    }

protected:
    // The CHttpResponseFactory method is the
    // protected constructor for the 
    // CHttpResponseFactory class.
    CHttpResponseFactory()
    {

    }

    // The CHttpResponseFactory method is the 
    // protected virtual destructor for the
    // CHttpResponseFactory class.
    virtual ~CHttpResponseFactory()
    {

    }
};

// The RegisterModule method is the 
// main entry point for the DLL.
// dwServerVersion: the current server version.
// pModuleInfo: the current 
// IHttpModuleRegistrationInfo pointer.
// pGlobalInfo: the current IHttpServer pointer.
// return: the value returned by calling the static
// CHttpResponseFactory::RegisterCHttpModule method.
HRESULT
__stdcall
RegisterModule
(
    DWORD dwServerVersion,
    IHttpModuleRegistrationInfo* pModuleInfo,
    IHttpServer* pGlobalInfo
)
{
    return CHttpResponseFactory::RegisterCHttpModule
        (dwServerVersion,
         pModuleInfo,
         pGlobalInfo);
}

위의 코드는 응답 스트림에 다음과 유사한 XML을 씁니다.

<?xml version="1.0" ?>  
<user passWord="[hidden]" />  

모듈은 RegisterModule 함수를 내보내야 합니다. 프로젝트에 대한 모듈 정의(.def) 파일을 만들어 이 함수를 내보내거나 스위치를 사용하여 /EXPORT:RegisterModule 모듈을 컴파일할 수 있습니다. 자세한 내용은 연습: 네이티브 코드를 사용하여 Request-Level HTTP 모듈 만들기를 참조하세요.

필요에 따라 각 함수에 대한 호출 규칙을 명시적으로 선언하는 대신 호출 규칙을 사용하여 __stdcall (/Gz) 코드를 컴파일할 수 있습니다.

요구 사항

형식 Description
클라이언트 - Windows Vista의 IIS 7.0
- Windows 7의 IIS 7.5
- Windows 8의 IIS 8.0
- WINDOWS 10 IIS 10.0
서버 - Windows Server 2008의 IIS 7.0
- Windows Server 2008 R2의 IIS 7.5
- Windows Server 2012의 IIS 8.0
- Windows Server 2012 R2의 IIS 8.5
- WINDOWS SERVER 2016 IIS 10.0
제품 - IIS 7.0, IIS 7.5, IIS 8.0, IIS 8.5, IIS 10.0
- IIS Express 7.5, IIS Express 8.0, IIS Express 10.0
헤더 Httpserv.h

참고 항목

IHttpUser 인터페이스
IHttpUser::GetUserName 메서드
IHttpUser::GetRemoteUserName 메서드