locked
errorCode=0x803d0005 WWSAPI with EWS , 'Unauthorized request. RRS feed

  • Question

  • Hi all

    I have a problem with WWSAPI & EWS with this code, and when request to server always a error "

    The server returned HTTP status code '401 (0x191)' with text 'Unauthorized'.
    The requested resource requires user authentication." I used C# with EXchangeSevervice (below ), It's work fine. I think it relate to certificate. Please help me, thanks.

    int _tmain(int argc, _TCHAR* argv[])
    {
    	HRESULT hr = NOERROR;
    	WS_ERROR* error = NULL;
    	WS_HEAP* heap = NULL;
    	WS_SERVICE_PROXY* proxy = NULL;
    
    	WS_CHANNEL_PROPERTY channelProperties[4]; // hold up to 4 channel properties
    	ULONG channelPropertyCount = 0;
    
    	WS_ENVELOPE_VERSION soapVersion = WS_ENVELOPE_VERSION_SOAP_1_1;
    	channelProperties[channelPropertyCount].id = WS_CHANNEL_PROPERTY_ENVELOPE_VERSION;
    	channelProperties[channelPropertyCount].value = &soapVersion;
    	channelProperties[channelPropertyCount].valueSize = sizeof(soapVersion);
    	channelPropertyCount++;
    
    	WS_ADDRESSING_VERSION addressingVersion = WS_ADDRESSING_VERSION_TRANSPORT;
    	channelProperties[channelPropertyCount].id = WS_CHANNEL_PROPERTY_ADDRESSING_VERSION;
    	channelProperties[channelPropertyCount].value = &addressingVersion ;
    	channelProperties[channelPropertyCount].valueSize = sizeof(addressingVersion );
    	channelPropertyCount++;
    
    	DWORD dwWS_HTTP_HEADER_AUTH_SCHEME_NEGOTIATE = WS_HTTP_HEADER_AUTH_SCHEME_NEGOTIATE;
    	WS_SECURITY_BINDING_PROPERTY rgSecBindingProp[1];
    	rgSecBindingProp[0].id = WS_SECURITY_BINDING_PROPERTY_HTTP_HEADER_AUTH_SCHEME;
    	rgSecBindingProp[0].valueSize = sizeof(DWORD);
    	rgSecBindingProp[0].value = (void*)&dwWS_HTTP_HEADER_AUTH_SCHEME_NEGOTIATE;
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    
    
    	WS_STRING_WINDOWS_INTEGRATED_AUTH_CREDENTIAL intAuthCredential = {}; // zero out the struct 
    	WS_STRING userName = WS_STRING_VALUE(L"myaccount");
    	WS_STRING passWord = WS_STRING_VALUE(L"mypass");
    	intAuthCredential.credential.credentialType = WS_STRING_WINDOWS_INTEGRATED_AUTH_CREDENTIAL_TYPE; 
    	intAuthCredential.username = userName;
    	intAuthCredential.password = passWord;
    	 
      
    	WS_HTTP_HEADER_AUTH_SECURITY_BINDING  authBinding = {};
    	authBinding.binding.bindingType = WS_HTTP_HEADER_AUTH_SECURITY_BINDING_TYPE;
    	authBinding.clientCredential =&intAuthCredential.credential;
    	authBinding.binding.properties = rgSecBindingProp;
    	authBinding.binding.propertyCount = WsCountOf(rgSecBindingProp);
    
    	//ignore some ssl errors
    	DWORD dwIgnoreCnSertValue = WS_CERT_FAILURE_CN_MISMATCH;
    	WS_SECURITY_BINDING_PROPERTY rgSslProp[1];
    	rgSslProp[0].id = WS_SECURITY_BINDING_PROPERTY_CERT_FAILURES_TO_IGNORE;
    	rgSslProp[0].valueSize = sizeof(DWORD);
    	rgSslProp[0].value = (void*)&dwIgnoreCnSertValue;
    
      
    
    	// declare and initialize an SSL transport security binding
    	WS_SSL_TRANSPORT_SECURITY_BINDING sslBinding = {}; // zero out the struct
    	sslBinding.binding.bindingType = WS_SSL_TRANSPORT_SECURITY_BINDING_TYPE; // set the binding type
    	sslBinding.binding.properties = rgSslProp;
    	sslBinding.binding.propertyCount =WsCountOf(rgSslProp);
    
    	// declare and initialize the array of all security bindings
    	WS_SECURITY_BINDING* securityBindings[2] = { &sslBinding.binding, &authBinding.binding };
    
    	// declare and initialize the security description
    	WS_SECURITY_DESCRIPTION securityDescription = {}; // zero out the struct
    	securityDescription.securityBindings = securityBindings;
    	securityDescription.securityBindingCount = WsCountOf(securityBindings);
    	securityDescription.properties = NULL;
    	securityDescription.propertyCount = 0;
          
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    	 
    	WS_STRING url=WS_STRING_VALUE(L"https://mycompany/ews/Exchange.asmx");
    	int result = 0;
    	WS_ENDPOINT_ADDRESS address = {}; 
    	address.url=url; 
     
     
    	// Create an error object for storing rich error information
    	hr = WsCreateError(
    		NULL, 
    		0, 
    		&error);
    	if (FAILED(hr))
    	{
    		return hr;
    	}
    
    	// Create a heap to store deserialized data
    	hr = WsCreateHeap(
    		/*maxSize*/ 8192, 
    		/*trimSize*/ 512, 
    		NULL, 
    		0, 
    		&heap, 
    		error);
    	if (FAILED(hr))
    	{
    		return hr;
    	}
    
    	// Create the proxy
    	hr = WsCreateServiceProxy(
    		WS_CHANNEL_TYPE_REQUEST, 
    		WS_HTTP_CHANNEL_BINDING, 
    		&securityDescription,
    		NULL, 
    		0, 
    		channelProperties,
    		channelPropertyCount,
    		&proxy, 
    		error);
    	 
    	if (FAILED(hr))
    	{
    		return hr;
    	}
        
    	hr = WsOpenServiceProxy(
    		proxy, 
    		&address, 
    		NULL, 
    		error);
    	if (FAILED(hr)) 
    	{ 
    		WsFreeServiceProxy(proxy); 
    		WsFreeHeap(heap); 
    		WsFreeError(error); 
    		return hr; 
    	} 
           
    	ResolveNamesType ReqType; 
    	ReqType.UnresolvedEntry = L"test";
    	ReqType.SearchScope = ResolveNamesSearchScopeTypeActiveDirectory;
    	ReqType.ContactDataShape=DefaultShapeNamesTypeIdOnly;
    	ReqType.ReturnFullContactData = true;
    	ReqType.ParentFolderIds = NULL;
    	ReqType.ParentFolderIdsCount = 0;
        ResolveNamesType_Init(&ReqType);
    
    	ResolveNamesResponseType* pRespType;
      
    	hr = ExchangeServiceBinding_ResolveNames(proxy,
    		&ReqType,
    		&pRespType,
    		heap,
    		NULL,
    		0,
    		NULL,
    		error);
    WsCloseServiceProxy(proxy, NULL, error); 
    	WsFreeServiceProxy(proxy); 
    	WsFreeHeap(heap); 
    	WsFreeError(error); 
    	 }

    C# code:

     class Program
        {
            static void Main(string[] args)
            {
                try
                {
                    ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
    
                    service.UseDefaultCredentials = false;
                    service.Credentials = new NetworkCredential("**", "******");
                    service.Url = new Uri("https://mycompany/EWS/exchange.asmx");
                    Console.WriteLine(service.Url);
                   
                    service.TraceEnabled = true; 
                    EmailMessage message = new EmailMessage(service);
                    message.Subject = "Hello from the EWS Managed API";
                    message.Body = "Bau very ga";
                    message.ToRecipients.Add("recipient..");
                    //message.Save();
                    message.SendAndSaveCopy();  
                }catch(Exception e)
                {
                    Console.WriteLine(e.ToString());
                }
              
            }
        }
    

    Wednesday, March 7, 2012 11:16 AM

Answers

  • Hi, all.. Sorry because your mistake about username.

    In C++: user name must like: user@yourcompany.local ( instead of user@yourcompany.com ).

    In C#: username must like: user 

    This example work fine!

    Thanks

    Bao Doan


    • Edited by thaibao Thursday, March 8, 2012 1:31 AM
    • Marked as answer by thaibao Friday, March 9, 2012 10:13 AM
    Thursday, March 8, 2012 1:31 AM