How to search AD Global Caalogue rather than Domain Controller? - c#

I have some c# code that successfully searches a domain however our customer is saying that it needs to search the global catalogue. How easy is this? Does it make any sense?

AD Global Catalog (GC) can be on any Domain Controller (usually it is on all of them) and changes done to Active Directory replicate to all domain controllers every few minutes. There are however some settings in AD that are not replicated and can be only found on this particular domain controller that's why it's often necessary to search the value on all domain controllers then just ask one.
So to answer your question you most likely are doing good job (can't say for sure without source code) querying one domain controller and this is exactly what your customer is requiring you to do. But you may need to add option to scan other domain controllers for additional information (this could be Last Logon Times for users if i remember good that is stored per domain controller and is not replicated).
Unless there's more to it then you are telling us in the question :-)

Firs of all Global Catalog is a Directory. Programaticaly, it can be queried exactly in the same way as Active-Directory.
You just have to find the GCs adresses and ports. It can be easily done, querying the DNS of you client domain for service (SRV) entries _gc._tcp.DNSDomain. The entries will give you the DNS adress and the port (generally 3268) of the global catalogs present.
Here is the Nslookup example :
> set type=srv
> _gc._tcp.societe.fr
Serveur : srventr2.societe.fr
Address: 192.168.183.138
_gc._tcp.societe.fr SRV service location:
priority = 0
weight = 100
port = 3268
svr hostname = srventr2.societe.fr
srventr2.societe.fr internet address = 192.168.183.138
After that, you can search the Global Catalog exactly in the same way as a normal directory. As you can read in comments it's only interresting if you've got multiple domains in your forest. This is because all the objects of all domains of the forest can be found in the GC, but be carefull for each object all the attributes are not present (as specified in the SCHEMA).

The answer to this was pretty simple all I did was change the url from...
GC://<url> to LDAP://<ur>

Related

Force PrincipalContext to connect to a specific server

Is there a way to force PrincipalContext to connect to a specific Domain Controller? I'm enumerating the list of locked accounts for my application, and I would like to be able to query multiple servers and return the list from all DCs.
Currently I get whichever DC my PrincipalContext happens to connect to, and my list is not always completely correct of accounts that are locked out.
I've done some digging, but don't see any way to make reference to which Domain Controller the call for PrincipalContext connects to.
Yes, you can connect to a specific domain controller.
new PrincipalContext(ContextType.Domain, name, container, username, password);
The name part of this principal context can be set to an IP address of a domain controller. I assume that you speak about different active directories otherwise you may have a problem how the domain controllers are distributing the information.
Also, make sure the container is the correct with OC=... and DC=....
Hope it helps!

How can you keep a session across multiple subdomains in c# mvc?

A shopping cart application I'm working on jumps domain when it goes from the normal page into the submit-your-details page.
Long story short there are two copies of the application deployed: one server for the 'main' site and one server with an ev certificate running on https for the customer details (including payment; this is a PCI compliance issue).
My question is this:
When jumping from http://shop.domain -> https://secure.domain (and back, if the user browses back), how can I preserve the session?
Its trivial to pass cookies cross domain using JSONP, but I have no idea what to do with them on the remote side to 'reconnect' to the session.
I have read various things about rolling your own custom session provider, etc. etc. but I haven't found one that is more than just generic advice; certainly no examples of how this might be used to rejoin a session.
This is a for an MVC3 c# web app.
Problem with Session's is that they are kept in the same domain.
If you have the 2 applications in sub domains you can always append this to your web.config
<httpCookies domain=".domain.com"/>
and that will do the trick, but if the domains are completely different, the best way is always to roll out your own session provider or use an existing one, like SQL.
You can use for this any Caching System where instead of append variables into a session variable, you append them into the cache as key/value pair, you can always use a NoSQL alternative (plenty of free accounts out there so you can prototyping and make a proof of concept in order to roll out the final bits).
Memcached server is always a good alternative and Couchbase as the community version available for free.
The trick here is to do this:
Cache.AddObject(key + "UserInfo-name", "Bruno Alexandre");
where key could be a query string value appended in global.asax upon session_start
instead of this
Session["UserInfo-name"] = "Bruno Alexandre";
When you create cookie then you must write
Response.AppendCookie("Your cookie name");
To get that the code is something like
if (Request.Cookies["Your cookie name"] != null)
{
string value = Request.Cookies["Your cookie name"].Value;
}
and if there are different solutions then find
machineKey
which need to be same. you get it under
system.web in web.config file
and then write after machineKey
<httpCookies domain=".yourdomainname.com" />
I am creating user session using HttpContext from a function.
HttpContext cu;
string username = cu.User.Identity.Name;
username = Guid.NewGuid().ToString();
cu.Session["username"] = username;
HttpCookie hc = new HttpCookie("username", username);
hc.Domain = ".yourdomain.com";
hc.Expires = DateTime.Now.AddDays(1d);
cu.Response.Cookies.Add(hc);
With this code, I am able to share session within 3 sub-domains.

Recognizing a returning visitor in ASP.NET

If an anonymous user on a site returns multiple times in a certain period (lets say three times a week), then I need to suggest the user to log in/register on the site.
I was thinking about keeping this info in a cookie, but is there a better way of doing this? Or maybe a standardized way build in .NET or in a third party library?
For anonymous user the only way is the cookie.
You place an encrypted ID to the cookie and connect that id with your anonymous user on the database.
Google set up advertising cookies to last for 30 days for example
http://www.google.com/privacy/ads/
Google analytic set up up to 2 years
http://code.google.com/apis/analytics/docs/concepts/gaConceptsCookies.html
Google Analytics sets an expiration date of 2 years for unique visitor
tracking. However, if your visitors delete their cookies and revisit
your site, then Google Analytics will set new cookies (including new
unique visitor cookies) for those visitors. While you can configure
the duration of a user session cookie (from the default 30 minutes)
using the _setSessionCookieTimeout() method, you cannot configure the
duration of the unique visitor cookie.
There are a few ways, but they not 100% accurate. That said, a cookie would be adequate for your situation.
One other way is that you can check the and store the visitor's IP address combined with the UserAgent value. This might not be entirely accurate since sometimes a company could have lots of internal users, but using only one public IP address.
Hope this helps. Cheers.
You can also use Javascript and localStorage to display the information.
if (localStorage.getItem('lastVisit')) {
alert('You have been here before!');
} else {
localStorage.setItem('lastVisit', new Date());
}
In short, just use a cookie, there isn't anything wrong with this method. Also, this allows the user to clear such information from their system and is the expected behavior of a website from an end-user, so its good practice.
Also quickly, a 'Visitor' is generally defined as a visit from a unique address (eg. IP Address). So you would want to check the IP to consider it as the same visitor. If they visit the website from a different IP, that would be considered a second visitor which is also expected behavior. You could go a bit further here though, and check the browser and consider that a separate visitor, or other specific information that would be available through all web browsers.
Conclusion, just use a cookie and IP Address, try not to over-complicate it, and definitely don't choose an option that isn't cross-browser if you don't go the cookie/IP route.
Hope this helped.

MVC Active Directory Membership

I am trying to make use of the active directory membership rather than SQL but there is very limited documentation available online. I have managed to connect my application to the domain controller without any problems but when you use "Context.User.Identity.Name" it comes up with DOMAIN\User. I want to basically drill down and get information such as full name, e-mail address, etc.
I just need a useful link and the searching I have done doesn't appear to have got me anywhere!
Many thanks
This should give you a bit of a clue: http://msdn.microsoft.com/en-us/library/ms973834.aspx
and here is a list of LDAP properties that you might want to play around with in the search result: http://www.computerperformance.co.uk/Logon/LDAP_attributes_active_directory.htm
Have you tried with this doc?
http://msdn.microsoft.com/en-US/library/system.web.security.activedirectorymembershipprovider%28v=vs.90%29.aspx
Can help?
If you are making use of Active Directory then you are likely using Windows Authentication. If so, all you need to do is:
Reference System.DirectoryServices.AccountManagement
In code (perhaps a controller action or model constructor)
// establishes your domain as the context for your user lookup
var principalContext = new PrincipalContext(ContextType.Domain, "domainName");
// gets the current user's UserPrincipal object
var userPrincipal.FindByIdentity(principalContext, #User.Identity.Name)
// example
var email = userPrincipal.EmailAddress;
Note:
This works because Windows Authentication means User.Identity on the current HttpContext is a WindowsIdentity and thus its Name property can be used to search AD.
You aren't limited to looking up the current user. You can use FindByIdentity() to search any value passed, and this method exists on other principals (ex. GroupPrincipal). You can also designate you wish to search by another type such as SID instead of Name.
Enjoy!

Setting up OpenID Provider with SubDomains Identifiers using DotNetOpenAuth

I am currently trying to implement an OpenID Provider on my own domain name.
Thus, I would like the OpenID Identifier of a user to be user.example.com instead of the default example.com/user.aspx/user..
Is it possible for DotNetOpenAuthto do that? If so, roughly what changes do i need to make?
Yes, it's absolutely possible.
Configure your DNS and web site(s) and IIS to actually respond to user.example.com.
Place a default.aspx file such that it responds to requests for that domain, and make that URL an OpenID Claimed Identifier by placing the tags in it that you find in the user.aspx sample. Be sure in those tags that point to your OP Endpoint that it uses the absolute URL (which may be http://www.example.com/provider.ashx)
Modify your provider.ashx (or server.aspx, or MVC action, whatever you're using for your OP Endpoint) to be willing to send assertions for user.example.com
And you're done. I haven't gone into great detail on these steps because it's the same steps you take when you customize the URL of your claimed identifiers in any way -- special host name or not. The only really special step is #1: Configuring IIS. To accept any random host name requires special DNS configuration, but since it's just your own user name you can just hard-code your username into DNS.

Categories