mirror of
https://github.com/freedbygrace/ActiveDirectoryToRestApi.git
synced 2026-08-21 07:06:38 +00:00
Add project files.
This commit is contained in:
@@ -0,0 +1,25 @@
|
|||||||
|
**/.classpath
|
||||||
|
**/.dockerignore
|
||||||
|
**/.env
|
||||||
|
**/.git
|
||||||
|
**/.gitignore
|
||||||
|
**/.project
|
||||||
|
**/.settings
|
||||||
|
**/.toolstarget
|
||||||
|
**/.vs
|
||||||
|
**/.vscode
|
||||||
|
**/*.*proj.user
|
||||||
|
**/*.dbmdl
|
||||||
|
**/*.jfm
|
||||||
|
**/azds.yaml
|
||||||
|
**/bin
|
||||||
|
**/charts
|
||||||
|
**/docker-compose*
|
||||||
|
**/Dockerfile*
|
||||||
|
**/node_modules
|
||||||
|
**/npm-debug.log
|
||||||
|
**/obj
|
||||||
|
**/secrets.dev.yaml
|
||||||
|
**/values.dev.yaml
|
||||||
|
LICENSE
|
||||||
|
README.md
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.7.34024.191
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ActiveDirectoryToRestApi", "src\ActiveDirectoryToRestApi\ActiveDirectoryToRestApi.csproj", "{2A1D2EF2-8050-48ED-AD6A-0049D800DE39}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{69C1A7CC-CE13-44EC-924A-104C576C2D34}"
|
||||||
|
ProjectSection(SolutionItems) = preProject
|
||||||
|
LICENSE = LICENSE
|
||||||
|
README.md = README.md
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{2A1D2EF2-8050-48ED-AD6A-0049D800DE39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{2A1D2EF2-8050-48ED-AD6A-0049D800DE39}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{2A1D2EF2-8050-48ED-AD6A-0049D800DE39}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{2A1D2EF2-8050-48ED-AD6A-0049D800DE39}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {D76E9DAF-9C86-445C-B53D-A96BC45CD2C9}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 zimbres
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# ActiveDirectoryToRestApi
|
||||||
|
|
||||||
|
Rest Api to get some data from Active Directory by LDAP
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<Nullable>disable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||||
|
<DockerfileContext>..\..</DockerfileContext>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.11" />
|
||||||
|
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.5" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||||
|
<PackageReference Include="System.DirectoryServices.Protocols" Version="7.0.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace ActiveDirectoryToRestApi.Configurations;
|
||||||
|
|
||||||
|
public class LdapConfigs
|
||||||
|
{
|
||||||
|
public string Server { get; set; }
|
||||||
|
public string DomainName { get; set; }
|
||||||
|
public string User { get; set; }
|
||||||
|
public string Pass { get; set; }
|
||||||
|
public string DistinguishedName { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
namespace ActiveDirectoryToRestApi.Controllers;
|
||||||
|
|
||||||
|
[ApiController]
|
||||||
|
[Route("[controller]")]
|
||||||
|
public class GroupController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly ILogger<GroupController> _logger;
|
||||||
|
private readonly LdapService _ldapService;
|
||||||
|
|
||||||
|
public GroupController(ILogger<GroupController> logger, LdapService ldapService)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_ldapService = ldapService;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("/group")]
|
||||||
|
public ActionResult<Group> Group(string group = "mygroup")
|
||||||
|
{
|
||||||
|
var members = _ldapService.GetGroupMembers(group);
|
||||||
|
if (members == null)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
return members;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
namespace ActiveDirectoryToRestApi.Controllers;
|
||||||
|
|
||||||
|
[ApiController]
|
||||||
|
[Route("[controller]")]
|
||||||
|
public class UserController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly ILogger<UserController> _logger;
|
||||||
|
private readonly LdapService _ldapService;
|
||||||
|
private readonly AuthUserService _authUserService;
|
||||||
|
|
||||||
|
public UserController(ILogger<UserController> logger, LdapService ldapService, AuthUserService authUserService)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_ldapService = ldapService;
|
||||||
|
_authUserService = authUserService;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("/email")]
|
||||||
|
public ActionResult<User> Email(string email = "test.user@zimbres.com")
|
||||||
|
{
|
||||||
|
var user = _ldapService.GetUserByEmail(email);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("/username")]
|
||||||
|
public ActionResult<User> Username(string username = "testUser")
|
||||||
|
{
|
||||||
|
var user = _ldapService.GetUserByUserName(username);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("/authUser")]
|
||||||
|
public IActionResult AuthUser(UserLogin userLogin)
|
||||||
|
{
|
||||||
|
var status = _authUserService.AuthUser(userLogin.UserName, userLogin.Password);
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
return Unauthorized();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
|
||||||
|
RUN apt update && apt install -y --no-install-recommends libldap-2.4-2 && rm -rf /var/lib/apt/lists/*
|
||||||
|
WORKDIR /app
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
|
||||||
|
WORKDIR /src
|
||||||
|
COPY ["src/ActiveDirectoryToRestApi/ActiveDirectoryToRestApi.csproj", "src/ActiveDirectoryToRestApi/"]
|
||||||
|
RUN dotnet restore "src/ActiveDirectoryToRestApi/ActiveDirectoryToRestApi.csproj"
|
||||||
|
COPY . .
|
||||||
|
WORKDIR "/src/src/ActiveDirectoryToRestApi"
|
||||||
|
RUN dotnet build "ActiveDirectoryToRestApi.csproj" -c Release -o /app/build
|
||||||
|
|
||||||
|
FROM build AS publish
|
||||||
|
RUN dotnet publish "ActiveDirectoryToRestApi.csproj" -c Release -o /app/publish /p:UseAppHost=false
|
||||||
|
|
||||||
|
FROM base AS final
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=publish /app/publish .
|
||||||
|
ENTRYPOINT ["dotnet", "ActiveDirectoryToRestApi.dll"]
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
namespace ActiveDirectoryToRestApi.Extensions;
|
||||||
|
|
||||||
|
public static class LdapAttrExtensions
|
||||||
|
{
|
||||||
|
public static string ConvertToDateTime(this string ldapTime)
|
||||||
|
{
|
||||||
|
if (ldapTime == "0" || ldapTime == "9223372036854775807") return "Never";
|
||||||
|
var date = long.Parse(ldapTime);
|
||||||
|
|
||||||
|
return DateTime.FromFileTime(date).ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsExpired(this string ldapTime)
|
||||||
|
{
|
||||||
|
if (ldapTime == "0" || ldapTime == "9223372036854775807") return false;
|
||||||
|
var expiration = DateTime.FromFileTime(long.Parse(ldapTime));
|
||||||
|
if (expiration < DateTime.Now) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsPasswordExpired(this string userAccountControl)
|
||||||
|
{
|
||||||
|
if (userAccountControl == "8388608") return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsEnabled(this string userAccountControl)
|
||||||
|
{
|
||||||
|
if (userAccountControl == "512" || userAccountControl == "66048" || userAccountControl == "262656") return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsPasswordNeverExpire(this string userAccountControl)
|
||||||
|
{
|
||||||
|
if (userAccountControl == "66048" || userAccountControl == "66050") return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GroupType(this string groupType)
|
||||||
|
{
|
||||||
|
return groupType switch
|
||||||
|
{
|
||||||
|
"2" => "Global distribution group",
|
||||||
|
"4" => "Global distribution group",
|
||||||
|
"8" => "Universal distribution group",
|
||||||
|
"-2147483646" => "Global security group",
|
||||||
|
"-2147483644" => "Domain local security group",
|
||||||
|
"-2147483640" => "Universal security group",
|
||||||
|
_ => null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
global using ActiveDirectoryToRestApi.Configurations;
|
||||||
|
global using ActiveDirectoryToRestApi.Extensions;
|
||||||
|
global using ActiveDirectoryToRestApi.Models;
|
||||||
|
global using ActiveDirectoryToRestApi.Services;
|
||||||
|
global using Microsoft.AspNetCore.Mvc;
|
||||||
|
global using System.ComponentModel;
|
||||||
|
global using System.ComponentModel.DataAnnotations;
|
||||||
|
global using System.DirectoryServices.Protocols;
|
||||||
|
global using System.Net;
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
namespace ActiveDirectoryToRestApi.Models;
|
||||||
|
|
||||||
|
public class Group
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Type { get; set; }
|
||||||
|
public string DistinguishedName { get; set; }
|
||||||
|
public List<string> Members { get; set; } = new();
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
namespace ActiveDirectoryToRestApi.Models;
|
||||||
|
|
||||||
|
public class User
|
||||||
|
{
|
||||||
|
public string FirstName { get; set; }
|
||||||
|
public string LastName { get; set; }
|
||||||
|
public string DisplayName { get; set; }
|
||||||
|
public string Email { get; set; }
|
||||||
|
public string LogonName { get; set; }
|
||||||
|
public string SamAccountName { get; set; }
|
||||||
|
public bool Enabled { get; set; }
|
||||||
|
public bool PasswordNeverExpire { get; set; }
|
||||||
|
public bool PasswordExpired { get; set; }
|
||||||
|
public string PasswordLastSet { get; set; }
|
||||||
|
public string PasswordExpiration { get; set; }
|
||||||
|
public bool Expired { get; set; }
|
||||||
|
public string Expiration { get; set; }
|
||||||
|
public string DistinguishedName { get; set; }
|
||||||
|
public List<string> Groups { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
namespace ActiveDirectoryToRestApi.Models;
|
||||||
|
|
||||||
|
public class UserLogin
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
[DefaultValue("testUser")]
|
||||||
|
public string UserName { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[DefaultValue("Thi$1sMyPassw0rd")]
|
||||||
|
public string Password { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
builder.Services.AddControllers();
|
||||||
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
|
builder.Services.AddSwaggerGen();
|
||||||
|
builder.Services.AddSingleton(provider =>
|
||||||
|
{
|
||||||
|
var configs = builder.Configuration.GetSection(nameof(LdapConfigs)).Get<LdapConfigs>();
|
||||||
|
var endpoint = new LdapDirectoryIdentifier(configs.Server, false, false);
|
||||||
|
var ldapConnection = new LdapConnection(endpoint,
|
||||||
|
new NetworkCredential($"{configs.User}@{configs.DomainName}", configs.Pass))
|
||||||
|
{
|
||||||
|
AuthType = AuthType.Basic
|
||||||
|
};
|
||||||
|
ldapConnection.SessionOptions.ReferralChasing = ReferralChasingOptions.None;
|
||||||
|
ldapConnection.Bind();
|
||||||
|
return ldapConnection;
|
||||||
|
});
|
||||||
|
builder.Services.AddSingleton<LdapService>();
|
||||||
|
builder.Services.AddTransient<AuthUserService>();
|
||||||
|
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
app.UseSwagger();
|
||||||
|
app.UseSwaggerUI();
|
||||||
|
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
app.MapControllers();
|
||||||
|
|
||||||
|
app.Run();
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"profiles": {
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
},
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"applicationUrl": "http://localhost:5220"
|
||||||
|
},
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": false,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Docker": {
|
||||||
|
"commandName": "Docker",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_URLS": "http://+:80"
|
||||||
|
},
|
||||||
|
"publishAllPorts": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:20943",
|
||||||
|
"sslPort": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
namespace ActiveDirectoryToRestApi.Services;
|
||||||
|
|
||||||
|
public class AuthUserService
|
||||||
|
{
|
||||||
|
private readonly IConfiguration _configuration;
|
||||||
|
|
||||||
|
public AuthUserService(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
_configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool AuthUser(string username, string password)
|
||||||
|
{
|
||||||
|
var configs = _configuration.GetSection(nameof(LdapConfigs)).Get<LdapConfigs>();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var endpoint = new LdapDirectoryIdentifier(configs.Server, false, false);
|
||||||
|
using var connection = new LdapConnection(endpoint,
|
||||||
|
new NetworkCredential($"{configs.DomainName}\\{username}", password))
|
||||||
|
{
|
||||||
|
AuthType = AuthType.Basic
|
||||||
|
};
|
||||||
|
connection.SessionOptions.ReferralChasing = ReferralChasingOptions.None;
|
||||||
|
connection.Bind();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (LdapException)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,177 @@
|
|||||||
|
namespace ActiveDirectoryToRestApi.Services;
|
||||||
|
|
||||||
|
public class LdapService
|
||||||
|
{
|
||||||
|
private readonly LdapConfigs _ldapConfigs;
|
||||||
|
private readonly LdapConnection _connection;
|
||||||
|
private readonly IConfiguration _configuration;
|
||||||
|
|
||||||
|
public LdapService(LdapConnection connection, IConfiguration configuration)
|
||||||
|
{
|
||||||
|
_connection = connection;
|
||||||
|
_configuration = configuration;
|
||||||
|
_ldapConfigs = _configuration.GetSection(nameof(LdapConfigs)).Get<LdapConfigs>();
|
||||||
|
}
|
||||||
|
public User GetUserByUserName(string username)
|
||||||
|
{
|
||||||
|
string filter = $"(&(objectClass=user)(objectCategory=person)(sAMAccountName={username}))";
|
||||||
|
return GetUser(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public User GetUserByEmail(string email)
|
||||||
|
{
|
||||||
|
string filter = $"(&(objectClass=user)(objectCategory=person)(mail={email}))";
|
||||||
|
return GetUser(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private User GetUser(string filter)
|
||||||
|
{
|
||||||
|
string[] attributesToReturn = { "givenName", "sn", "mail", "userPrincipalName", "displayName", "sAMAccountName",
|
||||||
|
"userAccountControl", "accountExpires", "memberOf", "distinguishedName", "pwdLastSet" };
|
||||||
|
|
||||||
|
SearchRequest searchRequest = new(_ldapConfigs.DistinguishedName, filter, SearchScope.Subtree, attributesToReturn);
|
||||||
|
|
||||||
|
SearchResponse searchResponse = (SearchResponse)_connection.SendRequest(searchRequest);
|
||||||
|
|
||||||
|
if (searchResponse.Entries.Count > 0)
|
||||||
|
{
|
||||||
|
SearchResultEntry entry = searchResponse.Entries[0];
|
||||||
|
|
||||||
|
string userAccountControl = entry.Attributes["userAccountControl"][0].ToString();
|
||||||
|
string accountExpires = entry.Attributes["accountExpires"][0].ToString();
|
||||||
|
string expiration = accountExpires.ConvertToDateTime();
|
||||||
|
string pwdLastSet = entry.Attributes["pwdLastSet"][0].ToString().ConvertToDateTime();
|
||||||
|
string passwordExpiration = GetPasswordExpiration(pwdLastSet);
|
||||||
|
bool expired = accountExpires.IsExpired();
|
||||||
|
string mail = entry.Attributes["mail"]?[0].ToString() ?? "";
|
||||||
|
string givenName = entry.Attributes["givenName"]?[0].ToString() ?? "";
|
||||||
|
string sn = entry.Attributes["sn"]?[0].ToString() ?? "";
|
||||||
|
string displayName = entry.Attributes["displayName"]?[0].ToString() ?? "";
|
||||||
|
string sAMAccountName = entry.Attributes["sAMAccountName"][0].ToString();
|
||||||
|
string userPrincipalName = entry.Attributes["userPrincipalName"]?[0].ToString() ?? "";
|
||||||
|
string distinguishedName = entry.DistinguishedName;
|
||||||
|
bool enabled = userAccountControl.IsEnabled();
|
||||||
|
bool passwordNeverExpire = userAccountControl.IsPasswordNeverExpire();
|
||||||
|
bool passwordExpired = userAccountControl.IsPasswordExpired();
|
||||||
|
|
||||||
|
var groups = new List<string>();
|
||||||
|
var memberOfAttribute = entry.Attributes["memberOf"];
|
||||||
|
if (memberOfAttribute != null)
|
||||||
|
{
|
||||||
|
foreach (var groupDn in memberOfAttribute.GetValues(typeof(string)))
|
||||||
|
{
|
||||||
|
groups.Add(ParseGroupName(groupDn.ToString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = new User
|
||||||
|
{
|
||||||
|
DisplayName = displayName,
|
||||||
|
Email = mail,
|
||||||
|
SamAccountName = sAMAccountName,
|
||||||
|
Enabled = enabled,
|
||||||
|
LogonName = userPrincipalName,
|
||||||
|
FirstName = givenName,
|
||||||
|
LastName = sn,
|
||||||
|
PasswordNeverExpire = passwordNeverExpire,
|
||||||
|
PasswordExpired = passwordExpired,
|
||||||
|
PasswordLastSet = pwdLastSet,
|
||||||
|
PasswordExpiration = passwordExpiration,
|
||||||
|
Expiration = expiration,
|
||||||
|
Expired = expired,
|
||||||
|
DistinguishedName = distinguishedName,
|
||||||
|
Groups = groups
|
||||||
|
};
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ParseGroupName(string groupDn)
|
||||||
|
{
|
||||||
|
int startIndex = groupDn.IndexOf('=') + 1;
|
||||||
|
int endIndex = groupDn.IndexOf(',');
|
||||||
|
|
||||||
|
if (startIndex > 0 && endIndex > 0)
|
||||||
|
{
|
||||||
|
return groupDn[startIndex..endIndex];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return groupDn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Group GetGroupMembers(string groupName)
|
||||||
|
{
|
||||||
|
Group group = GetGroup(groupName);
|
||||||
|
|
||||||
|
if (group is null) return null;
|
||||||
|
|
||||||
|
string filter = $"(&(objectCategory=user)(memberOf={group.DistinguishedName}))";
|
||||||
|
string[] attributesToReturn = { "sAMAccountName" };
|
||||||
|
|
||||||
|
SearchRequest searchRequest = new(_ldapConfigs.DistinguishedName, filter, SearchScope.Subtree, attributesToReturn);
|
||||||
|
SearchResponse searchResponse = (SearchResponse)_connection.SendRequest(searchRequest);
|
||||||
|
|
||||||
|
foreach (SearchResultEntry entry in searchResponse.Entries)
|
||||||
|
{
|
||||||
|
group.Members.Add(entry.Attributes["sAMAccountName"][0].ToString());
|
||||||
|
}
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Group GetGroup(string groupName)
|
||||||
|
{
|
||||||
|
string filter = $"(&(objectClass=group)(cn={groupName}))";
|
||||||
|
string[] attributesToReturn = { "distinguishedName", "cn", "groupType" };
|
||||||
|
|
||||||
|
SearchRequest searchRequest = new(_ldapConfigs.DistinguishedName, filter, SearchScope.Subtree, attributesToReturn);
|
||||||
|
SearchResponse searchResponse = (SearchResponse)_connection.SendRequest(searchRequest);
|
||||||
|
|
||||||
|
if (searchResponse.Entries.Count > 0)
|
||||||
|
{
|
||||||
|
SearchResultEntry entry = searchResponse.Entries[0];
|
||||||
|
Group group = new()
|
||||||
|
{
|
||||||
|
Name = entry.Attributes["cn"][0].ToString(),
|
||||||
|
Type = entry.Attributes["groupType"][0].ToString().GroupType(),
|
||||||
|
DistinguishedName = searchResponse.Entries[0].DistinguishedName
|
||||||
|
};
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetPasswordExpiration(string pwdLastSet)
|
||||||
|
{
|
||||||
|
var pwdLastSetDate = DateTime.Parse(pwdLastSet);
|
||||||
|
var passwordExpiration = pwdLastSetDate.AddDays(GetMaxPwdAge());
|
||||||
|
return passwordExpiration.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private double GetMaxPwdAge()
|
||||||
|
{
|
||||||
|
string filter = "(objectClass=domain)";
|
||||||
|
string[] attributesToRetrieve = { "maxPwdAge" };
|
||||||
|
|
||||||
|
SearchRequest searchRequest = new(_ldapConfigs.DistinguishedName, filter, SearchScope.Subtree, attributesToRetrieve);
|
||||||
|
SearchResponse searchResponse = (SearchResponse)_connection.SendRequest(searchRequest);
|
||||||
|
|
||||||
|
if (searchResponse.Entries.Count == 1)
|
||||||
|
{
|
||||||
|
SearchResultEntry entry = searchResponse.Entries[0];
|
||||||
|
long value = long.Parse(entry.Attributes["maxPwdAge"][0].ToString());
|
||||||
|
TimeSpan maxPwdAge = TimeSpan.FromTicks(value);
|
||||||
|
double days = maxPwdAge.TotalDays;
|
||||||
|
return Math.Abs(days);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*",
|
||||||
|
"LdapConfigs": {
|
||||||
|
"Server": "192.168.100.25",
|
||||||
|
"DomainName": "AD", // (pre-Windows 2000)
|
||||||
|
"User": "ldapAdmin",
|
||||||
|
"Pass": "Thi$1sMyPassw0rd",
|
||||||
|
"DistinguishedName": "DC=ad,DC=zimbres,DC=com"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user