I´m trying to access Sharepoint list data in Office 365 from an external website. I registered my app in Azure Active Directory and I've done all the process of creating and trusting a certifacte and getting the access token.
Add-Type -Path ".\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
$authenticationContext = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext -ArgumentList "https://login.microsoftonline.com/{myTenantId}/", $false
$cer = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cer.Import(".\WithPrivateKey.pfx", "privateKey", [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet)
$clientAssertion = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.ClientAssertionCertificate -ArgumentList "{myClientId}", $cer
$authenticationResult = $authenticationContext.AcquireToken("https://{tenantName}.sharepoint.com", $clientAssertion)
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "Bearer " + $authenticationResult.AccessToken)
I can successfully call to Sharepoint REST Api by presenting the access token in request headers.
$response = Invoke-RestMethod -Uri https://{myTenantName}.sharepoint.com/sites/devSite/_vti_bin/ListData.svc/TestList -Method Get -Headers $headers
However I can't do the same to access asmx endpoints, such as Lists.asmx, whenever I try to call any method on those services I get 401 UNAUTHORIZED
$body = '<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<GetList xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<listName>TestList</listName>
</GetList>
</soap12:Body>
</soap12:Envelope>'
$response = Invoke-WebRequest -Uri https://{myTenantName}.sharepoint.com/sites/site/_vti_bin/Lists.asmx -Method Post -ContentType 'application/soap+xml' -Headers $headers -Body $body
After sometime digging into the .net Sharepoint client sdk, I found how SharepointOnlineCredential class does it, thus allowing access to Sharepoint SOAP Services.
So, as said already by Fei Xue, the Azure AD token is not valid to access Sharepoint SOAP services (althoug the token is valid to allows access to REST services...). To access Sharepoint Online services, you will need to use some sort of claims authentication, either by requesting user consent or by directly using a known user and password.
As we can't use the .net SDK in our php app, we have investigated how the SDK creates the requests to get authenticated when using user credentials directly:
First send your authentication credentials as a SAML-WSSecurity POST request to the authentication endpoint https://login.microsoftonline.com/rst2.srf:
POST https://login.microsoftonline.com/rst2.srf
Content-Type: application/soap+xml; charset=utf-8
Content-Length: [calculate]
Host: login.microsoftonline.com
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust">
<S:Header>
<wsa:Action S:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</wsa:Action>
<wsa:To S:mustUnderstand="1">https://login.microsoftonline.com/rst2.srf</wsa:To>
<ps:AuthInfo xmlns:ps="http://schemas.microsoft.com/LiveID/SoapServices/v1" Id="PPAuthInfo">
<ps:BinaryVersion>5</ps:BinaryVersion>
<ps:HostingApp>Managed IDCRL</ps:HostingApp>
</ps:AuthInfo>
<wsse:Security>
<wsse:UsernameToken wsu:Id="user">
<wsse:Username>[user]</wsse:Username>
<wsse:Password>[password]</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</S:Header>
<S:Body>
<wst:RequestSecurityToken xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust" Id="RST0">
<wst:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</wst:RequestType>
<wsp:AppliesTo>
<wsa:EndpointReference>
<wsa:Address>sharepoint.com</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wsp:PolicyReference URI="MBI"></wsp:PolicyReference>
</wst:RequestSecurityToken>
</S:Body>
</S:Envelope>
The response, in xml format, will come with the security token in it:
....
<wst:RequestedSecurityToken>
<wsse:BinarySecurityToken Id="Compact0">t=EwA4A06hBwAUNfDkMme61kIdXqvj9tWnUbHtXWEAAREB5clgLb8J/VvxRFIKLUnd9SRyoBHmTHFk0viit2FMlGXak5NJKJhicT8MiZmgA2HoTrJM1EgXCNUpmWqrX1LQRNfs0PHEV4XncjI9lnphsSTiFSCDjmdCKtW4TmV8n18xJHvBtDUWdvCT2lBti8/gf1oiqD5lQBPtxr+d4OwNtJHADEKpC/YIoatcKqgxI480tlWOZHpEL1wifo5EDMDRRc985ObMCZ31fPdSpA7WIbDzlZYX9ou6Cq7EybrIHsAcr5cPIJ8y0FRUacma9+dMxqr/lILAIyAYz/GdTNffa2Q3zJOSWW5RcnigtCApHgf83HjW8DqC6NgTrXs6rpUDZgAACC/4JZlSLB3JCALIntkKmNtRl2JLvwUljkXrP5jg5ipK/J/fGF3oc46aP/YT3VnrrD6TCV5ZECki5ycYZ6JR5RDK6OSqI9c5FDfFS/YmSCcdcaJ1cG2Ug3Oz3w14mznYGwmvrgyGvw35aoyjnKZALw8OQ2Ddi97gbe03L4rrM7CxTGwEPgoKCK7USkwxZT+myLJASVhd29+eNsTqd7wuphhLrzbgYZ+7swlJb3oIJw/2T7YvJ4fTPByaLxGaBt7iry74aSh/RnXdH3snOQnsr63bXqqoDJGcj7A3aIpElw2LlW2/PGh84zke3corp2q/jg7PEKCnV8PYN2xiwSfqY9vNCny14xhHEPsK8FWDBOPDpgeC18qz+FpTN0rGUMXl20bxJGxGqnQ+s8k0Gu9yTxoZKWPSeVihJk6qUQo6KJb/NE/QRco94QDUjMYi+gccGN0D1ouUe+O0fb0InXeM+98qfXJLQAjoUtgS8rRJUAqFk5XVwebGbx0ICRv3Q/wiJ7T5yUryMBTtwbaGf/07QuGTv9CW2UTsV9zT1nMSRDfUpelZrgZt6huLnDRLC8yVHfXjndMwONdymxWcD9sLb8EcNmTUFHDfBrv8XFb50PNJAV4qvK8CgVmWu2C2GWXoZfYkaR6o6jpliQdT5NcNnb9wNy36OqDnIWl0ZNM1SOzVX0yQOLeaf8+1bslaafyYMAbhcAI=&p=
</wsse:BinarySecurityToken>
</wst:RequestedSecurityToken>
...
Then using the security token extracted from the previous response, you need to send a GET request to your tenant credentials endpoint: https://yourtenantname.sharepoint.com/_vti_bin/idcrl.svc/
You will need to send an Authorization header with the format: BPOSIDCRL + space + token. Like:
GET https://yourtenantname/_vti_bin/idcrl.svc/
Host: yourtenant.sharepoint.com
Authorization: BPOSIDCRL t=EwA4A06hBwAUNfDkMme61kIdXqvj9tWnUbHtXWEAAREB5clgLb8J/VvxRFIKLUnd9SRyoBHmTHFk0viit2FMlGXak5NJKJhicT8MiZmgA2HoTrJM1EgXCNUpmWqrX1LQRNfs0PHEV4XncjI9lnphsSTiFSCDjmdCKtW4TmV8n18xJHvBtDUWdvCT2lBti8
The response to this request will set a cookie that we need to capture and use in our next requests to the soap services:
Set-Cookie: SPOIDCRL=77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48U1A+VHJ1ZSwwaC5mfG1lbWJlcnNoaXB8MTAwMzdmZmU5NTc2YzdlZUBsaXZlLmNvbSwwIy5mfG1lbWJlcnNoaXB8Y2xvdWRAYXNlbWJsaWFkZXYub25taWNyb3NvZnQuY29tLDEzMTAxMjE4ODQ0Mzc0NDcxMjsxMzA5NTg5NTQ0NTAwMDAwMDAsRmFsc2UsUCtRcmlFSFRkRnZCNkJEREZFek1mK3RVaGlzZTZtdnl1R0N4aXpjaWpyRUdxZk1BN1RpdTJNdGN0VE42TVNjdi9Cbjd2OXRxS2VPaTBzWTdlTnRqNkFESmRubFM2S0ttVjdoeHRWNjdtY3FlQVQzYWJGeDFEVFd5dEJsOWZ3MDJkZ2JTakV3eUM3WTRIWXg0ek5UYUtvUTZacGFXR0NjZ0svZEtEbloya3ozdGFBblVPM1gvUkxBeUorYkZac2RGclBCRGF4aDNTMGpBTml2VTBzb0pJR0FFRmdsQzVaMWhxU28rekZFMU5UV01oMXphMjNPYUU0TjJUNHVjd1BlaEREKzR4Ry9yMWdXMC9zOWdTaGxTMlc1U29iVDhTY2NyYi80aG9Xb1Y2TWxva0t1bXBNOWc4cCtxb0xFL3dtaElDUm9MRGhQSXR1anhoSjlqb2lZY1RBPT0saHR0cHM6Ly9hc2VtYmxpYWRldi5zaGFyZXBvaW50LmNvbS9fdnRpX2Jpbi9pZGNybC5zdmMvPC9TUD4=; path=/; secure; HttpOnly
Finally by attaching this cookie to every request to Sharepoint Services we get authenticated responses:
POST https://yourtenantname.sharepoint.com/_vti_bin/Lists.asmx HTTP/1.1
Host: yourtenantname.sharepoint.com
Content-Type: application/soap+xml; charset=utf-8
Content-Length: [calculate]
Cookie: SPOIDCRL=77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48U1A+VHJ1ZSwwaC5mfG1lbWJlcnNoaXB8MTAwMzdmZmU5NTc2YzdlZUBsaXZlLmNvbSwwIy5mfG1lbWJlcnNoaXB8Y2xvdWRAYXNlbWJsaWFkZXYub25taWNyb3NvZnQuY29tLDEzMTAxMjExNjM5MjM3NTM1ODsxMzA5NTg5NTQ0NTAwMDAwMDAsRmFsc2UsdEFEQUZZSnZiMFF6cWxFSFlKOGRPN1d1cnJ5RzJvcGxTelBueWFMUzhrNitjenBGT0JVK292M1VkSWhydGU3TXFMOHRJaFFzazRrNHd5REFqMklDUDcyMWpES3hKWmZRZjdaUlZQeisrUi92c09Qak13em5ITkg4bHVEQXdKcVlLdE16NStoaU84cUtTRzNZWEJYbWF4SDk1cDZtSDlaMVRzaFVDRXZMZ3ZIbkt6aWlPclh4UDE2RDBmZHlTRWxsU0Radmt2Tkg0UHBLT2VGbjI5S25qSk9veDVha21TZVlIbTY2ZnF5S0tpOUJmMHdjRmlyelNRZzBWZTc4NW1JZ1ZaQUY2VTArVEI0QVRvVXRVVFFqTnd4ODJEZE9jbWlqQ25NUTUzUHUrWEFIT25lenFVb1dPTXovVWk5V2VSTUMvMWZiOUpsUmZMNlZaNjNaZDRVazB3PT0saHR0cHM6Ly9hc2VtYmxpYWRldi5zaGFyZXBvaW50LmNvbS9fdnRpX2Jpbi9pZGNybC5zdmMvPC9TUD4=; path=/; secure; HttpOnly
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<GetListCollection xmlns="http://schemas.microsoft.com/sharepoint/soap/" />
</soap12:Body>
</soap12:Envelope>
The token get from Azure AD by ADAL only used for the Office 365 REST API(Code above using OAuth2.0 which get an JSON Wet Token for the REST API). This token doesn't work for the SharePoint web service.
To use the SharePoint web service, we need to authenticate the SharePoint with
SharePoint Claims Authentication. More detail about SharePoint authentication you can refer to the links below:
https://msdn.microsoft.com/en-us/library/hh147177.aspx#SPO_RA_OverviewSPAuthentication
Related
I want to access an online program via the command line within a bash script. I've been told I can run a SOAP request in order to access the software. This is the request I've been told I can use.
POST /OnlineAnalysis/Service.asmx HTTP/1.1
Host: cydas.org
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://www.cydas.org/OnlineAnalysis/analyseKaryotype"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<analyseKaryotype xmlns="http://www.cydas.org/OnlineAnalysis/">
<strKaryotype>string</strKaryotype>
</analyseKaryotype>
</soap:Body>
</soap:Envelope>
I've never run a SOAP request before but it looks like I'm able to use the curl command based on this question. I've tried to model my curl command according to the link I posted
curl -X POST -H "POST /OnlineAnalysis/Service.asmx HTTP/1.1" -H "Content-Type: text/xml; charset=utf-8" -H "SOAPAction: \"http://www.cydas.org/OnlineAnalysis/analyseKaryotype\"" -H "Host: cydas.org" --data-binary #request.xml
And am getting this output
<HTML>
<HEAD>
<TITLE>405 Method Not Allowed</TITLE>
<BASE href="/error_docs/"><!--[if lte IE 6]></BASE><![endif]-->
</HEAD>
<BODY>
<H1>Method Not Allowed</H1>
The HTTP verb used to access this page is not allowed.<P>
<HR>
<ADDRESS>
Web Server at cydas.org
</ADDRESS>
</BODY>
</HTML>
<!--
- Unfortunately, Microsoft has added a clever new
- "feature" to Internet Explorer. If the text of
...
These are the contents of my request.xml file below
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<analyseKaryotype xmlns="http://www.cydas.org/OnlineAnalysis/">
<strKaryotype>46,XX,del(3)(p11)</strKaryotype>
</analyseKaryotype>
</soap:Body>
</soap:Envelope>
I'm not sure what the expected output is supposed to be yet because I can't run the program. I just want to get my SOAP request running properly.
try this:
curl -v "http://www.cydas.org/OnlineAnalysis/Service.asmx" -H "Content-Type: text/xml;charset=UTF-8" -H "SOAPAction: \"http://www.cydas.org/OnlineAnalysis/analyseKaryotype\"" -H "Connection: Keep-Alive" -H "Host: www.cydas.org" --data #request.xml
The server responded with the message: "The Karyotype del(3)(p11) is not valid:
Non-specified error in chromosome count element (del(3)(p11))"
Here's the complete response message:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<analyseKaryotypeResponse xmlns="http://www.cydas.org/OnlineAnalysis/">
<analyseKaryotypeResult>
<Original_ISCN_Formula>del(3)(p11)</Original_ISCN_Formula>
<IsPolyClonal>false</IsPolyClonal>
<IsValidKaryotype>false</IsValidKaryotype>
<Corrected_ISCN_Formula/>
<CloneSize>0</CloneSize>
<IsIncompleteKaryotype>false</IsIncompleteKaryotype>
<Ploidy>0</Ploidy>
<ErrorMessages>The Karyotype del(3)(p11) is not valid:
Non-specified error in chromosome count element (del(3)(p11))</ErrorMessages>
</analyseKaryotypeResult>
</analyseKaryotypeResponse>
</soap:Body>
</soap:Envelope>
cURL is a great tool, but if you want a nice gui you can try other tools like SoapUI or Postman for testing APIs. SoapUI is a standalone Java application and Postman is a plugin for Chrome. They're both free.
While I create the service provider and add the Inbound Authentication Config -> SAML2 Web SSO Configuration via Web UI of Identity Server admin panel everything works and I see the SAMLSSO provider in the expanded tab later.
Now I get stuck with creating the Service Provider and adding the SAMLSSO provider via API.
I am using the following services to do the work:
IdentityApplicationManagementService?wsdl - for creating service provider.
IdentitySAMLSSOConfigService?wsdl - for creating SAMLSSO provider.
I send the following request in order:
Firstly create the SAMLSSO provider:
POST /services/IdentitySAMLSSOConfigService.IdentitySAMLSSOConfigServiceHttpsSoap11Endpoint/ HTTP/1.1
Host: test.com
Connection: Keep-Alive
User-Agent: PHP-SOAP/5.6.11-1ubuntu3.4
Content-Type: text/xml; charset=utf-8
SOAPAction: "urn:addRPServiceProvider"
Content-Length: 1228
Authorization: Basic *****
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns1="http://dto.saml.sso.identity.carbon.wso2.org/xsd"
xmlns:ns2="http://org.apache.axis2/xsd">
<SOAP-ENV:Body>
<ns2:addRPServiceProvider>
<ns2:spDto>
<ns1:assertionConsumerUrl xsi:nil="true"/>
<ns1:assertionConsumerUrls>https://test.shib/Shibboleth.sso/SAML2/POST</ns1:assertionConsumerUrls>
<ns1:attributeConsumingServiceIndex xsi:nil="true"/>
<ns1:certAlias xsi:nil="true"/>
<ns1:defaultAssertionConsumerUrl>https://test.shib/Shibboleth.sso/SAML2/POST</ns1:defaultAssertionConsumerUrl>
<ns1:digestAlgorithmURI xsi:nil="true"/>
<ns1:idpInitSLOReturnToURLs xsi:nil="true"/>
<ns1:issuer>https://tesh.shib/shibboleth</ns1:issuer>
<ns1:loginPageURL xsi:nil="true"/>
<ns1:nameIDFormat xsi:nil="true"/>
<ns1:nameIdClaimUri xsi:nil="true"/>
<ns1:requestedAudiences xsi:nil="true"/>
<ns1:requestedClaims xsi:nil="true"/>
<ns1:requestedRecipients xsi:nil="true"/>
<ns1:signingAlgorithmURI xsi:nil="true"/>
<ns1:sloRequestURL xsi:nil="true"/>
<ns1:sloResponseURL xsi:nil="true"/>
</ns2:spDto>
</ns2:addRPServiceProvider>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Then I create the Service Provider with Inbound authentication config set with the SAMLSSO provider as mentioned here:
POST /services/IdentityApplicationManagementService.IdentityApplicationManagementServiceHttpsSoap11Endpoint/ HTTP/1.1
Host: test.com
Connection: Keep-Alive
User-Agent: PHP-SOAP/5.6.11-1ubuntu3.4
Content-Type: text/xml; charset=utf-8
SOAPAction: "urn:createApplication"
Content-Length: 1934
Authorization: Basic ****
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://model.common.application.identity.carbon.wso2.org/xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns2="http://org.apache.axis2/xsd">
<SOAP-ENV:Body>
<ns2:createApplication>
<ns2:serviceProvider>
<ns1:applicationName>tect_com</ns1:applicationName>
<ns1:claimConfig xsi:nil="true"/>
<ns1:description>Test SP</ns1:description>
<ns1:inboundAuthenticationConfig>
<ns1:inboundAuthenticationRequestConfigs>
<ns1:friendlyName xsi:nil="true"/>
<ns1:inboundAuthKey>https://test.shib/shibboleth</ns1:inboundAuthKey>
<ns1:inboundAuthType>samlsso</ns1:inboundAuthType>
<ns1:properties xsi:nil="true"/>
</ns1:inboundAuthenticationRequestConfigs>
<ns1:inboundAuthenticationRequestConfigs>
<ns1:friendlyName xsi:nil="true"/>
<ns1:inboundAuthKey></ns1:inboundAuthKey>
<ns1:inboundAuthType>openid</ns1:inboundAuthType>
<ns1:properties xsi:nil="true"/>
</ns1:inboundAuthenticationRequestConfigs>
<ns1:inboundAuthenticationRequestConfigs>
<ns1:friendlyName xsi:nil="true"/>
<ns1:inboundAuthKey></ns1:inboundAuthKey>
<ns1:inboundAuthType>passivests</ns1:inboundAuthType>
<ns1:properties xsi:nil="true"/>
</ns1:inboundAuthenticationRequestConfigs>
</ns1:inboundAuthenticationConfig>
<ns1:inboundProvisioningConfig xsi:nil="true"/>
<ns1:localAndOutBoundAuthenticationConfig xsi:nil="true"/>
<ns1:outboundProvisioningConfig xsi:nil="true"/>
<ns1:owner>
<ns1:tenantDomain>user.com</ns1:tenantDomain>
<ns1:userName>user</ns1:userName>
<ns1:userStoreDomain xsi:nil="true"/>
</ns1:owner>
<ns1:permissionAndRoleConfig xsi:nil="true"/>
<ns1:requestPathAuthenticatorConfigs xsi:nil="true"/>
<ns1:saasApp>true</ns1:saasApp>
<ns1:spProperties xsi:nil="true"/>
</ns2:serviceProvider>
</ns2:createApplication>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Both request are accepted. I can see the Service Provider in Web UI, but the section with SAML Web SSO Configuration is empty.
If I try to authenticate with my new SP everything works.
If I try add the same SAML SSO Config via Web UI it gives me an error that it already exists.
The table SP_INBOUND_AUTH is empty while creating SAMLSSO Config using API. But if I create the SAML Configuration using Web UI, I can see the record in SP_INBOUND_AUTH table.
What am I missing?
When creating the Service provider, it should be done in two steps.
creating a service provider for the given application name and the description (createApplication).
update it with other configurations (updateApplication).
So in your case, createApplication should be invoked only with application name and description. Then you have to invoke updateApplication operation and configure its inbound authentication, etc.
[1] https://docs.wso2.com/display/IS510/Using+the+Service+Provider+API#UsingtheServiceProviderAPI-createApplication
all. I have next problem. I want to connect to mailbox with Impersonation rights. User Admin has Impersonation rights, and i know how to do it in C#.
I have next code:
ExchangeServiceBindingProxy *proxy = new ExchangeServiceBindingProxy(endpoint.c_str());
soap *pSoap = proxy->soap;
pSoap->userid = "Admin";
pSoap->passwd = "PASSWORD";
pSoap->ntlm_challenge = "";
pSoap->authrealm = "Ursa-Minor";
pSoap->ssl_flags = SOAP_SSL_NO_AUTHENTICATION;
pSoap->keep_alive = true;
soap_mode(pSoap,SOAP_IO_KEEPALIVE);
string smtp = "User1#no-such-email.com";
pSoap->header = new struct SOAP_ENV__Header();
pSoap->header->ns3__RequestServerVersion = new _ns3__RequestServerVersion();
pSoap->header->ns3__RequestServerVersion->Version = ns3__ExchangeVersionType__Exchange2007_USCORESP1;
if(!smtp.empty())
{
pSoap->header->ns3__ExchangeImpersonation = new ns3__ExchangeImpersonationType();
pSoap->header->ns3__ExchangeImpersonation->ConnectingSID = new ns3__ConnectingSIDType();
pSoap->header->ns3__ExchangeImpersonation->ConnectingSID->union_ConnectingSIDType.PrimarySmtpAddress = &smtp;
pSoap->header->ns3__ExchangeImpersonation->ConnectingSID->__union_ConnectingSIDType = 3;
}
As a resault i have this request:
POST /ews/Exchange.asmx HTTP/1.1
Host: 192.168.0.49
User-Agent: gSOAP/2.8
Content-Type: text/xml; charset=utf-8
Content-Length: 1093
Connection: keep-alive
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGoAAAAYABgAggAAABoAGgBAAAAACAAIAFoAAAAIAAgAYgAAAAAAAACaAAAABYKBAk4ATwAtAFMAVQBDAEgALQBFAE0AQQBJAEwASQB2AGEAbgBJAHYAYQBuAKEcAIkJWxEWBsuOv7MjtBpHLDWAL8JCTJ28+8Uotrb6QFrMa88HavXFTG1ddTR1VQ==
SOAPAction: "http://schemas.microsoft.com/exchange/services/2006/messages/GetFolder"
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns3="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:ns1="http://schemas.microsoft.com/exchange/services/2006/messages">
<SOAP-ENV:Header>
<ns3:ExchangeImpersonation SOAP-ENV:mustUnderstand="1">
<ns3:ConnectingSID>
<ns3:PrimarySmtpAddress>User1#no-such-email.com</ns3:PrimarySmtpAddress>
</ns3:ConnectingSID>
</ns3:ExchangeImpersonation>
<ns3:RequestServerVersion SOAP-ENV:mustUnderstand="1" Version="Exchange2007_SP1"></ns3:RequestServerVersion></SOAP-ENV:Header><SOAP-ENV:Body><ns1:GetFolder xsi:type="ns1:GetFolderType"><ns1:FolderShape><ns3:BaseShape>AllProperties</ns3:BaseShape></ns1:FolderShape><ns1:FolderIds><ns3:DistinguishedFolderId Id="msgfolderroot" xsi:type="ns3:DistinguishedFolderIdType"></ns3:DistinguishedFolderId></ns1:FolderIds></ns1:GetFolder></SOAP-ENV:Body>
</SOAP-ENV:Envelope>
It seems legit, but server response return error:
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode xmlns:a="http://schemas.microsoft.com/exchange/services/2006/types">a:ErrorInternalServerError</faultcode>
<faultstring xml:lang="en-US">An internal server error occurred. The operation failed.</faultstring>
<detail>
<e:ResponseCode xmlns:e="http://schemas.microsoft.com/exchange/services/2006/errors">ErrorInternalServerError</e:ResponseCode>
<e:Message xmlns:e="http://schemas.microsoft.com/exchange/services/2006/errors">An internal server error occurred. The operation failed.</e:Message>
</detail>
</s:Fault>
</s:Body>
</s:Envelope>
ns3:ExchangeImpersonation> !!! THERE IS SOMETHING WRONG
<ns3:RequestServerVersion SOAP-ENV:mustUnderstand="1" Version="Exchange2007_SP1"></ns3:RequestServerVersion>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:GetFolder xsi:type="ns1:GetFolderType">
<ns1:FolderShape><ns3:BaseShape>AllProperties</ns3:BaseShape></ns1:FolderShape>
<ns1:FolderIds>
<ns3:DistinguishedFolderId Id="msgfolderroot" xsi:type="ns3:DistinguishedFolderIdType"></ns3:DistinguishedFolderId>
</ns1:FolderIds>
</ns1:GetFolder>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Response even doesn`t have well formed xml.
Well, i don`t know how to solve this problem at this moment.
To remove the mustunderstand attribute from the wsdl2h-generated source code declarations that produces the SOAP Header, use wsdl2h option -k.
This is an old question, but I had a little update on it: To those that may be experiencing issues with mustunderstand appearing due to using some gsoap plugin (for me it was with the wsse plugin, I know mustunderstand is part of that standard, but the service I am calling does not)
Anyway, to solve this I edited the header files in gsoap/import to remove the mustunderstand parts. This stopped the wsse header having mustunderstand included.
I am using a SAP odata service and I added it as a web reference in visual studio 2012.
Uri serviceUri = new Uri("http://zbc.net:4521/sap/opu/odata/sap/Emp/", UriKind.Absolute);
Emp context = new Emp(serviceUri);
context.Credentials = new System.Net.NetworkCredential("loginanme", "pass");
var query = from b in context.Employees
where b.Role == "Admin"
select b;
foreach (var myObject in query)
{
Console.WriteLine("\n name: {0} | role: {1}", myObject.name, myObject.Role);
}
When I execute the code above, I get the following error:
"An error occurred while processing this request."
InnerException: "A missing or empty content type header was found when trying to read a message. The content type header is required."
this is the query that VS2012 produces:
Query: {http://zbc.net:4521/sap/opu/odata/sap/Emp/Employees()?$filter=Role eq 'Admin'}
StackTrace:
at Microsoft.Data.OData.ODataMessageReader.GetContentTypeHeader()
at Microsoft.Data.OData.ODataMessageReader.TryGetSinglePayloadKindResultFromContentType(IEnumerable`1& payloadKindResults, MediaType& contentType, Encoding& contentEncoding)
at Microsoft.Data.OData.ODataMessageReader.DetectPayloadKind()
at System.Data.Services.Client.Materialization.ODataMaterializer.CreateODataMessageReader(IODataResponseMessage responseMessage, ResponseInfo responseInfo, Boolean projectionQuery, ODataPayloadKind& payloadKind)
at System.Data.Services.Client.Materialization.ODataMaterializer.CreateMaterializerForMessage(IODataResponseMessage responseMessage, ResponseInfo responseInfo, Type materializerType, QueryComponents queryComponents, ProjectionPlan plan, ODataPayloadKind payloadKind)
at System.Data.Services.Client.MaterializeAtom..ctor(ResponseInfo responseInfo, QueryComponents queryComponents, ProjectionPlan plan, IODataResponseMessage responseMessage, ODataPayloadKind payloadKind)
at System.Data.Services.Client.QueryResult.CreateMaterializer(ProjectionPlan plan, ODataPayloadKind payloadKind)
at System.Data.Services.Client.QueryResult.ProcessResult[TElement](ProjectionPlan plan)
at System.Data.Services.Client.DataServiceRequest.Execute[TElement](DataServiceContext context, QueryComponents queryComponents)
Response from RESTClient (firefox add-on)
Status Code: 200 OK
Content-Encoding: gzip
Content-Length: 566
Content-Type: application/xml
Last-Modified: Tue, 09 Jul 2013 13:03:22 GMT
Server: SAP NetWeaver Application Server / ABAP 731
dataserviceversion: 2.0
Response body
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
xmlns:sap="http://www.sap.com/Protocols/SAPData">
<edmx:DataServices m:DataServiceVersion="2.0">
<Schema Namespace="Emp" xml:lang="en" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
<EntityType Name="Bank" sap:content-version="1">
<Key>
<PropertyRef Name="Admin"/>
</Key>
<Property Name="Name" Type="Edm.String" MaxLength="35" sap:label="Name"/>
<Property Name="street" Type="Edm.String" MaxLength="35" sap:label="Street"/>
<Property Name="Role" Type="Edm.String" MaxLength="35" sap:label="Role"/>
<Property Name="Region" Type="Edm.String" MaxLength="3" sap:label="Region"/>
</EntityType>
<EntityContainer Name="Emp" m:IsDefaultEntityContainer="true">
<EntitySet Name="Employees" EntityType="Emp.Employee" sap:deletable="false" sap:content-version="1"/>
</EntityContainer>
<atom:link rel="self" href="http://zbc.net:4521/sap/opu/odata/sap/Emp/$metadata" xmlns:atom="http://www.w3.org/2005/Atom"/>
<atom:link rel="latest-version" href="http://zbc.net:4521/sap/opu/odata/sap/Emp/$metadata"
xmlns:atom="http://www.w3.org/2005/Atom"/>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
From Fiddler I get the following response:
HTTP/1.1 401 Unauthorized
www-authenticate: Basic realm="SAP NetWeaver Application Server [SVD/800]"
content-length: 2180
content-type: text/html; charset=utf-8
server: SAP NetWeaver Application Server / ABAP 731
How come in fiddler I get a 401? How can I provide a login and pass in Fiddler so that I don't get a 401?
Thanks Vitek Karas MSFT for your suggestion. The issue is sovled by installing the latest version of WCF Data Services 5.6.0. and thanks to Maikel who tried in on our dev and was able to solve the issue.
I m working on wso2 admin services. I get url as http://localhost:9763/services/AuthenticationAdmin?wsdl for AuthencticationAdmin.
Now, when I hit the login operation, with admin,admin,127.0.0.1, I get true as return.
ESB console shows logged in.
Now, when I hit logout operation, I dont get any response.
Also I notice that header of the response does not contain any session ID.
My ESB is 4.6.0.
login request :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:aut="http://authentication.services.core.carbon.wso2.org">
<soapenv:Header/>
<soapenv:Body>
<aut:login>
<!--Optional:-->
<aut:username>admin</aut:username>
<!--Optional:-->
<aut:password>admin</aut:password>
<!--Optional:-->
<aut:remoteAddress>127.0.0.1</aut:remoteAddress>
</aut:login>
</soapenv:Body>
</soapenv:Envelope>
login response :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:loginResponse xmlns:ns="http://authentication.services.core.carbon.wso2.org">
<ns:return>true</ns:return>
</ns:loginResponse>
</soapenv:Body>
</soapenv:Envelope>
In the response, when I hit login I see, at bottom I only get 6 elements in header as follows :
> Date Tue, 25 Jun 2013 14:31:42 GMT
> Transfer-Encoding chunked
> #status# HTTP/1.1 200 OK
> Content-Type text/xml; charset=UTF-8
> Connection Keep-Alive
> Server WSO2-PassThrough-HTTP
Now, I dont get session ID. Can you please point out where m I going wrong?
My scenario is that I want to login to WSO2 and then hit some other admin service operation.
After some time debugging with the java client (see my other answer), I noticed that the SOAPUI Endpoint was not using the 9443 port that I was using in the Java client. See the image below.
The 8243 port was picked up from the WSDL by SOAPUI.
When I changed the SOAP UI Endpoint port from 8243 to 9443, the JSESSIONID gets returned in the response, as seen below:
HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=573D42750DE6C0A287E1582239EB5847; Path=/; Secure; HttpOnly
Content-Type: text/xml;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 26 Jun 2013 22:14:20 GMT
Server: WSO2 Carbon Server
<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns:loginResponse xmlns:ns="http://authentication.services.core.carbon.wso2.org"><ns:return>true</ns:return></ns:loginResponse></soapenv:Body></soapenv:Envelope>
I have no idea what the difference is between the ports 8243 and 9443, or why one returns a JSESSIONID and the other doesn't.
You could try accessing the server using a java client. There is an example here. You could try this example and dump out the SOAP message to see the difference against what you are seeing in SOAPUI.
I'm wondering if the example axis client's setManageSession(true) does some magic on the session:
public static void main(String[] args) throws
RemoteException, AuthenticationAdminAuthenticationExceptionException {
System.setProperty("javax.net.ssl.trustStore",
SampleConstants.CLIENT_TRUST_STORE_PATH);
System.setProperty("javax.net.ssl.trustStorePassword",
SampleConstants.KEY_STORE_PASSWORD);
System.setProperty("javax.net.ssl.trustStoreType",
SampleConstants.KEY_STORE_TYPE);
AuthenticationAdminStub stub =
new AuthenticationAdminStub(
"https://localhost:9443/services/AuthenticationAdmin");
ServiceClient client = stub._getServiceClient();
Options options = client.getOptions();
options.setManageSession(true);
Login login = new Login();
login.setUsername("admin");
login.setPassword("admin");
stub.login(login);
ServiceContext serviceContext = stub.
_getServiceClient().getLastOperationContext().getServiceContext();
String sessionCookie = (String) serviceContext
.getProperty(HTTPConstants.COOKIE_STRING);
System.out.println(sessionCookie);
}
The above code prints out something similar to the following:
JSESSIONID=844ECBED015805A24FF9DBD5F5A56C8D; Path=/; Secure=null; HttpOnly=null