Find group membership using System.DirectoryServices.AccountManagement - active-directory

I'm trying to authenticate a user against Active Directory using the types in the AccountManagement namespace/assembly in my .NET 4 application (VisualStudio 2010). Here is the code I have:
private Boolean ValidateUser(String domainName, String userName, String password)
{
var ou = String.Format(CultureInfo.InvariantCulture,
"LDAP://{0}.mydomain.com/dc={0},dc=mydomain,dc=com",
domainName);
var domain = String.Format(CultureInfo.InvariantCulture,
"{0}.mydomain.com",
domainName);
using (var context = new PrincipalContext(ContextType.Domain,
domain,
ou))
{
if (context.ValidateCredentials(userName, password))
{
var userPrincipal = UserPrincipal.FindByIdentity(context,
IdentityType.SamAccountName,
userName);
return userPrincipal.IsMemberOf(context, IdentityType.Name, "GroupName");
}
return false;
}
}
The code runs great until the statement where I call FindByIdentity. This call results in the following exception:
System.DirectoryServices.AccountManagement.PrincipalOperationException was caught
Message=Unknown error (0x80005000)
Source=System.DirectoryServices.AccountManagement
ErrorCode=-2147463168
StackTrace:
at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInit()
at System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit()
at System.DirectoryServices.AccountManagement.PrincipalContext.Initialize()
at System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx()
at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext context, Type principalType, Nullable`1 identityType, String identityValue, DateTime refDate)
at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithType(PrincipalContext context, Type principalType, IdentityType identityType, String identityValue)
at System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context, IdentityType identityType, String identityValue)
at Dominos.Pulse.Server.Security.DirectoryServices.ActiveDirectoryAuthenticationProvider.ValidateUser(String domainName, String userName, String password)
InnerException: System.Runtime.InteropServices.COMException
Message=Unknown error (0x80005000)
Source=System.DirectoryServices
ErrorCode=-2147463168
StackTrace:
at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
at System.DirectoryServices.DirectoryEntry.Bind()
at System.DirectoryServices.DirectoryEntry.get_SchemaEntry()
at System.DirectoryServices.AccountManagement.ADStoreCtx.IsContainer(DirectoryEntry de)
at System.DirectoryServices.AccountManagement.ADStoreCtx..ctor(DirectoryEntry ctxBase, Boolean ownCtxBase, String username, String password, ContextOptions options)
at System.DirectoryServices.AccountManagement.PrincipalContext.CreateContextFromDirectoryEntry(DirectoryEntry entry)
at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInit()
InnerException:
Clearly I have something configured wrong. If not, perhaps I'm simply going about this the wrong way.
My goal is to simply authenticate the user against A/D then make sure that they are the member of a specific group (or groups). What am I doing wrong?

Can you try to dine OU like this :
var ou = String.Format(CultureInfo.InvariantCulture,
"dc={0},dc=mydomain,dc=com",
domainName);
The root context is just not need to validate credentials.

Related

Getting socket error while accessing azure cognitive search index

I have created an index in the azure portal and I am trying to access the index in my code to get the data. Everytime I do it I get a {System.Net.Sockets.SocketException (11001): No such host is known at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)}.
Is there anything I can do for this?
Below is my code
static void Main(string[] args)
{
Index();
}
public static DocumentSearchResult<SearchResult> Index()
{
IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile("appsettings.json");
IConfigurationRoot configuration = builder.Build();
string serviceName = configuration["SearchServiceName"];
string key = configuration["SearchServiceQueryApiKey"];
//Creating search client
SearchServiceClient serviceClient = new SearchServiceClient(serviceName, new SearchCredentials(key));
SearchIndexClient indexClient = new SearchIndexClient(serviceName, "cognitivesearchpoc", new SearchCredentials(key));
SearchParameters parameters;
DocumentSearchResult<SearchResult> results;
parameters = new SearchParameters() { Select = new[] { "*" } };
return indexClient.Documents.Search<SearchResult>("*");
}
The error message is telling you that the host name to which you’re trying to connect is incorrect. Use just the host name portion of your service endpoint as the service name. In your case, that’s just “devglobalsearch” without the DNS suffix.

Could not generate emails getting error

System.Net.Mail.SmtpException: Failure sending mail. ---> System.Net.WebException: The remote name could not be resolved: 'mailrelay'
at System.Net.ServicePoint.GetConnection(PooledStream PooledStream, Object owner, Boolean async, IPAddress& address, Socket& abortSocket, Socket& abortSocket6)
at System.Net.PooledStream.Activate(Object owningObject, Boolean async, GeneralAsyncDelegate asyncCallback)
at System.Net.PooledStream.Activate(Object owningObject, GeneralAsyncDelegate asyncCallback)
at System.Net.ConnectionPool.GetConnection(Object owningObject, GeneralAsyncDelegate asyncCallback, Int32 creationTimeout)
at System.Net.Mail.SmtpConnection.GetConnection(ServicePoint servicePoint)
at System.Net.Mail.SmtpTransport.GetConnection(ServicePoint servicePoint)
at System.Net.Mail.SmtpClient.GetConnection()
at System.Net.Mail.SmtpClient.Send(MailMessage message)
--- End of inner exception stack trace ---
at System.Net.Mail.SmtpClient.Send(MailMessage message)
at EmailSender.PerformDelivery(IMessage message)
below is my code
mail = new MailMessage();
string[] toAddresses = email.To.EmailAddress.Split(new char[] { ';' });
foreach (string toAddress in toAddresses)
{
if (!string.IsNullOrEmpty(toAddress.Trim()))
{
mail.To.Add(new MailAddress(toAddress));
}
}
string[] ccAddresses = email.CcEmail.Split(new char[] { ';' });
foreach (string ccAddress in ccAddresses)
{
if (!string.IsNullOrEmpty(ccAddress.Trim()))
{
mail.CC.Add(new MailAddress(ccAddress));
}
}
string[] bccAddresses = email.BccEmail.Split(new char[] { ';' });
foreach (string bccAddress in bccAddresses)
{
if (!string.IsNullOrEmpty(bccAddress.Trim()))
{
mail.Bcc.Add(new MailAddress(bccAddress));
}
}
mail.From = new MailAddress(email.From.EmailAddress,email.From.FullName);
mail.Subject = email.Subject;
mail.Body = email.Body;
if (email.Body.Contains("<html>"))
{
mail.IsBodyHtml = true;
}
if (!email.ExcludeAttachment && !string.IsNullOrEmpty(email.AttachmentPath))
mail.Attachments.Add(new Attachment(email.AttachmentPath));
client = new SmtpClient();
client.Host = ConfigurationSettings.AppSettings["SmtpServer"].ToString();
client.Send(mail);
It looks like ConfigurationSettings.AppSettings["SmtpServer"].ToString() is returning "mailrelay"
Check your AppSettings (normally in web.config), find the SmtpServer setting and change it to a machine name, ip address or domain name that is a mail relay that will accept emails from your app (most mail relays are secured to prevent spammers using them).
If "mailrelay" does work on your dev machine, ping it and find out what IP address it is resolving to. It needs to resolve to a machine that your other environment can see too. If it's a local test machine, then chances are that a production server in a hosting environment can't access it.

Save Cookie in Silverlight Application

I have a silverlight Web Application and want to save user credentials if it checks "Keep me signed in" checkbox.
if (KeepMeSignedIn)
{
SetCookie("CECrd", userName, password);
}
The Set cookie function is as folows..
private static void SetCookie(string key, string uname, string password)
{
string cookieName = "CECrd";
string oldCookie = HtmlPage.Document.GetProperty(cookieName) as String;
DateTime expiration = DateTime.UtcNow + TimeSpan.FromDays(2000);
string cookie = String.Format("{0}={1}={2};expires={3}",key,uname, password, expiration.ToString("R"));
HtmlPage.Document.SetProperty(cookieName, cookie);
}
But i am unable to save the cookie in the browser.
Please help me out.
Cookies consist of name-value "pairs"
e.g.
Name=value
AnotherName=AnotherValue
expires=somedate
Your string.format has a property with 2 equals signs in it!
string cookie = String.Format("{0}={1}={2};expires={3}",key,uname, password, expiration.ToString("R"))
Which generates "{key}={uname}={password};expires={somedate2000daysfromnow}" which is two entries:
{key}={uname}={password}; // invalid
expires={somedate2000daysfromnow} // Valid

[RuntimeException: No EntityManager bound to this thread. Try to annotate your action method with #play.db.jpa.Transactional]

this is the problem once i try to save data into db with sql statement insert.
my function is this:
public void save(){
JPA.em().persist(this);
}
and
public static Result registered() {
Form<User> requestform = form(User.class).bindFromRequest();
if(requestform.hasErrors()){
return badRequest("<p>fehlerhafte eingabe!</p>").as("text/html");
} else {
User user = requestform.get();
String fullname = user.fullname;
String email = user.email;
String password = user.password;
String username = user.username;
new User(username, password, fullname, email).save();
}
return redirect(controllers.routes.Application.index());
}
thanks for help
It is just like the debugging message says, you do not have an entity manager bound to your methods because they are not marked as transactions.
#play.db.jpa.Transactional
public static Result registered() {
Also, if you are using EBean, you could just extend Model for your User class, which comes with many handy built in functions for database use, see documentation here: http://www.playframework.org/documentation/2.0.1/JavaEbean

How to Use a Web Service to Update TextBox controls in ASP.NET?

I have a web form where I need to add, update, delete and read using a unique ID. So far I have managed to add, update and delete functions with little trouble.
However now I am having trouble getting my read function to work (understand I have a webform that has four text fields; ID, FIRSTNAME, SURNAME AND ADDRESS). Basically when an ID that has been previously created (using add button) is entered into the text field and the read button clicked it should update the other 3 text fields with the stored entries depending on the ID entered.
Here is my behind code (cs.) on the web form
protected void cmdRead_Click(object sender, EventArgs e)
{
// Create a reference to the Web service
DbWebService.WebService1 proxy = new DbWebService.WebService1();
// Create a person details object to send to the Web service.
string ADDRESS;
string SURNAME;
string FIRSTNAME;
string ID;
ADDRESS = txtAddress.Text;
SURNAME = txtSurname.Text;
FIRSTNAME = txtFirstname.Text;
ID = txtID.Text;
// Attempt to store in the Web service
bool rsp = proxy.ReadPerson(int.Parse(ID), FIRSTNAME, SURNAME, ADDRESS);
// Inform the user
if (rsp)
{
lblOutcome.Text = "Successfully read data.";
txtFirstname.Text = FIRSTNAME;
txtSurname.Text = SURNAME;
txtAddress.Text = ADDRESS;
}
else
{
lblOutcome.Text = "Failed to read data! Select a previously created ID!";
}
}
and here is my web function on the web service (which is where the SQL Server Express database is)
[WebMethod]
public bool ReadPerson(int ID, string FIRSTNAME, string SURNAME, string ADDRESS)
{
// In case of failure failure first
bool rtn = false;
// Connect to the Database
SqlConnection connection = new SqlConnection(#"Data Source=.\SQLEXPRESS;AttachDbFilename='|DataDirectory|\Database.mdf';Integrated Security=True;User Instance=True");
// Open the connection
connection.Open();
// Prepare an SQL Command
SqlCommand command = new SqlCommand(String.Format("SELECT FIRSTNAME, SURNAME, ADDRESS FROM PersonalDetails WHERE ID = '{0}'", ID), connection);
// Execute the SQL command and get a data reader.
SqlDataReader reader = command.ExecuteReader();
// Instruct the reader to read the first record.
if (reader.Read())
{
// A record exists, thus the return value is updated
FIRSTNAME = (string)reader["FIRSTNAME"];
SURNAME = (string)reader["SURNAME"];
ADDRESS = (string)reader["ADDRESS"];
rtn = true;
}
// Close the connection
connection.Close();
// Return the result.
return (rtn);
}
Now the problem is when I click read I get a success message (using a label as you can see in the behind code) but the fields don't update, I assume this is because of the (rtn = true;) statement. Therefore I thought something like this might work:
rtn = (bool)reader["ADDRESS"];
However with this I get a specified cast is not valid, so I figure maybe the bool doesn't work in this context, I think it might work if I use string instead but how do I convert, I think rtn needs a value in regards to the reader right??
Basically I am just looking for a solution to which will update the text fields in the web form.
There are several problems with your code. The most obvious is that your code cannot ever return the data from the database. You are sending FIRSTNAME etc. to the web service - you are not returning them from the web service.
There is no reason to have a bool return from the service to tell you whether or not it succeeded. Let the service throw an exception if it failed. Instead, you should return the fields from the database as the return of the service.
In the service:
public class Person
{
public string FIRSTNAME {get;set;}
public string SURNAME {get;set;}
public string ADDRESS {get;set;}
}
[WebMethod]
public Person ReadPerson(int ID)
{
// ...
if (reader.Read())
{
// A record exists, thus return the value
Person p = new Person();
p.FIRSTNAME = (string)reader["FIRSTNAME"];
p.SURNAME = (string)reader["SURNAME"];
p.ADDRESS = (string)reader["ADDRESS"];
rtn = p;
}
connection.Close();
return rtn;
}
Also, you should not be using a WebMethod or an ASMX web service unless you have no choice. ASMX is a legacy technology which is kept around only for backwards compatability. It should not be used for new development. You should use WCF instead.
The other issues with your code are resolved below:
[WebMethod]
public Person ReadPerson(int id)
{
using (
var connection =
new SqlConnection(
#"Data Source=.\SQLEXPRESS;
AttachDbFilename='|DataDirectory|\Database.mdf';
Integrated Security=True;
User Instance=True")
)
{
connection.Open();
using (
var command =
new SqlCommand(#"
SELECT FIRSTNAME, SURNAME, ADDRESS
FROM PersonalDetails
WHERE ID = #id",
connection))
{
var idParameter =
command.Parameters.Add(
"#id", SqlDbType.Int);
idParameter.Value = id;
using (var reader = command.ExecuteReader())
{
if (!reader.Read())
{
return null;
}
return new Person
{
Firstname =
(string)
reader["FIRSTNAME"],
Surname =
(string)
reader["SURNAME"],
Address =
(string)
reader["ADDRESS"]
};
}
}
}
}
The main issue is that the SqlConnection, SqlCommand, and SqlDataReader all need to be instantiated inside of using blocks. This ensures that the objects are disposed of (closed) whether or not an exception is thrown.
Next, you should not get into the habit of building queries through string manipulation; not even using String.Format. That leaves you open to "SQL Injection" attacks. Using parameters resolves that problem. See "Commands and Parameters " in MSDN.
One last minor issue: I recommend that you get out of the habit of placing comments on obvious statements. For instance, it's not necessary to comment that Open opens the connection to the database, or that return returns a value.

Resources