Exchange Server Login Credentials Setup - c#

I just want to pass this by you and make sure that I am doing this right. My code:
ExchangeService _mailService = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
_mailService.Credentials = new System.Net.NetworkCredential(#"userName", #"password", #"mydomainInfo");
//_mailService.UseDefaultCredentials = true;
_mailService.Url = new Uri("https://webmail.mydomain.com/ews/exchange.asmx");
try
{
ItemView allItems = new ItemView(100);
SearchFilter searchFilterInbox = new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false);
Folder _inbox = Folder.Bind(_mailService, WellKnownFolderName.Inbox);
// <SNIP>
So I get this far and the Bind returns an Authentication Fail (401). If I comment out the '.Credentials' and uncomment '.UseDefaultCredentials', I log in just fine. But I need to access a different inbox folder. I pulled the UserName and Domain Name from my account on Outlook. Even if I use my own login information, I still get this error. To me that says I'm just not providing the right information. Thoughts? I can log into the web side of the service just fine.

Well I solved my own problem. It was what I was suspecting. I just didn't have the correct data in the "domain" and "username" fields. I was actually calling the server the Exchange Server was on. So I changed it to the domain that my computer is logged into and changed the user id from "me#email.com" to "me" and it works! So I had it all setup right, just wrong information.

Related

LDAP search fails on server, not in Visual Studio

I'm creating a service to search for users in LDAP. This should be fairly straightforward and probably done a thousand times, but I cannot seem to break through properly. I thought I had it, but then I deployed this to IIS and it all fell apart.
The following is setup as environment variables:
ldapController
ldapPort
adminUsername 🡒 Definitely a different user than the error reports
adminPassword
baseDn
And read in through my Startup.Configure method.
EDIT I know they are available to IIS, because I returned them in a REST endpoint.
This is my code:
// Connect to LDAP
LdapConnection conn = new LdapConnection();
conn.Connect(ldapController, ldapPort);
conn.Bind(adminUsername, adminPassword);
// Run search
LdapSearchResults lsc = conn.Search(
baseDn,
LdapConnection.SCOPE_SUB,
lFilter,
new string[] { /* lots of attributes to fetch */ },
false
);
// List out entries
var entries = new List<UserDto>();
while (lsc.hasMore() && entries.Count < 10) {
LdapEntry ent = lsc.next(); // <--- THIS FAILS!
// ...
}
return entries;
As I said, when debugging this in visual studio, it all works fine. When deployed to IIS, the error is;
Login failed for user 'DOMAIN\IIS_SERVER$'
Why? The user specified in adminUsername should be the user used to login (through conn.Bind(adminUsername, adminPassword);), right? So why does it explode stating that the IIS user is the one doing the login?
EDIT I'm using Novell.Directory.Ldap.NETStandard
EDIT The 'user' specified in the error above, is actually NOT a user at all. It is the AD registered name of the computer running IIS... If that makes any difference at all.
UPDATE After consulting with colleagues, I set up a new application pool on IIS, and tried to run the application as a specified user instead of the default passthrough. Exactly the same error message regardless of which user I set.
Try going via Network credentials that allows you to specify domain:
var networkCredential = new NetworkCredential(userName, password, domain);
conn.Bind(networkCredential);
If that does not work, specify auth type basic (not sure that the default is) before the call to bind.
conn.AuthType = AuthType.Basic;

LdapConnection Bind() always fails over SSL

I need to query some information with Active Directory that is only accessible when authenticated over SSL. I can make anonymous connections without issue, but I always get an "LDAP server is unavailable error" when trying to use SSL. There's a lot of forum topics about this, and I've reviewed them but have not found a solution. This code is an ASP.NET MVC app being run on IIS Express.
LdapConnection conn = new LdapConnection("ldap.xxx.com:636/OU=xxx,DC=xxx,DC=xxx,DC=xxx");
//conn.AutoBind = false;
conn.SessionOptions.ProtocolVersion = 3;
conn.AuthType = AuthType.Basic; //Tried with Negotiate as well
conn.Credential = new NetworkCredential(#"domain\user", "userPW", "domain");
conn.SessionOptions.SecureSocketLayer = true;
conn.SessionOptions.VerifyServerCertificate = new VerifyServerCertificateCallback((dev, cer) => true);
//conn.Timeout = new TimeSpan(1, 0, 0);
conn.Bind();
I use that container string with a PrincipalContext to validate the credentials for this account, that validation is successful (that takes place before this code). The container places me into the correct node and the account credentials are a match. Which is why this error puzzles me. Protocol version is correct as well. I've set the verifycert callback to return true regardless of the certificate.
The error is being thrown on the first line, if I remove the container it creates the connection, but then hangs indefinitely when I call .Bind(). If I specify the domain after the connection is made, the "unavailable error" is thrown on .Bind(). I don't understand why it fails with the container because it works when passed in with a PrincipalContext.
Thank you for any help.

EWS Exchange Web service API AutodiscoverUrl exception

I get an error when I try to create an appointment:
The expected XML node type was XmlDeclaration, but the actual type is
Element.
This Exception occurs when I call AutodiscoverUrl.
I created a web service to do this.
[webMethod]
CreateAppointment()
{
var service = new ExchangeService(ExchangeVersion.Exchange2007_SP1)
{
Credentials = new WebCredentials("myAcount#gmail.com", "mypassowrd")
};
service.AutodiscoverUrl("myAcount#gmail.com");
//----------------------------------------------------------------------
var app = new Appointment(service)
{
Subject = "Meet George",
Body = "You need to meet George",
Location = "1st Floor Boardroom",
Start = DateTime.Now.AddHours(2),
End = DateTime.Now.AddHours(3),
IsReminderSet = true,
ReminderMinutesBeforeStart = 15
};
app.RequiredAttendees.Add(new Attendee("any#gmail.com"));
app.Save(SendInvitationsMode.SendToAllAndSaveCopy);
}
Some potential answers.
Passing in the wrong url or domain.
Passing in a bad email address.
Rebuilding the Windows Profile can sometimes help. (Warning: have an IT Admin do this). And it might be overkill.
A user could have an old, bad, or multiple outlook profiles set up. The email server name could be bad in the outlook profile. (See Control Panel > Mail)
Autodiscover depends on two things:
DNS entries that point from the users mail domain to the Autodiscover data on the Exchange server. Typically you would have a DNS entry with the name autodiscover.domain.com, but there's more than one way of setting this up for different versions of Exchange. If the correct DNS entry doesn't exist, auto-discovery will fail.
Autodiscover data hosted on the Exchange server (I believe it's an XML file) and accessed over HTTP. If this isn't accessible (perhaps it's behind a firewall) then auto-discovery will fail.
Check the appropriate DNS entries and autodiscover information is accessible to your client.

Silverlight: Preventing authentication window / login prompt while connecting SharePoint with different credentials using DataContext (REST)

I'm programming a Silverlight client to consume a list in Sharepoint 2010 using REST. It's supposed to work as a gadget on users Windows desktop.
My requirement is, logging into Sharepoint with specific credentials instead of current logged user. It works fine with the source code I pasted down and I'm able to fetch the list content as expected, however, everytime I run the software, Windows shows a login box - authentication window to user before estabilishing a connection to Sharepoint.
If user skips it by clicking "cancel" the rest of software works normally.
So I need to prevent this login box.
ObservableCollection<ShoutBoxItem> allItems = new ObservableCollection<ShoutBoxItem>();
ShoutsProxy.TwitterDataContext context = new TwitterDataContext(new Uri(webServiceUrl));
context.HttpStack = HttpStack.ClientHttp;
context.Credentials = new System.Net.NetworkCredential(username, password, domain);
context.UseDefaultCredentials = false;
DataServiceQuery<ShoutBoxItem> query = DataServiceQuery<ShoutBoxItem>)context.ShoutBox;
query.BeginExecute(onGetShoutBoxItemsComplete, query);
So at exactly "query.beginexecute" line, a login box comes up immediately.
Any suggestions?
Greetings from Duisburg,
Alper Barkmaz
Well, I have found a workaround for this.
Instead of filling out a NetworkCredential object with login information, I post username and password at web service URL, http://username:password#domain.com/service.svc
And voila, there's no authentication prompt. The point was, my silverlight application was hosted in local html file with address starting with file://, thus transferring network credentials to target domain was having problems. So in this case, instead of dealing this inside Silverlight, I directly modified the URL and the result was brilliant.
Security: I believe httpclient breaks in, does authentication and removes the login information from URL, so the login information is not transferred over network as plain text. However, double checking this is better.
The new form of solution is,
ObservableCollection<ShoutBoxItem> allItems = new ObservableCollection<ShoutBoxItem>();
ShoutsProxy.TwitterDataContext context = new TwitterDataContext(new Uri("http://username:password#domain.com/service.svc"));
context.HttpStack = HttpStack.ClientHttp;
context.Credentials = new System.Net.NetworkCredential();
context.UseDefaultCredentials = false;
DataServiceQuery<ShoutBoxItem> query = DataServiceQuery<ShoutBoxItem>)context.ShoutBox;
query.BeginExecute(onGetShoutBoxItemsComplete, query);

EWS Managed API: Searching an Inbox other than the main mailbox associated with Windows login

I have an application extracting emails from 'User A', with the email address UserA#email.com. I use the following code to do so:
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010);
service.UseDefaultCredentials = true;
service.Url = new Uri(ServerName);
FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.Inbox, new ItemView(500));
This works fine if User A is logged in and runs the application.
However, lets say 'User B' has been granted access to User A's inbox and wants to run the same application to extract files from User A's Inbox. How would I change the code above to specify the email account inbox?
I know that I could hardcode the login details of User A when getting the credentials, but ideally I would avoid having hardcoded usernames but instead use the credentials of the user running the application.
This may just be my lack of understanding, but I'm relatively new to .net and very new to EWS. Any pointers would be much appreciated!
Thanks
Delegation is what I needed:
FolderId InboxId = new FolderId(WellKnownFolderName.Inbox, "UserA#email.com");
FindItemsResults<Item> findResults = service.FindItems(InboxId, new ItemView(500));

Categories