As I understand there is a way to retrieve group where user belong. For example Admins, Users etc.
After doing that I want to transform this into claims. I cannot find how I can retrieve a user's groups.
Currently I am using my local user and not (Domain Active Directory).
Is there any solutions for that issue?
Is it a good approach or it is better to retrieve permissions for each user from the database and then operate with them?
you need to know is that AD is working on windows host only. read Microsoft docs before you start project
add startup configuration , create login page
services
.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.LoginPath = "/Login";
});
.....
app.UseAuthentication();
app.UseAuthorization();
third your needs:
application.json config:
"ldap": {
"path": "LDAP://DC.yourdomain.com",
"domain": "yourdomain.com",
"personFilter": "(SAMAccountName={username})",
"groupFilter": "(&(objectCategory=person)(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))",
//"property": "cn,displayName,mail,givenName,sn,o,title,company,department,telephoneNumber,description,userPrincipalName",
"property": "cn,displayName,mail,givenName,sn,o,title,company,department"
//"property": "cn,member,memberof,sAMAccountName,primaryGroupToken"
}
and you can use this method to check username and password
public Dictionary<string, string> UserInfo { get; private set; }
public bool IsAuthenticated(string username, string password)
{
bool result = false;
string domainAndUsername = Configuration["ldap:domain"] + @"\" + username;
DirectoryEntry entry = new DirectoryEntry(Configuration["ldap:path"], domainAndUsername, password);
try
{
Object obj = entry.NativeObject;
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = Configuration["ldap:personFilter"].Replace("{username}", username);
var propList = Configuration["ldap:property"].Split(',');
search.PropertiesToLoad.AddRange(propList);
SearchResult searchResult = search.FindOne();
if (null == searchResult)
{
return false;
}
foreach (var propName in propList)
{
UserInfo.Add(propName, GetProperty(searchResult.Properties, propName));
}
DirectoryEntry obUser = new DirectoryEntry(searchResult.Path);
object obGroups = obUser.Invoke("Groups");
var groupList = new List<string>();
foreach (object ob in (IEnumerable)obGroups)
{
DirectoryEntry obGpEntry = new DirectoryEntry(ob);
groupList.Add(obGpEntry.Name);
}
UserInfo.Add("group", string.Join(",", groupList));
result = true;
}
catch (Exception ex)
{
throw new SysAuthException("Invalid Authentication", ex);
}
return result;
}
when login success you can check all user info from userInfo property
sample code for login page (add claim and login state to net core pipeline):
try
{
if (Authentication.IsAuthenticated(UserData.Username, UserData.Password))
{
var claims = new List<Claim>() {
new Claim(ClaimTypes.Name, UserData.Username)
};
foreach (var item in Authentication.UserInfo)
{
claims.Add(new Claim(item.Key, item.Value));
}
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var principal = new ClaimsPrincipal(identity);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, new AuthenticationProperties()
{
IsPersistent = UserData.RememberLogin
});
if (!string.IsNullOrEmpty(UserData.ReturnUrl))
return LocalRedirect(UserData.ReturnUrl);
return Redirect("/");
}
}
catch (SysAuthException ex)
{
Error = ex.InnerException.Message;
}
if you need to protect your page add @attribute [Authorize]
in top of your page also you can check other claim for example roles or group with this attribute
sample code show current user info
<div>
<table class="table table-bordered table-striped">
<caption>Current User Info</caption>
@foreach (var claim in User.Claims)
{
<tr><td>@claim.Type</td><td>@claim.Value</td></tr>
}
</table>
</div>