How do I configure ServiceStack.net to authenticate using the OAuthProvider against Google - google-api

I'd like to configure ServiceStack.net to authenticate using the OAuthProvider against Google. Here is my current configuration:
Plugins.Add(new AuthFeature(() => new AuthUserSession(),
new IAuthProvider[] {
new OAuthProvider(appSettings,
"https://accounts.google.com/o/oauth2/auth",
"google",
"Google Client ID",
"Google Client secret")
}));
However, I get the following error:
response Status
error Code ArgumentNullException
message String reference not set to an instance of a String. Parameter name: s
stack Trace
[Auth: 8/19/2013 7:48:47 PM]: [REQUEST: {provider:google}] System.ArgumentNullException: String reference not set to an instance of a String. Parameter name: s at System.Text.Encoding.GetBytes(String s) at ServiceStack.ServiceInterface.Auth.OAuthUtils.PercentEncode(String s) at ServiceStack.ServiceInterface.Auth.OAuthAuthorizer.<>c__DisplayClass3.<MakeSignature>b__1(String k) at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Linq.Buffer`1..ctor(IEnumerable`1 source) at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source) at ServiceStack.ServiceInterface.Auth.OAuthAuthorizer.MakeSignature(String method, String base_uri, Dictionary`2 headers) at ServiceStack.ServiceInterface.Auth.OAuthAuthorizer.AcquireRequestToken() at ServiceStack.ServiceInterface.Auth.OAuthProvider.Authenticate(IServiceBase authService, IAuthSession session, Auth request) at ServiceStack.ServiceInterface.Auth.AuthService.Authenticate(Auth request, String provider, IAuthSession session, IAuthProvider oAuthConfig) at ServiceStack.ServiceInterface.Auth.AuthService.Post(Auth request) at lambda_method(Closure , Object , Object ) at ServiceStack.ServiceHost.ServiceRunner`1.Execute(IRequestContext requestContext, Object instance, TRequest request)
According to the network trace, nothing ever hits Google.
Thanks!

I also had this problem. My solution was to double check the Web.Config in the root of the service. I didn't have the ServiceStack OAuth Config setup correctly there.
Use the keys:
<add key="oauth.GoogleOpenId.RedirectUrl" value="http://bootstrapapi.apphb.com/friends"/>
<add key="oauth.GoogleOpenId.CallbackUrl" value="http://bootstrapapi.apphb.com/api/auth/GoogleOpenId"/>
and the Google IAuthProvider
new GoogleOpenIdOAuthProvider(appSettings), //Sign-in with Google OpenId

Related

how to retrieve the same error response received by webclient in spring reactive

I reveive a request from client, and to process that I have to make request to azure resource management app.
Now, if the client passes me incorrect info, and if I make direct call from postman to azure API, it returns me very useful info. refer below (below call contains incorrect query params) :
i get response like below in case of incorrect param passed :
{
"error": {
"code": "ResourceNotFound",
"message": "The Resource 'Microsoft.MachineLearningServices/workspaces/workspace_XYZ/onlineEndpoints/Endpoint_XYZ' under resource group 'resourceGroupXYZ' was not found. For more details please go to https://aka.ms/ARMResourceNotFoundFix"
}
}
Now, I make this query using springboot reactive webclient API.
But I am not sure how to pass the same error back as it contains very useful info. The exception handling methods calls like onErrorReturn etc did not help me here to get the original error msg. :
response = getWebClient()
.post()
.uri(apiUrl)
.headers(h -> authToken)
.retrieve()
.bodyToMono(String.class)
// .onErrorReturn(response)
.block();

JSON parse error: Can not set com.google.api.services.androidmanagement.v1.model.KioskCustomization field

Issue while creating Policy In Android Management API,Iam Using Spring Boot as BackEnd.
this is my request:
{
"name": "testpolicy",
"applications": [
{
"packageName": "com.adobe.reader",
"installType": "REQUIRED_FOR_SETUP",
"defaultPermissionPolicy": "GRANT"
}
],
"kioskCustomization":{
"powerButtonActions": "POWER_BUTTON_ACTIONS_UNSPECIFIED",
"systemErrorWarnings": "SYSTEM_ERROR_WARNINGS_UNSPECIFIED",
"systemNavigation": "SYSTEM_NAVIGATION_UNSPECIFIED",
"statusBar": "STATUS_BAR_UNSPECIFIED",
"deviceSettings": "DEVICE_SETTINGS_UNSPECIFIED"
},
"kioskCustomLauncherEnabled": true
}
This is my response:
JSON parse error: Can not set com.google.api.services.androidmanagement.v1.model.KioskCustomization field com.google.api.services.androidmanagement.v1.model.Policy.kioskCustomization to java.util.LinkedHashMap; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not set com.google.api.services.androidmanagement.v1.model.KioskCustomization field com.google.api.services.androidmanagement.v1.model.Policy.kioskCustomization to java.util.LinkedHashMap (through reference chain: com.google.api.services.androidmanagement.v1.model.Policy["kioskCustomization"])
code written in the controller:
#PostMapping("/policies")
public ResponseEntity<com.google.api.services.androidmanagement.v1.model.Policy> savePolicy(
#RequestBody Policy policy, #RequestParam String enterpriseId) throws Exception {
}
control is not even coming inside the controller
I tried your request in Quickstart and did not encounter any error, the cause of your error may come from your implementation (Parser being used, or the format when typed) , I suggest that you try your request in quickstart to confirm that there is nothing wrong with your request.
Also you can check this documentation for a sample app that demonstrates how to provision a corporate-owned, single-use (COSU) device, and send it a reboot command. The app uses the Android Management API Java client library.

How to exchange JWT token for Credentials in Cognito Identity Pool in .NET Core 3.1 WebApi

Broad Overview: I am trying to create a .Net Core 3.1 WebApi backend that is authenticated against Amazon Cognito. I want to use the Amazon-hosted sign-in page(s) provided by Cognito. I want to leverage Cognito Identity Pool to provide temporary scoped credentials for users after they have logged in. I cannot figure out how to exchange the Cognito token to create the Credentials to call AWS services.
Technology Overview
.NET Core 3.1 WebApi
Amazon Cognito User Pool for initial authentication
Amazon Identity Pool for defining permissions (Roles) for logged in users
Deployed on AWS via API Gateway + Lambda using the AWS Serverless framework (basically CloudFormation)
Currently both of the following work:
Add [Authorize] attribute to a controller endpoint and access the URL in a browser. This re-directs me to the Cognito-hosted login page and, upon successful login, returns me back to the controller/endpoint and I am authorized.
Create a separate Client application and login to AWS Cognito. Pass the JWT token in the Authorization HTTP header when calling APIs from the client and the Authorization succeeds and API access is granted.
In both cases, the access to the API is permitted however the AmazonServiceClient instances that are created in the WebApi are granted the permissions associated with the Lambda function (which is the proper behavior).
Problem
I need to create AmazonServiceClients whose credentials match the Role defined by the Cognito Identity Pool.
To do this, I need to exchange token provided by logging into Cognito User Pool for temporary credentials in the Identity Pool.
Virtually ALL examples and documentation I can find on this process define how to manually login to Cognito using the API (not the hosted web UI), and then using the API response to create a CognitoUser and then get credentials from the Identity Pool using that user.
The closest (though super brief) documentation I can find to do what I need is from AWS here: https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/cognito-creds-provider.html
// Authenticate user through Facebook
string facebookToken = GetFacebookAuthToken();
// Add Facebook login to credentials. This clears the current AWS credentials
// and retrieves new AWS credentials using the authenticated role.
credentials.AddLogin("graph.facebook.com", facebookAccessToken);
While that example uses Facebook, conceptually it should be the same for any provider (Facebook, Google, Twitter, OpenId, etc.).
My Current Attempt
I have registered CognitoAWSCredentials as a Scoped service as it is user-specific and therefore should only exist as long as the API request session exists.
RegionEndpoint region = Configuration.GetAWSOptions().Region;
services.AddScoped(_ => new CognitoAWSCredentials(Settings.CognitoIdentityPoolId, region));
I have created an event handler that gets triggered when the OpenIdConnect event 'OnTokenValidated' is fired. This happens after I login to the Cognito hosted web UI and am redirected back to my API.
In this handler I can call:
CognitoAWSCredentials creds = services.BuildServiceProvider().GetRequiredService<CognitoAWSCredentials>();
creds.AddLogin( ... ??? ...);
(note: since I'm setting all this up in the Startup.ConfigureServices(IServiceCollection services) method, I am building an IServiceProvider instance each time authentication succeeds... which may be inefficient but I haven't figured out another way to access a scoped service inside the ConfigureServices method)
All this preamble to say that I cannot find a set of values for the AddLogin call which allow this test call to succeed:
ImmutableCredentials immCreds = creds.GetCredentials();
Relevant Data Structures
In the event handler where I can call AddLogin, I have access to: Microsoft.AspNetCore.Authentication.OpenIdConnect.TokenValidatedContext which in particular contains:
Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage with:
access_token
id_token
refresh_token
System.IdentityModel.Tokens.Jwt.JwtSecurityToken with:
{
{
"alg": "RS256",
"kid": "**************************"
}. {
"at_hash": "**************************",
"sub": "**************************",
"email_verified": true,
"iss": "https://cognito-idp.ca-central-1.amazonaws.com/**************************",
"cognito:username": "**************************",
"nonce": "**************************",
"aud": "**************************",
"event_id": "**************************",
"token_use": "id",
"auth_time": 1595260191,
"exp": 1595263791,
"iat": 1595260191,
"email": "**************************"
}
}
I have tried using the iss value as the providerName in AddLogin, and either the access_token or id_token but neither work.
Does anyone know what I need to use for AddLogin in order for Cognito to create Identity Pool credentials for me based upon a JWT token from a Cognito User Pool login?
unless I missed it, I haven't seen documentation that states this, but even though all the Issuer fields on the various data structures include the 'https://', you need to strip it before using the Issuer as the providerName on the AddLogin call. ugh.
CognitoAWSCredentials creds = services.BuildServiceProvider().GetRequiredService<CognitoAWSCredentials>();
string shortIssuer = tokenValidatedContext.SecurityToken.Issuer;
if (shortIssuer.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase)) shortIssuer = shortIssuer.Substring("https://".Length);
if (shortIssuer.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase)) shortIssuer = shortIssuer.Substring("http://".Length);
creds.AddLogin(shortIssuer, tokenValidatedContext.TokenEndpointResponse.IdToken);
now, the above code has a problem as the services.BuildServiceProvider(). part means the credentials object I modify isn't global (only local to the service provider I built here I think), but that's a different issue - just noting that in case anyone is copying this code.
services...<other authentication setup>...
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.ClientId = Settings.CognitoClientId;
options.MetadataAddress = CognitoMetadataAddress;
options.ResponseType = OpenIdConnectResponseType.Code;
options.SaveTokens = true;
options.UsePkce = true;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidIssuers = new string[] { Settings.CognitoAuthority },
ValidateAudience = true,
ValidAudiences = new string[] { Settings.CognitoClientId }
};
options.Events = new OpenIdConnectEvents() {
OnTokenValidated = tokenValidatedContext => {
CognitoAWSCredentials creds = services.BuildServiceProvider().GetRequiredService<CognitoAWSCredentials>();
string shortIssuer = tokenValidatedContext.SecurityToken.Issuer;
if (shortIssuer.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase)) shortIssuer = shortIssuer.Substring("https://".Length);
if (shortIssuer.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase)) shortIssuer = shortIssuer.Substring("http://".Length);
creds.AddLogin(shortIssuer, tokenValidatedContext.TokenEndpointResponse.IdToken);
return Task.CompletedTask;
}
};
})
(some code removed to focus on specifically the OpenId Connect event and the CognitoAWSCredentials init)

AWS Signed requests when indexing documents with Spring Data Elasticsearch

I'm unable to index a document in the AWS-hosted Elasticsearch cluster using signed requests.
Infrastructure setup
Elasticsearch version: 7.4
Access policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "es:*",
"Resource": "arn:aws:es:<RESOURCE>/*"
}
]
}
Code
The following code loads the client libraries using version 7.6. I have also downgraded them to match the cluster version but with no effect.
build.gradle
// ...
implementation("org.springframework.data:spring-data-elasticsearch")
implementation("org.elasticsearch:elasticsearch")
implementation("org.elasticsearch.client:elasticsearch-rest-high-level-client")
// ...
The client configuration definition. The environment variables like AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_PROFILE are filled.
#Configuration
public class ElasticsearchClientConfig extends AbstractElasticsearchConfiguration {
#Value("${elasticsearch.host}")
private String elasticsearchHost;
#Value("${elasticsearch.port}")
private int elasticsearchPort;
#Override
#Bean
public RestHighLevelClient elasticsearchClient() {
var SERVICE_NAME = "es";
var REGION = "us-east-1";
var defaultCP = new DefaultAWSCredentialsProviderChain();
AWS4Signer signer = new AWS4Signer();
signer.setServiceName(SERVICE_NAME);
signer.setRegionName(REGION);
HttpRequestInterceptor interceptor = new AWSRequestSigningApacheInterceptor
(SERVICE_NAME, signer, defaultCP);
RestClientBuilder restClientBuilder = RestClient
.builder(HttpHost.create(elasticsearchHost))
.setHttpClientConfigCallback(hacb -> hacb.addInterceptorLast(interceptor));
return new RestHighLevelClient(restClientBuilder);
}
}
Where the AWSRequestSigningApacheInterceptor is taken from here.
So far so good. When the application loads it's accessing the cluster and manages to create relevant indices correctly.
Problem
There problem is when performing save() operation from Spring Data repository. There are two requests made to ES
#Override
public <S extends T> S save(S entity) {
Assert.notNull(entity, "Cannot save 'null' entity.");
operations.save(entity, getIndexCoordinates());
operations.indexOps(entity.getClass()).refresh();
return entity;
}
Looking at the logs the first one succeeds. The following error ends the second call
org.elasticsearch.client.ResponseException: method [POST], host [HOST], URI [/asset/_refresh?ignore_throttled=false&ignore_unavailable=false&expand_wildcards=open&allow_no_indices=true], status line [HTTP/1.1 403 Forbidden]
{"message":"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details."}
Looking at more detailed logs for both operations
Call for saving (ends with 200 status code):
com.amazonaws.auth.AWS4Signer : AWS4 Canonical Request: '"PUT
/asset/_doc/2
timeout=1m
content-length:128
content-type:application/json
host:<HOST>
user-agent:Apache-HttpAsyncClient/4.1.4 (Java/11.0.2)
x-amz-date:20200715T110349Z
content-length;content-type;host;user-agent;x-amz-date
55c1faf282ca0da145667bf7632f667349dbe30ed1edc64439cec2e8d463e176"
2020-07-15 13:03:49.240 DEBUG 3942 --- [nio-8080-exec-1] com.amazonaws.auth.AWS4Signer : AWS4 String to Sign: '"AWS4-HMAC-SHA256
20200715T110349Z
20200715/us-east-1/es/aws4_request
76b6547ad98145ef7ad514baac4ce67fa885bd56073e9855757ade19e28f6fec"
Call for refreshing (ends with 403 status code):
com.amazonaws.auth.AWS4Signer : AWS4 Canonical Request: '"POST
/asset/_refresh
host:<HOST>
user-agent:Apache-HttpAsyncClient/4.1.4 (Java/11.0.2)
x-amz-date:20200715T110349Z
host;user-agent;x-amz-date
bbe4763d6a0252c6e955bcc4884e15035479910b02395548dbb16bcbad1ddf95"
2020-07-15 13:03:49.446 DEBUG 3942 --- [nio-8080-exec-1] com.amazonaws.auth.AWS4Signer : AWS4 String to Sign: '"AWS4-HMAC-SHA256
20200715T110349Z
20200715/us-east-1/es/aws4_request
189b39cf0475734e29c7f9cd5fd845fc95f73c95151a3b6f6d430b95f6bee47e"
When indexing documents directly using lower-level clients everything works fine. I suspect that signature calculation behaves incorrectly for subsequent API calls.
I had a same issue, in my case i'm using AWSRequestSigningApacheInterceptor, and i had old version. after upgrade to latest version, it's fixed.

CrmDataContext.GetEntities query - ERROR: 0x80040204 - Invalid user auth

I created domain user 'jsmith' in Active Directory and i've added that domain account as a user in Dynamics CRM. My goal here is to execute code with a service account that is in the PrivUserGroup for the organization while impersonating 'jsmith'. I instantiate the CrmDataContext by passing it an instance of CrmConnection. When calling the constructor of the CrmConnection I pass it the name of my connection string in the application config file then I set the ImpersonatedUser property to the system user id of 'jsmith'. One thing to note is that I'm using a console application to run this. View my code below:
Connection String in app.config:
<add name="Crm" connectionString="Authentication Type=AD; Server=http://dev01/myorg; User ID=myorgdomain\sv-crm; Password=password123" />
CrmDataContext and GetEntities code:
var connection = new CrmConnection("Crm");
connection.ImpersonatedUser = Guid.Parse("1937F45C-8EB4-E011-8FE4-005056887B79");
var crm = new CrmDataContext(connection);
var contacts = crm.GetEntities("contacts")
if(contacts.Count() > 0) //the call to Count() is where the error gets thrown. Invalid user auth.
//do something
I have no issues when trying to impersonate with my own system user id which is tied to my AD domain account that I'm logged in as while running the tests. I get results back just fine so I know there is no issue with the service account that is being used to execute the code. I've even assigned 'jsmith' to the same business unit and put him in the same roles that I'm in (which is System Administrator) and I still get the Invalid user auth. What could I possibly be missing. Below is error information in the trace file on the server. In the trace information below the one thing that does stick out is the first line: "[2011-07-22 18:14:08.0] Process: w3wp |Organization:f827deb3-c6cc-df11-bc07-005056887b79 |Thread: 6 |Category: Exception |User: 822138f1-c574-e011-9dca-005056887b79 |Level: Error | CrmException..ctor*". The User id that is being display is my system user id. It seems like it would show the id of the service account from the connection string or the id 'jblow' who is being impersonated. Any ideas would be greatly appreciated.
[2011-07-22 18:14:08.0] Process: w3wp |Organization:f827deb3-c6cc-df11-bc07-005056887b79 |Thread: 6 |Category: Exception |User: 822138f1-c574-e011-9dca-005056887b79 |Level: Error | CrmException..ctor
at CrmException..ctor(Int32 errorCode, Object[] arguments)
at SecurityHelper.VerifyAndReturnCurrentCallerId(Guid userId, Guid callerId, Guid orgId)
at CrmWebService.get_CurrentCallerId()
at CrmService.Execute(Request request)
at RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
at RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at LogicalMethodInfo.Invoke(Object target, Object[] values)
at WebServiceHandler.Invoke()
at WebServiceHandler.CoreProcessRequest()
at SyncSessionlessHandler.ProcessRequest(HttpContext context)
at CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
at ApplicationStepManager.ResumeSteps(Exception error)
at HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
at HttpRuntime.ProcessRequestInternal(HttpWorkerRequest wr)
at HttpRuntime.ProcessRequestNoDemand(HttpWorkerRequest wr)
at ISAPIRuntime.ProcessRequest(IntPtr ecb, Int32 iWRType)
>Crm Exception: Message: Invalid user auth., ErrorCode: -2147220988
[2011-07-22 18:14:08.0] Process: w3wp |Organization:f827deb3-c6cc-df11-bc07-005056887b79 |Thread: 6 |Category: Platform.Sdk |User: 822138f1-c574-e011-9dca-005056887b79 |Level: Error | CompositeSoapExtensionExceptionHandler.Handle
at CompositeSoapExtensionExceptionHandler.Handle(Stream to, Stream from, Exception exception)
at CrmAuthenticationSoapExtensionBase.ProcessMessage(SoapMessage message)
at SoapMessage.RunExtensions(SoapExtension[] extensions, Boolean throwOnException)
at SoapServerProtocol.WriteException(Exception e, Stream outputStream)
at WebServiceHandler.WriteException(Exception e)
at WebServiceHandler.Invoke()
at WebServiceHandler.CoreProcessRequest()
at SyncSessionlessHandler.ProcessRequest(HttpContext context)
at CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
at ApplicationStepManager.ResumeSteps(Exception error)
at HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
at HttpRuntime.ProcessRequestInternal(HttpWorkerRequest wr)
at HttpRuntime.ProcessRequestNoDemand(HttpWorkerRequest wr)
at ISAPIRuntime.ProcessRequest(IntPtr ecb, Int32 iWRType)
>CrmSoapExtension detected CrmException:
System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> Microsoft.Crm.CrmException: Invalid user auth.
at Microsoft.Crm.Sdk.SecurityHelper.VerifyAndReturnCurrentCallerId(Guid userId, Guid callerId, Guid orgId)
at Microsoft.Crm.WebServices.Crm2007.CrmWebService.get_CurrentCallerId()
at Microsoft.Crm.Sdk.Crm2007.CrmService.Execute(Request request)
--- End of inner exception stack trace ---
UPDATE 7/25:
I decided to perform a test by making a call like I've been doing using the CrmDataContext where the CrmConnection.ImpersonatedUser is set to the jsmith id. Then I made another call (exact same query) using the old school approach where you build the QueryExpression and pass it into the CrmService where the CallerId property of the CrmAuthenticationToken is set to the id for jsmith. The using CrmDataContext failed with the "Invalid user auth" error but the other call using the CrmService and QueryExpression ran fine. I used fiddler to look at the raw http request for each of those calls. The raw request was the exact same for both calls except for one thing.... The Negotiate token in the Authorization header of the request. I made both calls, one right after the other, in my console app and they produce different Negotiate tokens. That's got to be the problem although I don't know how to fix. Seems like this is a bug in the Advanced Developer Extensions. Below are the raw http for both.
--using CrmDataContext
POST http://myserver/MSCRMServices/2007/CrmService.asmx HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 4.0.30319.235)
VsDebuggerCausalityData: uIDPo6mcKDyuc+pPqk3LRv81TrIAAAAA/j8K/SLE5EivZ+mzg1+doYkmNLjkHbFHmbD9UyYmHFEACQAA
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://schemas.microsoft.com/crm/2007/WebServices/Execute"
Accept-Encoding: gzip,gzip
Authorization: Negotiate YIIIrgYGKwYBBQUCoIIIojCCCJ6g.....
Host: myserver
Content-Length: 1281
Expect: 100-continue
<?xml version="1.0" encoding="utf-8"?>
<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:Header>
<CrmAuthenticationToken xmlns="http://schemas.microsoft.com/crm/2007/WebServices">
<AuthenticationType xmlns="http://schemas.microsoft.com/crm/2007/CoreTypes">0</AuthenticationType>
<OrganizationName xmlns="http://schemas.microsoft.com/crm/2007/CoreTypes">myorg</OrganizationName>
<CallerId xmlns="http://schemas.microsoft.com/crm/2007/CoreTypes">1937f45c-8eb4-e011-8fe4-005056887b79</CallerId>
</CrmAuthenticationToken>
</soap:Header>
<soap:Body>
<Execute xmlns="http://schemas.microsoft.com/crm/2007/WebServices">
<Request xsi:type="RetrieveMultipleRequest" ReturnDynamicEntities="true">
<Query xmlns:q1="http://schemas.microsoft.com/crm/2006/Query" xsi:type="q1:QueryExpression">
<q1:EntityName>contact</q1:EntityName>
<q1:ColumnSet xsi:type="q1:AllColumns" />
<q1:Distinct>false</q1:Distinct>
<q1:PageInfo>
<q1:PageNumber>1</q1:PageNumber>
<q1:Count>100</q1:Count>
</q1:PageInfo>
<q1:LinkEntities />
<q1:Criteria>
<q1:FilterOperator>And</q1:FilterOperator>
<q1:Conditions />
<q1:Filters />
</q1:Criteria>
<q1:Orders />
</Query>
</Request>
</Execute>
</soap:Body>
</soap:Envelope>
--call using CrmService with QueryExpression
POST http://myserver/MSCrmServices/2007/CrmService.asmx HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 4.0.30319.235)
VsDebuggerCausalityData: uIDPo8cVsRu/YZBCl+8cnC9j5fwAAAAAGni8rU7A/Uy4JYm/bi/S6d/soXPiw+xBoKSYCD/1KRIACQAA
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://schemas.microsoft.com/crm/2007/WebServices/Execute"
Authorization: Negotiate YIIG5wYGKwYBBQUCoIIG2zCCBtegMDAuBgkqhk.....
Host: myserver
Content-Length: 1219
Expect: 100-continue
<?xml version="1.0" encoding="utf-8"?>
<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:Header>
<CrmAuthenticationToken xmlns="http://schemas.microsoft.com/crm/2007/WebServices">
<AuthenticationType xmlns="http://schemas.microsoft.com/crm/2007/CoreTypes">0</AuthenticationType>
<OrganizationName xmlns="http://schemas.microsoft.com/crm/2007/CoreTypes">myorg</OrganizationName>
<CallerId xmlns="http://schemas.microsoft.com/crm/2007/CoreTypes">1937f45c-8eb4-e011-8fe4-005056887b79</CallerId>
</CrmAuthenticationToken>
</soap:Header>
<soap:Body>
<Execute xmlns="http://schemas.microsoft.com/crm/2007/WebServices">
<Request xsi:type="RetrieveMultipleRequest" ReturnDynamicEntities="false">
<Query xmlns:q1="http://schemas.microsoft.com/crm/2006/Query" xsi:type="q1:QueryExpression">
<q1:EntityName>contact</q1:EntityName>
<q1:ColumnSet xsi:type="q1:AllColumns" />
<q1:Distinct>false</q1:Distinct>
<q1:PageInfo>
<q1:PageNumber>1</q1:PageNumber>
<q1:Count>100</q1:Count>
</q1:PageInfo>
<q1:Criteria>
<q1:FilterOperator>And</q1:FilterOperator>
</q1:Criteria>
</Query>
</Request>
</Execute>
</soap:Body>
</soap:Envelope>
Sounds like you may have found a bug. I would open a free support ticket with Microsoft # 1-877-276-2464. They would be faster with resolution than what you're finding here and the outcome would be conclusive.
I never figured out the problem. But, my work-around is to just build a connection string at runtime that contains the username and password of the person i would want to impersonate via the CallerId property. So I want really be impersonated and I guess for my situation it really does not matter.

Resources