Connect to Microsoft Exchange Server using C# - c#

I have to establish connectivity with Microsoft Exchange Webservice and I have been given the below details -
Shared mailbox address is say -
"students#student.edu"
Service account is say -
"Student SA"
Password for service account is say -
"Pass1234"
I followed the code sample given in website:
https://learn.microsoft.com/en-us/exchange/client-developer/exchange-web-services/get-started-with-ews-managed-api-client-applications
Below is my code sample using the above details -
static void Main(string[] args)
{
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
service.Credentials = new WebCredentials("Student SA", "Pass1234");
service.TraceEnabled = true;
service.TraceFlags = TraceFlags.All;
service.AutodiscoverUrl("students#student.edu", RedirectionUrlValidationCallback);
// service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.PrincipalName, "myADAccount");
}
private static bool RedirectionUrlValidationCallback(string redirectionUrl)
{
// The default for the validation callback is to reject the URL.
bool result = false;
Uri redirectionUri = new Uri(redirectionUrl);
// Validate the contents of the redirection URL. In this simple validation
// callback, the redirection URL is considered valid if it is using HTTPS
// to encrypt the authentication credentials.
if (redirectionUri.Scheme == "https")
{
result = true;
}
return result;
}
When I run this locally, I am getting below error messages
<Trace Tag="AutodiscoverConfiguration" Tid="9" Time="2018-06-04 15:10:07Z">
Request error: The remote server returned an error: (401) Unauthorized.
</Trace>
I looked for the same in other threads here How to connect to Exchange?
and also on Code project, but they all tell the same way on how to connect to exchange webservice.
I am not sure as to why I am getting the unauthorized access in Autodiscover configuration and if I am using the correct code to connect to exchange server using the service account information that has been provided.

Your credential format doesn't look correct you should be either using the downlevel format which would be domain\username or the UPN see https://msdn.microsoft.com/en-us/library/windows/desktop/aa380525(v=vs.85).aspx. I'd suggest you use the UPN as that should always work.

Try the address instead of the Service Account:
service.Credentials = new WebCredentials("students#student.edu", "Pass1234");
Also this basic authentication is going away.
Look into implementing OAuth:
https://learn.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-authenticate-an-ews-application-by-using-oauth

Related

I want to integrate XERO to WebAPI C# Can someone provide me sample code for oauth2

I have tried the below
XeroConfiguration xeroConfig = new XeroConfiguration();
xeroConfig.ClientId = "****";
xeroConfig.ClientSecret = "****";
xeroConfig.CallbackUri = new Uri("http://localhost"); //default for standard webapi template
xeroConfig.Scope = "openid profile email files accounting.transactions accounting.contacts offline_access";
var client2 = new XeroClient(xeroConfig, httpClientFactory);
var test = client2.BuildLoginUri();
return Redirect(client2.BuildLoginUri());
After redirection it is giving below error
Error code: 500 Error: unauthorized_client : Invalid redirect_uri
It is because you have registered your app in the Authorization Server using a different redirect URI and in the above you are using a different redirect URI which will be validated by the Authorization Server and on mismatch, it is throwing you the Error.
You have to register your app with the Redirect URI that you will be using
Ex: If your app is running in http://localhost:6500 and your redirect URI to receive the token and process is http://localhost:6500/login. You have to provide this value to the Authorization Server.
ex: The setting would look like
xeroConfig.CallbackUri = new Uri("http://localhost:6500/login")

How to authenticate with Azure Active Directory programatically in a Connect App for Business Central?

I am attempting to write a connect app that will receive a set of data from an external source and put it inside an instance of microsoft dynamics 365 business central via its APIs. Documentation says there are two ways to do this, using basic authentication and logging in via Azure Active Directory. The former is easy and straightforward to do programmatically, but the documentation makes it very clear that it is not meant for production environments. I'm capable of doing the latter using Postman, but part of the process involves me typing in credentials in a popup window. Since the use case for the final product will be to run without user interaction, this won't do. I want the application to handle the credentials of what will be a service account by itself.
I'm able to modify records using basic authentication, and active directory if I fill out the login form when prompted. I've tried using a library called ADAL, but passing my account's credentials that way led to the following response: {"error":"invalid_request","error_description":"AADSTS90014: The request body must contain the following parameter: 'client_secret or client_assertion.}
I have access to the client secret, but there seems to be no means of passing it via ADAL, that I've found.
I've also tried, at a colleague's recommendation, to log in using the client id and client secret as username and password. The following code is what we ended up with:
RestClient client = new RestClient("https://login.windows.net/[my tenant domain]/oauth2/token?resource=https://api.businesscentral.dynamics.com");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("undefined", "grant_type=%20client_credentials&client_id=%20[my client id]&client_secret=[my client secret]&resource=[my resource]", ParameterType.RequestBody);
string bearerToken = "";
try
{
bearerToken = JsonConvert.DeserializeObject<Dictionary<string, string>>(client.Execute(request).Content)["access_token"];
Console.WriteLine(bearerToken);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
The code above successfully retrieves a token, but if I use that token I get the following response:
<error xmlns="http://docs.oasis-open.org/odata/ns/metadata"><code>Unauthorized</code><message>The credentials provided are incorrect</message></error>
I've never used Microsoft dynamics 365. But I've validated an user using a local active directory server using C# code.
using System.DirectoryServices.AccountManagement;
public class ActiveDirectoryService {
// The domain url is the url of the active directory server you're trying to validate with.
public bool ValidateWithActiveDirectoryAsync(string domainUrl, string userName, string password) {
using (var context = new PrincipalContext(ContextType.Domain, domainUrl)) {
UserPrincipal UserPrincipal1 = new UserPrincipal(context);
PrincipalSearcher search = new PrincipalSearcher(UserPrincipal1);
if (context.ValidateCredentials(userName, password)) {
return true;
}
}
return false;
}
}
I hope it works for you.

How to make an external GET request from IIS hosted WebAPI/MVC app (via proxy server)

We use Windows authentication. I've created both WebAPI/MVC applications to play with.
When hosted on production server / IIS appplication requires credentials to perform HTTP GET to an external site. For some reasons we temporarily cannot use special AD account for that.
I've read about ASP.NET impersonation. As far as I understand it is possible to incorporate with caller's credentials? I've tried to use this code though I'm not sure whether it is an appropriate approach to use with WebAPI.
[HttpGet]
[Route("api/test")]
public HttpResponseMessage test() {
using(var ctx = WindowsIdentity.GetCurrent().Impersonate()) {
var proxyOptions = new WebProxy("[proxyUrl]");
proxyOptions.UseDefaultCredentials = true;
var client = new WebClient();
client.UseDefaultCredentials = true;
client.Proxy = proxyOptions;
return new HttpResponseMessage {
Content = new StringContent(
content: client.DownloadString("[externalApiUrl]"),
encoding: Encoding.Default,
mediaType: "text/plain"
)
};
}
}
Anyway this doesn't work.
Should I configure delegation instead of impersonation?
How to perform an external request without a separate AD account for that?
Have you tried explicitly setting the credentials using
var proxyConfig = new WebProxy(
proxyServerUrl,
BypassOnLocal: false,
BypassList: null,
Credentials: new NetworkCredential(username, password)
);
The username / password should be an authorized user on your proxy server. Since you are using Windows Authentication, you may need to prefix domain name in the username E.g. domain\username
This approach should work in all the 3 environments you have mentioned.

PayPal SOAP API - Express Checkout - Error 10002

I'm trying to connect my website to the Paypal Sandbox in order to use the Express Checkout feature. I've used this link as reference but i keep getting the 10002 Error "Security header is not valid".
From the documentation this has to be a invalid credentials problem but if i made the request manually through soapUI it returns "Sucess", if i use the curl command it also works as expected.
Scenario: ASP.NET page with two Web References one to https://www.sandbox.paypal.com/wsdl/PayPalSvc.wsdl and another to https://www.paypalobjects.com/wsdl/PayPalSvc.wsdl, the given credentials are Username, Password and Signature as you can see in the following code snippet:
using CloudShop.com.paypal.sandbox.www;
namespace CloudShop
{
public static PayPalAPIAASoapBinding BuildPayPalWebservice()
{
UserIdPasswordType credentials = new UserIdPasswordType()
{
Username = CloudShopConf.PayPalAPIUsername,
Password = CloudShopConf.PayPalAPIPassword,
Signature = CloudShopConf.PayPalAPISignature
};
PayPalAPIAASoapBinding paypal = new PayPalAPIAASoapBinding();
paypal.RequesterCredentials = new CustomSecurityHeaderType()
{
Credentials = credentials
};
return paypal;
}
Right now i would like to know how to proceed with the debug. What could be wrong?
Some ideas:
Check if you are using the Live-Credentials for the sandbox account.
Are you using https://api-3t.sandbox.paypal.com/2.0/ (especially the -3t part) as the endpoint? You should as you are using Signature authentication.
As usual, you should step through every setting you are using: protocol, API Endpoint, Version, Credentials etc. and compare you're manual SoapUI call with the information stored in you shop configuration.
I also found a blog article on this error that might help resolving this issue.

Calling webservice in C# using SSL - '(401) Unauthorized'

I'm calling a method on a web service from behind a proxy server using the following code:
myWebService.TestWebService webservice = new myWebService.TestWebService();
webservice.Url = "http://test.com/webservice?wsdl";
WebProxy proxy = new WebProxy("1.2.3.4", 8080);
proxy.Credentials = new NetworkCredential("username", "password");
webservice.Proxy = proxy;
string response = webservice.TestWebMethod();
This works fine when using HTTP, I get the response I'm expecting in the 'response' string.
However - if I change the URL to HTTPS then I get a (401) Unauthorized response.
If I put the URL into my browser it works fine using HTTP or HTTPS.
I've added code to handle the SSL certificate validation by creating a System.Net.ServicePointManager.ServerCertificateValidationCallback delegate but the code never gets this far. The request is rejected before it validates the certificate or so it seems.
Any help is really appreciated...
Do you need credentials to navigate to the SSL url?
If so you need the web service credentials set.
Have you tried adding a web reference in Visual Studio using the SSL url?
If you can't add web reference through Visual Studio then the code is not going to work either.
Can you make sure that the last thing that you set is the proxy (e.g. change the url before you set the proxy)?
There is a small chance that the proxy could be lost, this should be the very last thing to try
Here is an example using a client cert (which i'm sure you don't need) but might provide some insight & using credentials to a web service.
WebService.ManageOutboundDelivery oWS = new WebService.ManageOutboundDelivery();
if (My.Settings.HasClientCert == true) {
X509Certificate2 signedCert = new X509Certificate2(HttpContext.Current.Server.MapPath(My.Settings.ClientCertName), My.Settings.ClientCertPW);
oWS.ClientCertificates.Add(signedCert);
}
System.Net.CredentialCache oCred = new System.Net.CredentialCache();
Net.NetworkCredential netCred = new Net.NetworkCredential(My.Settings.WebServiceUID, My.Settings.WebServicePW);
oCred.Add(new Uri(oWS.Url), "Basic", netCred);
oWS.Credentials = oCred;
Have you also checked the SSL cert is valid - i'm guessing you would see this when you hit it through the browser but it could be causing a problem trying to hit it programmatically.

Categories

Resources