如何使用C#从Azure Active Directory获取用户最后登录及创建日期
错误原因
- CS1061报错由以下几个常见原因导致:
- 未安装
Microsoft.GraphNuGet包,或项目中存在多版本SDK冲突 - 未引用
Microsoft.Graph命名空间 - Microsoft Graph .NET SDK版本差异:v4与v5的API结构、调用语法存在明显差异,原代码中使用的
.Request()语法仅适用于v4版本
- 未安装
前置权限要求:需要在Azure AD应用注册中为应用配置以下应用权限并完成管理员同意:
- 读取用户创建日期:
User.Read.All- 读取用户登录数据:
AuditLog.Read.All
实现方案
方案1:使用Microsoft Graph .NET SDK v5(当前主流版本)
- 首先安装依赖NuGet包:
Microsoft.Graph(v5.x版本)Azure.Identity(用于身份认证,示例采用客户端密钥流,可根据实际场景替换为其他认证流)
- 代码实现:
using Azure.Identity; using Microsoft.Graph; using Microsoft.Graph.Models; // 初始化Graph客户端 var clientId = "你的应用客户端ID"; var tenantId = "你的Azure AD租户ID"; var clientSecret = "你的应用客户端密钥"; var scopes = new[] { "https://graph.microsoft.com/.default" }; var clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret); var graphClient = new GraphServiceClient(clientSecretCredential, scopes); try { // 获取用户列表,同时拉取账号创建日期、最后登录日期属性 var users = await graphClient.Users.GetAsync(requestConfiguration => { requestConfiguration.QueryParameters.Select = new string[] { "Id", "DisplayName", "UserPrincipalName", "CreatedDateTime", "SignInActivity" }; requestConfiguration.QueryParameters.Top = 999; }); if (users?.Value != null) { foreach (var user in users.Value) { Console.WriteLine($"用户名:{user.DisplayName}"); Console.WriteLine($"用户主体名:{user.UserPrincipalName}"); Console.WriteLine($"账号创建日期:{user.CreatedDateTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "无数据"}"); Console.WriteLine($"最后登录日期:{user.SignInActivity?.LastSignInDateTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "无登录记录"}"); Console.WriteLine("------------------------"); } } // 若需要查询完整审计登录日志,v5调用方式如下 // var signInLogs = await graphClient.AuditLogs.SignIns.GetAsync(); } catch (ServiceException ex) { Console.WriteLine($"Graph API调用错误:{ex.Message}"); }
方案2:使用Microsoft Graph .NET SDK v4(旧版本)
- 首先安装依赖NuGet包:
Microsoft.Graph(v4.x版本)、Microsoft.Graph.Auth - 代码实现:
using Microsoft.Graph; using Microsoft.Graph.Auth; using Microsoft.Identity.Client; // 初始化Graph客户端 var clientId = "你的应用客户端ID"; var tenantId = "你的Azure AD租户ID"; var clientSecret = "你的应用客户端密钥"; IConfidentialClientApplication confidentialClientApp = ConfidentialClientApplicationBuilder .Create(clientId) .WithTenantId(tenantId) .WithClientSecret(clientSecret) .Build(); ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApp); var graphClient = new GraphServiceClient(authProvider); try { // 获取用户列表和所需属性 var users = await graphClient.Users .Request() .Select("Id,DisplayName,UserPrincipalName,CreatedDateTime,SignInActivity") .Top(999) .GetAsync(); foreach (var user in users) { Console.WriteLine($"用户名:{user.DisplayName}"); Console.WriteLine($"用户主体名:{user.UserPrincipalName}"); Console.WriteLine($"账号创建日期:{user.CreatedDateTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "无数据"}"); Console.WriteLine($"最后登录日期:{user.SignInActivity?.LastSignInDateTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "无登录记录"}"); Console.WriteLine("------------------------"); } // 审计日志查询方式(v4版本) // var signIns = await graphClient.AuditLogs.SignIns.Request().GetAsync(); } catch (ServiceException ex) { Console.WriteLine($"Graph API调用错误:{ex.Message}"); }
常见问题排查
- 若返回的
SignInActivity为空,确认已为应用授予AuditLog.Read.All权限且完成管理员同意 - 若租户用户量超过999,需要实现分页逻辑,通过返回结果中的
NextPageRequest获取下一页数据 - 确认项目中没有同时引用v4和v5版本的Graph SDK,避免命名空间冲突
内容的提问来源于stack exchange,提问作者Manikanta gadamsetti
相关产品推荐
相关产品推荐

