Issue Querying LDAP DirectoryEntry in ASP.NET - asp.net

I have users login to my application via Active Directory and then pull from their AD information to garner information about that user like so:
Dim ID as FormsIdentity = DirectCast(User.Identity, FormsIdentity)
Dim ticket as FormsAuthenticationTicket = ID.Ticket
Dim adDirectory as New DirectoryEntry("LDAP://DC=my,DC=domain,DC=com")
Dim adTicketID as String = ticket.Name.Substring(0, 5)
Session("people_id") = adDirectory.Children.Find("CN=" & adTicketID).Properties("employeeID").Value
Session("person_name") = adDirectory.Children.Find("CN=" & adTicketID).Properties("displayName").Value
Now, I want to be able to impersonate other users...so that I can "test" the application as them, so I added a textbox and a button to the page and when the button is clicked the text is assigned to a session variable like so:
Session("impersonate_user") = TextBox1.Text
When the page reloads I check to see if Session("impersonate_user") has a value other than "" and then attempt to query Active Directory using this session variable like so:
If CStr(Session("impersonate_user")) <> "" Then
Dim adDirectory as New DirectoryEntry(LDAP://DC=my,DC=domain,DC=com")
Dim adTicketID as String = CStr(Session("impersonate_user"))
Session("people_id") = adDirectory.Children.Find("CN=" & adTicketID).Properties("employeeID").Value
Session("person_name")= adDirectory.Children.Find("CN=" & adTicketID).Properties("displayName").Value
Else
[use the actual ticket.name to get this info.]
End If
But this doesn't work. Instead, it throws an error on the first Session line stating, "DirectoryServicesCOMException was unhandled by user code There is no such object on the server."
Why? I know I'm giving it a valid username! Is something strange happening in the casting of the session? The code is essentially the same between each method except that in one method rather than pulling from ticket.Name I pull from a session variable for the login I'll be looking up with AD.

Maybe the identity your process is running under needs permissions to access the active directory. You could do this by changing the identity your application runs under in the IIS application pool.
What is entered in the textbox?

Related

How do I log a user back in after change of Email/Username? - Asp.net/VB.Net

I found this code on a site which was written for me and works, and I'm trying to use it on a new site. The code checks that a emailAddress doesn't already exist when a user edits their account details, and because the emailAddress is also used as the underlying .NET membership username it needs to change that too. So far I've managed to get it to change the email address in tblAccounts which is done with this call:
acc.UpdateUsername(txtEmailAddress.Text, lblEmailAddress.Text)
Then it needs to check if the user changing the email is the logged in user and re-log them back in. This doesn't seem to work as I get this error from the siteMaster when it tries to redirect to the homepage:
System.NullReferenceException: Object reference not set to an instance of an object.
The error is caused in the siteMaster when it tries to check messages for logged in user and it flags up the last line of this as where the error occurs:
If HttpContext.Current.User.Identity.IsAuthenticated Then
hypSettings.visible=true
Dim counter As Integer = messaging.CheckUnreadMessages(Membership.GetUser.ProviderUserKey)
It therefore looks like the email address is being updated where it should, but the site isn't logging the user back in correctly. As I say, it works on the site where I took the code from and there isn't much difference between the sites, but I don't understand memberships and cookies too well so I'm not sure if something needs altering elsewhere?
Here's the code for changing the users email address:
'Check if the Role has been changed
Membership.ApplicationName = "/OCBS"
Dim userID As Guid = Guid.Parse(Request.QueryString("aID"))
Dim usr As MembershipUser = Membership.GetUser(userID, False)
'Now check if the email address has been changed, because the email address is used for the username then the underlying .NET membership username needs changing
If txtEmailAddress.Text <> lblEmailAddress.Text Then
'Email has been changed, update the username for this user
Dim acc As New accounts(Guid.Empty)
acc.UpdateUsername(txtEmailAddress.Text, lblEmailAddress.Text)
'Check if the user changing the email is the logged in user and re-log them back in
If User.Identity.Name = lblEmailAddress.Text Then
'FormsAuthentication.SetAuthCookie(txtEmailAddress.Text, False)
Response.Cookies.Clear()
Dim expiryDate As DateTime = DateTime.Now.AddDays(100)
Dim ticket As New FormsAuthenticationTicket(2, txtEmailAddress.Text, DateTime.Now, expiryDate, True, [String].Empty)
Dim encryptedTicket As String = FormsAuthentication.Encrypt(ticket)
Dim authenticationCookie As New HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
authenticationCookie.Expires = ticket.Expiration
Response.Cookies.Add(authenticationCookie)
End If
End If
Oooh, I've managed it.. I added this..
Session.Abandon()
FormsAuthentication.SignOut()
after line: Response.Cookies.Clear()

ASP.NET Membership provider password in email replace

We use the built in asp.net membership provider to handle users accounts. The default temporary passwords that the provider creates are a little too complex for our users so I've used the below code to generate one that's a little easier to key in so that they can reset their passwords. It's working perfectly to generate the new passwords and the membership provider is using it instead of the complex one.
Here is where my issue is: When the users request a temporary password the application emails it to them. I'm trying to replace the temporary password with the one I'm generating. You can see in the below screenshots that the password I generate appends to the bottom of the email but I can't get the <%Password%> to be replaced with my new one. What am I missing?
Public Sub PasswordRecovery1_SendingMail(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.MailMessageEventArgs) Handles PasswordRecovery1.SendingMail
Dim User As MembershipUser = Membership.GetUser(PasswordRecovery1.UserName)
Dim msg As String = e.Message.Body
Dim oldpswd As String = User.ResetPassword()
Dim newpass As String = GetPassword()
msg.Replace("<%Password%>", newpass)
msg += "<p>Your new password is: " & newpass & "</p>"
User.ChangePassword(oldpswd, newpass)
e.Message.Body = msg
End Sub
Email Template I'd like to update with newpass
Email that goes to user still has old password and new one at the bottom
Replaced the "<%Password%>" with "<-TemporaryPasswordArea>" in my template, then changed the msg assignment to the following and it's replacing it correctly in the email.
msg = msg.Replace("<-TemporaryPasswordArea>", newpass)

ASP.net Coding User Roles into Login Page

I've developed a login page, which functions off of a stored procedure. The login part functions well, however, the website will consist of roles that will determine what page the user is directed to once they are logged into the secure section. The columns I’m focusing on in the database / table are:
Guid -0 column
Login_name -9th column
Login_Pwd -10th column
Role_ID -11th column / Contains a value of 1 or a 2
What I’m trying to do is: get the login page to distinguish between the users with a Role_ID of 1 and those that have a Role_ID of 2. But, currently, when I log into the page, I’m directed to the SecurePage.aspx regardless of what Role ID the user has. Could I please get some direction on this?
This is my Stored Procedure:
ALTER PROCEDURE [dbo].[Check_Users]
#Login_name as varchar(100),
#Login_Pwd as varchar(50)
AS
/* SET NOCOUNT ON */
SELECT * FROM SupplierCompany WHERE Login_name=#Login_name AND Login_Pwd=#Login_Pwd
RETURN
This is the code behind my login button:
Try
Dim con As New SqlConnection(GetConnectionString())
con.Open()
Dim cmd As New SqlCommand("Check_Users", con)
cmd.CommandType = CommandType.StoredProcedure
Dim p1 As New SqlParameter("Login_name", username.Text)
Dim p2 As New SqlParameter("Login_Pwd", password.Text)
cmd.Parameters.Add(p1)
cmd.Parameters.Add(p2)
Dim rd As SqlDataReader = cmd.ExecuteReader()
If rd.HasRows Then
rd.Read()
lblinfo.Text = "You are Authorized."
FormsAuthentication.RedirectFromLoginPage(username.Text, True)
Response.Redirect("securepages/SecurePage.aspx")
Else
lblinfo.Text = "Invalid username or password."
End If
'check the Role of the usre logging in
While (rd.Read())
Session("numrecord") = rd.GetValue(0).ToString()
rd.GetValue(11).ToString()
If rd.GetValue(11).ToString() = 1 Then
Response.Redirect("securepages/SecurePage.aspx")
ElseIf rd.GetValue(11).ToString() = 2 Then
Response.Redirect("securepages/newShipment.aspx")
End If
End While
Catch
Finally
End Try
..Any assistance is greatly appreciated.
Inside your If rd.HasRows Then you redirect to the SecurePage, so I'm guessing it doesn't even reach the while. Try removing the Response.Redirect("securepgaes/SecurePage.aspx") inside this if, and adding the while loop there, like this:
If rd.HasRows Then
rd.Read()
lblinfo.Text = "You are Authorized."
FormsAuthentication.RedirectFromLoginPage(username.Text, True)
'Response.Redirect("securepages/SecurePage.aspx") Remove this line
'check the Role of the user logging in
While (rd.Read())
Session("numrecord") = rd.GetValue(0).ToString()
rd.GetValue(11).ToString()
If rd.GetValue(11).ToString() = 1 Then
Response.Redirect("securepages/SecurePage.aspx")
ElseIf rd.GetValue(11).ToString() = 2 Then
Response.Redirect("securepages/newShipment.aspx")
End If
End While
Else
lblinfo.Text = "Invalid username or password."
End If
Where have you defined the code to redirect the logged in user?
The Login control by default will try and redirect you to a destination page once successful. I would think you should hook in to the OnLoggedIn event and redirect the page before the server has a chance to do it for you.
As an alternative if that doesn't work you could try building your own 'Login Control' - since you are using a stored procedure to validate users anyway, it's not a huge leap to dump a few textboxes on the page and go that way. At least then you don't need to worry about overriding the default behaviour. I believe ASP.NET provides a bunch of SPs you can use which will validate user passwords and such - check it out on the server (they are all like dbo.aspnet_*.

How do I populate multiple textboxes based on value of another textbox or dropdownlist?

hello again.
We have a webform that employees use to make request for such things as VPN access to the company resources from remote locations.
I am populating a dropdownlist box from Active Directory. This works fine.
Then I have a textbox that is also populated from Active Directory by simply assigning the value of the logged in user as shown:
textbox1.Text = User.Identity.Name
Based on the value of my name assigned to textbox1.Text
The rest of the texboxes are populated with my work information with the following code:
textbox1.Text = User.Identity.Name
textbox1.Text = StrConv(textbox1.Text, vbProperCase)
txtdate.Text = DateTime.Now.ToString("MM/dd/yyyy")
Try
'Creates a Directory Entry Instance with the Username and Password provided
Dim deSystem As New DirectoryEntry("LDAP://OU=Departments,DC=domaname, DC=com", "usrname", "password")
'Authenticacion type Secure
deSystem.AuthenticationType = AuthenticationTypes.Secure
'Creates a Directory Searcher Instance
Dim dsSystem As New DirectorySearcher(deSystem)
'sAMAccountName is equal to our username passed in.
dsSystem.Filter = "sAMAccountName=" & textbox1.Text
'Properties that the Procedures will load from Active Directory
dsSystem.PropertiesToLoad.Add("mail") 'email address
dsSystem.PropertiesToLoad.Add("department") 'dept
dsSystem.PropertiesToLoad.Add("physicalDeliveryOfficeName") 'office
dsSystem.PropertiesToLoad.Add("title") 'title, eg programmer1
dsSystem.PropertiesToLoad.Add("telephoneNumber") 'phone
dsSystem.PropertiesToLoad.Add("streetAddress") 'street address
dsSystem.PropertiesToLoad.Add("l") 'city
dsSystem.PropertiesToLoad.Add("st") 'state
dsSystem.PropertiesToLoad.Add("postalCode") 'zip code
dsSystem.PropertiesToLoad.Add("EmployeeId") 'empid
dsSystem.PropertiesToLoad.Add("givenName") '//first name from active directory
dsSystem.PropertiesToLoad.Add("sn") '//lastname from active directory
'Find the user data
Dim srSystem As SearchResult = dsSystem.FindOne()
'Obtains the properties recently loaded
txtemail.Text = srSystem.Properties("mail").Item(0).ToString
dept.Text = srSystem.Properties("department").Item(0).ToString
office.Text = srSystem.Properties("physicalDeliveryOfficeName").Item(0).ToString
txttitle.Text = srSystem.Properties("title").Item(0).ToString
phone.Text = srSystem.Properties("telephoneNumber").Item(0).ToString
workaddress.Text = srSystem.Properties("streetAddress").Item(0).ToString
city.Text = srSystem.Properties("l").Item(0).ToString
state.Text = srSystem.Properties("st").Item(0).ToString
zipcode.Text = srSystem.Properties("postalCode").Item(0).ToString
hiddenempId.Value = srSystem.Properties("EmployeeId").Item(0).ToString
HiddenFName.Value = srSystem.Properties("givenName").Item(0).ToString
HiddenLName.Value = srSystem.Properties("sn").Item(0).ToString
This works fine as well.
Here is where my problem lies.
Initially, when the user logs in, based on logged user name from Active Directory, the rest of the textboxes get populated with the user's info.Sorry for repeating myself here.
However, sometimes, the user logged in is not necessarily the user needing reguest.
In other words, I can log in to fill a request for another employee.
In this case, I am required to select the name of the user I am completing the request for from the dropdownlist that is populated from Active Directory.
When I select this name from dropdownlist, it replaces my own name on textbox1.Text.
This works fine but the rest of the textboxes retain my own information.
What do I need to do to ensure that the name that replaces my original name on textbox1.Text also replaces the information on the rest of the textboxes?
I will post additional information as requested.
Many thanks in advance
Instead of loading all the text boxes when the form loads, load them from the TextChanged event of the user name text box. That way, any time the user name text box changes, all the other text boxes will automatically be re-loaded to reflect the change.

Exception thrown when using GData .NET Analytics API

I am facing an issue while trying to fetch data from GoogleAnalytics API on piece of code that has been working well just a couple of days ago.
For this I am referencing the following DLL's:
Google.GData.Analytics.dll
Google.GData.Client.dll
Google.GData.Extensions.dll
And I am using the following code:
Dim visits As String = String.Empty
Dim username As String = "myuser#mydomain.com"
Dim pass As String = "mypassword"
Const dataFeedUrl As String = "https://www.google.com/analytics/feeds/data"
Dim query As AccountQuery = New AccountQuery()
Dim service As AnalyticsService = New AnalyticsService("MyWebAnalyticsService")
service.setUserCredentials(username, pass)
Dim accountFeed As AccountFeed = service.Query(query) ''----------> Exception thrown in this line: GDataRequestException Execution of request failed: https://www.google.com/analytics/feeds/accounts/default
I thought it had to do with a blocking to the account I was using but it wasn't the case because I verified registering the site for another analytics account and is still not working.
This code has been working flawlessly as I've said but all of a sudden has stopped doing so yesterday.
Could you please help me figuring out what's wrong?. Maybe the way the user credentials are set has changed and I am missing something.
Thank you very much for your help.
'----Update----
I managed to make it work and now I can query the visits for a desired domain. The code goes as follows:
Dim visits As String = String.Empty
Dim username As String = "myuser#mydomain.com"
Dim pass As String = "mypassword"
'Follow the instructions on https://developers.google.com/analytics/resources/articles/gdata-migration-guide (Create a Project in the Google APIs Console) to generate your key
'Once you have it set it as part of the querystring to request our GA service
Dim gkey As String = "key=yourkeystring"
'Set the new URI to retrieve the feed data and append it the generated key
Dim dataFeedUrl As String = "https://www.google.com/analytics/feeds/data?" & gkey
'Create and authenticate on our service instance
Dim service As AnalyticsService = New AnalyticsService("MyAnaliticsService")
service.setUserCredentials(username, pass)
'Use the profile id for the account you want to get ths visits from, you can find it
'logging in your analytics account, select the desired domain on your list (blue link)
click on the administrator button and on the profiles tab find the profile
'configuration subtab, right there you will find the profile id in this case the eight characters long id 12345678
Dim query1 As DataQuery = New DataQuery(dataFeedUrl)
With query1
.Ids = "ga:12345678"
.Metrics = "ga:visits"
.Sort = "ga:visits"
.GAStartDate = DateTime.Now.AddMonths(-1).AddDays(-2).ToString("yyyy-MM-dd")
.GAEndDate = DateTime.Now.ToString("yyyy-MM-dd")
.StartIndex = 1
End With
'Use the generated datafeed based on the former query to get the visits
Dim dataFeedVisits As DataFeed = service.Query(query1)
For Each entry As DataEntry In dataFeedVisits.Entries
Dim st As String = entry.Title.Text
Dim ss As String = entry.Metrics(0).Value
visits = ss
Next
I have the same problem and it looks like google recently shut down the feed. It is answered in another post. Issue com.google.gdata.util.ResourceNotFoundException: Not Found with Google Analytic
Please make sure you registered your project in the APIs Console and you are sending the API Key with your requests.
If that is not the issue, inspecting the inner exception will give you more details about the error. As an alternative, you can use Fiddler to capture the HTTP request and the response. The latter will include a more descriptive error message.

Resources