CRM Dynamics 2015 Plugin registration Tool crashes on WCF/ASMX service call - wcf

Your help will be highly appreciated, I have registered a Plug-in on phone call create in CRM Dynamics 2015, When I debug the plugin using the profiler, the plugin Registration tool stops working as soon as I make a call to the WCF service client method exposed. I have tried with both an ASXM service and a WCF service,i have deployed the service in IIS on the same server CRM is hosted,I tested the service against a console and SOAP UI, everything works fine, the minute I use it kin a Plugin context it crashed the registration tool on service call. There is no error logged in the plugin Registration tool log files, here is my plugin code below
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
if (context == null)
{
throw new ArgumentNullException("localContext");
}
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.InitiatingUserId);
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
Entity phoneCallEntity = (Entity)context.InputParameters["Target"];
if (phoneCallEntity.LogicalName != "phonecall")
return;
//ensure that the Plugin fires on a create operaton
if (context.MessageName == "Create")
{
try
{
BasicHttpBinding myBinding = new BasicHttpBinding();
myBinding.Name = "BasicHttpBinding_IService1";
myBinding.Security.Mode = BasicHttpSecurityMode.None;
myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
myBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
myBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
EndpointAddress endPointAddress = new EndpointAddress("http://154.66.196.127/Webservice/ZoiperCallHistory.asmx");
ZoiperCallHistorySoapClient client = new ZoiperCallHistorySoapClient(myBinding,endPointAddress);
client.Open();
CallHistory callHistory = client.GetZoiperCallHistory();
client.GetZoiperCallHistory();
The code fails on this line : CallHistory callHistory = client.GetZoiperCallHistory();
Thanks in advance.

In my experience the plugin registration tool doesn't go well with debugging web service calls. Try instead using the tracing service to identify errors or to analyze the web service response.
ITracingService tracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));

Related

Signing in to an application with ws-federation from front-end application

I have two applications, one web-api application (y.x.com) and a front-end application (z.x.com). To authenticate the user who visits z.x.com I use ws-federation or microsoft live login following the web api template code provided by visual studio 2015. If I talk directly to the web api application (y.x.com) from my browser, postman, fiddler or anything similar the authentication works fine but if I try to sign in from the front-end application I get error: invalid_request (status 400).
Now I wonder if it should be possible to sign in from application z.x.com by calling y.x.com/Account/ExternalLogin?provider=Federation&response_type=token&client_id=self&redirect_uri=http://y.x.com.
My startup.auth in y.x.com looks like this
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
// In production mode set AllowInsecureHttp = false
AllowInsecureHttp = true
};
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
var wsOptions = new WsFederationAuthenticationOptions
{
MetadataAddress = "https://login.microsoftonline.com/afd2d5a6-bdb1-43f8-a42b-83ec49f1f22d/federationmetadata/2007-06/federationmetadata.xml",
Wtrealm = "http://y.x.com/",
Notifications = new WsFederationAuthenticationNotifications()
};
app.UseWsFederationAuthentication(wsOptions);
I can provide more code but I'm mostly interested in if should work at all.
Thanks.
This is possible. After som digging and help it turns out that in the web-api template there is a method named ValidateClientRedirectUri in the class ApplicationOAuthProvider. If I change that method to
public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)
{
context.Validated();
return Task.FromResult<object>(null);
}
and then from my front end application I can now have any return url I want, making it possible to sign in from the front-end application via the web-api application to an external source.

Servicestack, Xamarin and authentication

I've got an ServiceStack service running with custom authentication, this runs fine from the browser and through a Windows console program.
I'm now trying to get a simple Xamarin Android program to authenticate but whatever I try it crashes with an Exception without any further explanation. The code I am using stops at the line with 'var authResponse', I'm using the 4.0.44 ServiceStack packages and the lastest stable Xamarin from inside VS2015.
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
// servicestack
var client = new JsonServiceClient("http://10.0.2.2:8080");
var authResponse = client.Get<AuthenticateResponse>( new Authenticate
{
UserName = "Willem",
Password = "secret",
RememberMe = true
});
Any pointers to what/where I should look?
tia
If this is a self-hosted Service you would need to register the HttpListener AppHost to accept requests from different hosts by listening on a host wildcard, e.g:
appHost.Start("http://*:8080/");

CRM OrganizationServiceProxy authentication issue

We have an issue where our web app calls to CRM via Microsoft.Xrm.Sdk OriganizationServiceProxy are failing to authenticate. The issue appears to be environment specific i.e. the calls work on our DEV web server but fail when the app is promoted to our System Test environment. The code that fails is as follows:
using (var serviceProxy = this.serviceFactory.Impersonate(userProvider.PrincipalUserName).ServiceProxy)
{
var countResult = serviceProxy.RetrieveMultiple(new FetchExpression(query));
int? count = 0;
var entity = countResult.Entities.FirstOrDefault();
if (entity != null)
{
count = (int?)((AliasedValue)entity["activity_count"]).Value;
}
return count.Value;
}
The error that appears in our logs is:
System.ServiceModel.Security.SecurityNegotiationException: The caller was not authenticated by the service. ---> System.ServiceModel.FaultException: The request for security token could not be satisfied because authentication failed.
at System.ServiceModel.Security.SecurityUtils.ThrowIfNegotiationFault(Message message, EndpointAddress target)
at System.ServiceModel.Security.SspiNegotiationTokenProvider.GetNextOutgoingMessageBody(Message incomingMessage, SspiNegotiationTokenProviderState sspiState)
--- End of inner exception stack trace ---
I have double checked the apppool identity of the IIS site and CRM settings. Is there anything obvious here that we may have missed?
I found the connection to CRM Online was taking the longest time so I create one instance to pass round of the OrganizationServiceProxy with explicit credentials that I can easily switch between environments.
IServiceManagement<IOrganizationService> management = ServiceConfigurationFactory.CreateManagement<IOrganizationService>(new Uri(CrmUrl));
ClientCredentials credentials = new ClientCredentials();
credentials.UserName.UserName = CrmUserName;
credentials.UserName.Password = CrmPassword;
AuthenticationCredentials authCredentials = management.Authenticate(new AuthenticationCredentials { ClientCredentials = credentials });
SecurityTokenResponse securityTokenResponse = authCredentials.SecurityTokenResponse;
OrganizationServiceProxy orgProxy = new OrganizationServiceProxy(management, securityTokenResponse);
orgProxy.EnableProxyTypes();
_xrmService = new XrmServiceContext(orgProxy)

HTTP could not register URL (remote debugging)

C#, Windows 7.
I write an AutoCAD plugin and use the remote debuging (MS Visual Studio). My plugin must work as a WCF service. AutoCAD is unmanaged application and must to be as a host for my service. I am reading a book about WCF, and I try use it. I can't use acad.exe.config for my service settings: I have not permission. So I do it myself (I will read them from my xml file, but later, after refactoring). Code of my "server" (this code start by AutoCAD):
private static void RunServices() {
Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
try {
Uri address = new Uri("http://localhost:8000/CadService");
BasicHttpBinding binding = new BasicHttpBinding();
binding.Name = "httpBinding";
binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
binding.Security.Mode = BasicHttpSecurityMode.None;
host = new ServiceHost(typeof(CadService));
host.AddServiceEndpoint(typeof(ICadService), binding, address);
host.Open(); // I get an Exception here...
if (doc != null) {
doc.Editor.WriteMessage("Service launched.\n");
}
}
catch (Exception ex) {
if (doc != null) {
doc.Editor.WriteMessage("Exception: {0}\n", ex.Message);
}
}
}
I get an exception (look the code comment):
Exception: HTTP could not register URL http://+:8000/CadServices/.
Your process does not have access rights to this namespace
(see http://go.microsoft.com/fwlink/?LinkId=70353 for details).
But the http://go.microsoft.com/fwlink/?LinkId=70353 page is not exist. I try launch MS Visual Studio 2013 as admin (I read about this here), but It is not help me (look P.S.2 bellow).
P.S. If I launch AutoCAD as admin - all works fine.
P.S.2 If I launch the remote debugger as admin - all works fine too.
But I need use it as a usual user. Can I start my service (hosted in the AutoCAD) without the admin rights?
This is probably because AutoCad does not have the required rights to register the port in HTTP.SYS. In that case you have two options:
Start Autocad in Admin mode
Register the port / endpoint in HTTP.SYS manually. For this, there are several tools available. This is the one I would use : http://www.codeproject.com/Articles/437733/Demystify-http-sys-with-HttpSysManager
Let me know if this works

How to delegate Facebook SecurityToken to WCF service

I have the following components:
WPF Application,
Identity Server,
WCF Web Service,
WPF Application uses WebBrowser control to authenticate using Thintecture Identity Server using WS-Federation. Identity Server has enabled Home Realm Discovery and allow authentication using Facebook, Live ID and Google. After authentication I get ReqquestSecurityTokenResponse message, which I convert into SecurityToken.
After getting this SecurityToken I want to call WebService. I think I need create ActAsToken issued again by Thintecture Identity Server, but I can't configure it.
var serviceAddress = "http://localhost:7397/Service1.svc";
var token3 = token2.ToSecurityToken();
var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.Message);
binding.Security.Message.IssuedKeyType = System.IdentityModel.Tokens.SecurityKeyType.SymmetricKey;
binding.Security.Message.IssuerAddress = new EndpointAddress("https://dev3.example.com/Identity/issue/wsfed");
binding.Security.Message.IssuerBinding = new WS2007HttpBinding();
var factory = new ChannelFactory<IService1Channel>(binding,
new EndpointAddress(
new Uri(serviceAddress),
new DnsEndpointIdentity("dev3.example.com")));
factory.Credentials.SupportInteractive = false;
var proxy = factory.CreateChannelWithActAsToken(token3);
{
try
{
var output = proxy.GetData(1);
MessageBox.Show(output);
proxy.Dispose();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
But I get exceptions.
WebService is configured using Identity and access... VS extension.
Is this scenario possible?
you don't need an ActAs - you can use the CreateChannelWithIssuedToken method to create your WCF proxy.
You also need to configure bearer keys on the WCF service and client (instead of SymmetricKey).