Getting HTTP 401 Error calling MS CRM 365 USING SOAP UI - microsoft-dynamics

I am trying to call MSCRM 365 web services using SOAPUI, this is what i have done so far
Downloaded Organization WSDL from my cRM instance
Uploaded in SOAPUI
Added three header parameters - Content-Type, SOAPAction and Accept
Added Username and Password in Request Properties
Whenever I send a request to MSCRM, I get "HTTP ERROR 401 - Unauthorized: Access is denied"
Anyone have any ideas?
Thanks,
Nitesh

Since this is Dynamics 365 it does not authenticate using Username / Password. Instead you will need to use OAuth as shown in the link
https://msdn.microsoft.com/en-us/library/gg327838.aspx
// TODO Substitute your correct CRM root service address,
string resource = "https://mydomain.crm.dynamics.com";
// TODO Substitute your app registration values that can be obtained after you
// register the app in Active Directory on the Microsoft Azure portal.
string clientId = "e5cf0024-a66a-4f16-85ce-99ba97a24bb2";
string redirectUrl = "http://localhost/SdkSample";
// Authenticate the registered application with Azure Active Directory.
AuthenticationContext authContext =
new AuthenticationContext("https://login.windows.net/common", false);
AuthenticationResult result = authContext.AcquireToken(resource, clientId, new
Uri(redirectUrl));
Use the access token in message requests:
using (HttpClient httpClient = new HttpClient())
{
httpClient.Timeout = new TimeSpan(0, 2, 0); // 2 minutes
httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", result.AccessToken);
Another options would be to shift from Xrm.Client to Xrm.Tools.Connection. See the example in this site.
https://msdn.microsoft.com/en-us/library/jj602970.aspx

Related

Unable to authenticate in accessing Dynamic CRM Online Web Service

I need to utilize Dynamic CRM Data Service Endpoint exposed to get data from one of the methods.
Service(microsoft) account has access to this service.
I've tried authenticating to Discovery Service and Organization Service using sample code provided here [https://msdn.microsoft.com/en-us/library/hh675404.aspx] and succeed. However am not able to use same authentication to access data Service as I could find anyway to relate Data Service with the other two. Doing basic authentication using Network Credentials does not work.
I have downloaded the CSDL exposed and added that as service reference to my project, which created an class of web service which extends from DataServiceContext. Am trying to retrieve data of one of the methods using LinQ queries. It returs following error:
"The response payload is a not a valid response payload. Please make sure that the top level element is a valid Atom or JSON element or belongs to 'http://schemas.microsoft.com/ado/2007/08/dataservices' namespace." On capturing using fiddle I realized that on hitting data service URL it is redirected to sign in page 'login.microsoftonline.com/'
Can anybody suggest a way to authenticate the user to access Data Serivce?
Adding code:
//<snippetAuthenticateWithNoHelp1>
IServiceManagement<IDiscoveryService> serviceManagement =
ServiceConfigurationFactory.CreateManagement<IDiscoveryService>(
new Uri(_discoveryServiceAddress));
AuthenticationProviderType endpointType = serviceManagement.AuthenticationType;
// Set the credentials.
AuthenticationCredentials authCredentials = GetCredentials(serviceManagement, endpointType);
String organizationUri = String.Empty;
// Get the discovery service proxy.
using (DiscoveryServiceProxy discoveryProxy =
GetProxy<IDiscoveryService, DiscoveryServiceProxy>(serviceManagement, authCredentials))
{
// Obtain organization information from the Discovery service.
if (discoveryProxy != null)
{
// Obtain information about the organizations that the system user belongs to.
OrganizationDetailCollection orgs = DiscoverOrganizations(discoveryProxy);
// Obtains the Web address (Uri) of the target organization.
organizationUri = FindOrganization(_organizationUniqueName,
orgs.ToArray()).Endpoints[EndpointType.OrganizationService];
}
}
//</snippetAuthenticateWithNoHelp1>
if (!String.IsNullOrWhiteSpace(organizationUri))
{
//<snippetAuthenticateWithNoHelp3>
IServiceManagement<IOrganizationService> orgServiceManagement =
ServiceConfigurationFactory.CreateManagement<IOrganizationService>(
new Uri(organizationUri));
// Set the credentials.
AuthenticationCredentials credentials = GetCredentials(orgServiceManagement, endpointType);
// Get the organization service proxy.
using (OrganizationServiceProxy organizationProxy =
GetProxy<IOrganizationService, OrganizationServiceProxy>(orgServiceManagement, credentials))
{
// This statement is required to enable early-bound type support.
organizationProxy.EnableProxyTypes();
// Now make an SDK call with the organization service proxy.
// Display information about the logged on user.
Guid userid = ((WhoAmIResponse)organizationProxy.Execute(
new WhoAmIRequest())).UserId;
SystemUser systemUser = organizationProxy.Retrieve("systemuser", userid,
new ColumnSet(new string[] { "firstname", "lastname" })).ToEntity<SystemUser>();
Console.WriteLine("Logged on user is {0} {1}.",
systemUser.FirstName, systemUser.LastName);
Uri x = new Uri("https://<MyOrgainzationName>.crm.dynamics.com/XRMServices/2011/OrganizationData.svc/");
MyOrgainzationContext saContext = new MyOrgainzationContext(x);
NetworkCredential nc = new NetworkCredential();
nc.UserName = "*****#microsoft.com";
nc.Password = "********";
saContext.Credentials = nc;
var query_where3 = from c in saContext.new_productSet
select new
{
ProductStatus = c.new_ProductStatus,
LineofBusiness = c.new_LineofBusiness
};
var temp = saContext.Entities;
foreach (var c in query_where3)
{
System.Console.WriteLine("ProductStatus: " +
c.ProductStatus +
"\t\t\t" +
"LineofBusiness: " +
c.LineofBusiness);
}
}
//</snippetAuthenticateWithNoHelp3>
}
MyOrganizationContext is the context class created on adding CSDL file exposed at service endpoints
Have a look at the CRM Web Api Preview: https://msdn.microsoft.com/en-us/dynamics/crm/webapipreview.aspx. You can call this endpoint from outside xRM and you can authenticate with OAuth 2.0.

ASP.NET Identity / OData using CORS and cookie authentication missing Auth cookie

I have an ASP.NET Identity site and a ASP.NET OData site.
Both sites have CORS enabled and both site are using ASP.NET Identity CookieAuthentication.
When I execute both sites locally on my computer using IIS (not express) the AUTH cookie is being passed in the header on each request to the OData site.
But when I deploy the sites to the production IIS server then the header is missing the AUTH cookie when calling the production OData site.
Both production and my local IIS have the same domain name and CORS is setup to allow all.
The WebApiConfig has
cors = new Http.Cors.EnableCorsAttribute("*", "*", "*");
config.Enable(cors);
Before anyone asks, yes the machine key is the same between sites.
UPDATE
This seems to be a CORS issue.
When both sites are on my local machine they use the same host name and domain name but when the site are on the production server they have different host names and the same domain name.
You might need to specify the "Access-Control-Allow-Origin" inside your OAuthAuthorizationServerProvider.
I'm using OWIN but you should be able to do something similarly.
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
try adding the policy in your OWIN startup class as below. Just keep in mind that the Startup class might have some different class files since it's a partial class. Also, check ConfigureAuth method to see if everything is set according to your needs there. For instance, you set the external signin cookie of Identity as copied below in ConfigureAuth method to allow External Signin Cookeies like facebook and google.
public void Configuration(IAppBuilder app)
{
//
app.UseCors(CorsOptions.AllowAll);
ConfigureAuth(app);
}
app.UseExternalSignInCookie(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ExternalCookie);
I finally got this to work.
In the ASP.NET Identity site I have the following:
// configure OAuth for login
app.UseCookieAuthentication(new CookieAuthenticationOptions {
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
Provider = new CookieAuthenticationProvider(),
LoginPath = new PathString("/Account/Login.aspx"),
CookieName = ".TESTAUTH",
CookieDomain = ".test.com",
CookieSecure = CookieSecureOption.Always
});
It seems that the important part on the ASP.NET Identity site is that the "CookieName, CookieDomain, and the Machine Key" must match the one on the OData site.
And then on the OData site I have the following:
// configure OAuth for login
app.UseCookieAuthentication(new CookieAuthenticationOptions {
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
Provider = new CookieAuthenticationProvider { OnApplyRedirect = ApplyRedirect },
LoginPath = new PathString("/Account/Login.aspx"),
CookieName = ".TESTAUTH",
CookieDomain = ".test.com",
CookieSecure = CookieSecureOption.Always
});
// build the configuration for web api
HttpConfiguration config = new HttpConfiguration();
// Enable CORS (Cross-Origin Resource Sharing) for JavaScript / AJAX calls
// NOTE: USING ALL "*" IS NOT RECOMMENDED
var cors = new Http.Cors.EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
// call the web api startup
WebApiConfig.Register(config);
app.UseWebApi(config);
private void ApplyRedirect(CookieApplyRedirectContext context)
{
Uri absoluteUri = null;
if (Uri.TryCreate(context.RedirectUri, UriKind.Absolute, absoluteUri))
{
var path = PathString.FromUriComponent(absoluteUri);
if (path == context.OwinContext.Request.PathBase + context.Options.LoginPath)
{
QueryString returnURI = new QueryString(context.Options.ReturnUrlParameter, context.Request.Uri.AbsoluteUri);
context.RedirectUri = "https://www.test.com/Account/Login.aspx" + returnURI.ToString;
}
}
context.Response.Redirect(context.RedirectUri);
}
The "LoginPath" is required even though it does not exist on the OData site and you can't use a full url to another site for the login path.
I used "OnApplyRedirect" to redirect to the actual Login page.
I'm not sure what the difference is between "config.EnableCors" and "app.UseCors" but the EnableCors seems to be working for now.

Need to Get the Index of Session using SAML2.0 to fix Logout

I'm doing an agent SAML2.0 SSO using the code that is in this url:
http://svn.wso2.org/repos/wso2/people/asela/wso2-samples/sso_webapp/
but it does not work the logout. Excuse my English.
I am told, when the identity server sends responses of the authentication, sends a session index value in it and you need to return exactly the same value in the logout request to the identity server. How I can get the index value of the session with SAML 2.0?
This is the code of my class LogoutRequestBuilder
public LogoutRequest buildLogoutRequest(String subject, String reason) {
Util.doBootstrap();
LogoutRequest logoutReq = new org.opensaml.saml2.core.impl.LogoutRequestBuilder().buildObject();
logoutReq.setID(Util.createID());
DateTime issueInstant = new DateTime();
logoutReq.setIssueInstant(issueInstant);
logoutReq.setNotOnOrAfter(new DateTime(issueInstant.getMillis() + 5 * 60 * 1000));
IssuerBuilder issuerBuilder = new IssuerBuilder();
Issuer issuer = issuerBuilder.buildObject();
issuer.setValue(Util.getProperty(SSOConstants.ISSUER_ID));
logoutReq.setIssuer(issuer);
NameID nameId = new NameIDBuilder().buildObject();
nameId.setFormat(SSOConstants.SAML_NAME_ID_POLICY);
nameId.setValue(subject);
logoutReq.setNameID(nameId);
SessionIndex sessionIndex = new SessionIndexBuilder().buildObject();
sessionIndex.setSessionIndex(Util.createID());
logoutReq.getSessionIndexes().add(sessionIndex);
logoutReq.setReason(reason);
return logoutReq;
}
}
If single logout is enabled in service provider registration in WSO2IS. Within the SAML response you get will contain the SessionIndex.
So that value has to be stored somewhere to send back in the logout request.
This is an old sample you are using. [1] This document contain the sso sample which has single log out enabled.
[1] https://docs.wso2.com/display/IS500/Configuring+SAML2+SSO

WSO2 Admin services BAMMediatorConfigAdmin

I am trying to add BAM server profile (under ESB server) using Admin Web services. I am not seeing any error thrown while executing as standalone program but profile is not getting added. Please advise if below steps are correct -
Get admin cookie by connecting to "AuthenticationAdmin" URL
Create stubs using wsdl2java from "BAMMediatorConfigAdmin" WSDL
String bamcepServerProfileServiceURL = Constant.SERVICE_URL + "BAMMediatorConfigAdmin";
BAMMediatorConfigAdminStub stub = new BAMMediatorConfigAdminStub(bamcepServerProfileServiceURL);
ServiceClient client = stub._getServiceClient();
Options option = client.getOptions();
option.setManageSession(true);
option.setProperty(org.apache.axis2.transport.http.HTTPConstants.COOKIE_STRING, adminCookie);
BAMMediatorConfigAdminStub.BamServerConfig bamConfig = new BAMMediatorConfigAdminStub.BamServerConfig();
bamConfig.setUsername("admin");
bamConfig.setPassword("admin");
bamConfig.setLoadbalanced(false);
bamConfig.setSecurity(true);
bamConfig.setIp("localhost");
bamConfig.setAuthenticationPort("7611");
BAMMediatorConfigAdminStub.SaveBamServerConfig config = new BAMMediatorConfigAdminStub.SaveBamServerConfig();
config.setBamServerConfig(bamConfig);
stub.saveBamServerConfig(config);
Please check #addResource in[1], which creates the profile and calls ,
stub.saveResourceString(resourceString, bamServerProfileLocation);
through #saveResourceString in[2]
[1]https://svn.wso2.org/repos/wso2/carbon/platform/branches/4.1.0/components/mediators/bam/org.wso2.carbon.mediator.bam.config.ui/4.1.0/src/main/java/org/wso2/carbon/mediator/bam/config/ui/BamServerProfileUtils.java
[2]https://svn.wso2.org/repos/wso2/carbon/platform/branches/4.1.0/components/mediators/bam/org.wso2.carbon.mediator.bam.config.ui/4.1.0/src/main/java/org/wso2/carbon/mediator/bam/config/ui/BamServerProfileConfigAdminClient.java

Authentication failure calling SharePoint Web Service (JAX-WS client)

I have to call SharePoint 2010 Lists service from a Java client.
I used NetBeans to generate the JAX-WS classes from the WSDL.
And extended java.net.Authenticator to manage the authentication to SharePoint :
static final String user = "XXXXXXXX\\Administrateur"; // your account name
static final String pass = "mypassw"; // your password for the account
static class MyAuthenticator extends Authenticator {
public PasswordAuthentication getPasswordAuthentication() {
System.out.println("Feeding username and password for " + getRequestingScheme());
return (new PasswordAuthentication(user, pass.toCharArray()));
}
}
Calling the web service with JAX-WS :
Authenticator.setDefault(new MyAuthenticator());
com.nm.Lists service = new com.nm.Lists();
com.nm.ListsSoap port = service.getListsSoap12();
String pageUrl = "http://xxxxxxx/testPushFile.txt";
String comment = "no comment";
String checkinType = "1";
boolean result = port.checkInFile(pageUrl, comment, checkinType);
I am still getting the error :
Exception in thread "main" javax.xml.ws.WebServiceException: java.io.IOException: Authentication failure
at com.sun.xml.internal.ws.transport.http.client.HttpClientTransport.readResponseCodeAndMessage(HttpClientTransport.java:201)
Because it isn't working I tried :
to set the user without the domain
to set the domain as a system property : System.setProperty("http.auth.ntlm.domain", "XXXXXXXX");
to authenticate "old-fashioned way" :
((BindingProvider) port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, user);
((BindingProvider) port).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, pass);
Any ideas what's the problem with authentication ?
Thanks
I am coming back to give the solution. Here is what I have done to make the Web Service authentication work :
I enabled Basic Authentication in IIS Manager for my SharePoint Site,
I used a user credentials that was registred in Windows Domain