Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Azure广告-将所有用户的基本信息拉入列表_C#_Asp.net_Azure_Azure Web App Service_Azure Active Directory - Fatal编程技术网

C# Azure广告-将所有用户的基本信息拉入列表

C# Azure广告-将所有用户的基本信息拉入列表,c#,asp.net,azure,azure-web-app-service,azure-active-directory,C#,Asp.net,Azure,Azure Web App Service,Azure Active Directory,我对Azure的所有东西都是新手,我正在使用ASP.NET MVC 4模板项目。 我的目标是将Azure广告中的所有用户拉到一个可枚举列表中,以便我以后搜索 目前,我收到以下错误之一: Server Error in '/' Application Object reference not set to an instance of an object ... Exception Details: System.NullReferenceException: Object reference n

我对Azure的所有东西都是新手,我正在使用ASP.NET MVC 4模板项目。
我的目标是将Azure广告中的所有用户拉到一个可枚举列表中,以便我以后搜索

目前,我收到以下错误之一:

Server Error in '/' Application
Object reference not set to an instance of an object
...
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
或者这个,取决于哪个
。其中(…)
子句我注释掉了:

用于访问Graph API的令牌已过期。单击此处登录并获取新的访问令牌。

单击该链接将调用此URL:

https://login.microsoftonline.com//oauth2/authorize?client_id=&response_mode=form_post&response_type=code+id_token&scope=openid+profile&state=OpenIdConnect.AuthenticationProperties%&nonce=-client SKU=id_NET&x-client-ver=1.0.40306.1554

单击链接尝试了一些操作,但只是将我带着相同的错误放回同一页面,不做任何其他操作

UserProfileController.cs

private ApplicationDbContext db = new ApplicationDbContext();
private string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
private string appKey = ConfigurationManager.AppSettings["ida:ClientSecret"];
private string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
private string graphResourceID = "https://graph.windows.net";

public async Task<Collection<IUser>> GetAllUsers()
{
    var userList = new Collection<IUser>();
    try
    {
        string tenantID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
        Uri servicePointUri = new Uri(graphResourceID);
        Uri serviceRoot = new Uri(servicePointUri, tenantID);
        ActiveDirectoryClient activeDirectoryClient = new ActiveDirectoryClient(serviceRoot,
            async () => await GetTokenForApplication());

        // use the token for querying the graph to get the user details

        var result = await activeDirectoryClient.Users
            //.Where(u => u.JobTitle.Equals("Cool Dudes"))    // Works fine when uncommented, otherwise gives me a server error
            .ExecuteAsync();

        while (result.MorePagesAvailable)
        {
            userList = userList.Concat(result.CurrentPage.ToList()) as Collection<IUser>;
            await result.GetNextPageAsync();
        }
    }
    catch (Exception e)
    {
        if (Request.QueryString["reauth"] == "True")
        {
            // Send an OpenID Connect sign-on request to get a new set of tokens.
            // If the user still has a valid session with Azure AD, they will not
            //  be prompted for their credentials.
            // The OpenID Connect middleware will return to this controller after
            //  the sign-in response has been handled.
            HttpContext.GetOwinContext()
                .Authentication.Challenge(OpenIdConnectAuthenticationDefaults.AuthenticationType);
        }

        return userList;
    }

    return userList;
}

public async Task<ActionResult> Admin()
{
    try
    {
        var user = await GetAllUsers();

        return View(user
            //.Where(u => u.JobTitle.Equals("Cool Dudes"))  // When this is uncommented and the one in GetAllUsers is commented out, I get an error saying "The token for accessing the Graph API has expired. Click here to sign-in and get a new access token."
            );
    }
    catch (AdalException)
    {
        // Return to error page.
        return View("Error");
    }
    // if the above failed, the user needs to explicitly re-authenticate for the app to obtain the required token
    catch (Exception)
    {
        return View("Relogin");
    }
}

public void RefreshSession()
{
    HttpContext.GetOwinContext().Authentication.Challenge(
        new AuthenticationProperties { RedirectUri = "/UserProfile" },
        OpenIdConnectAuthenticationDefaults.AuthenticationType);
}

public async Task<string> GetTokenForApplication()
{
    string signedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
    string tenantID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
    string userObjectID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;

    // get a token for the Graph without triggering any user interaction (from the cache, via multi-resource refresh token, etc)
    ClientCredential clientcred = new ClientCredential(clientId, appKey);
    // initialize AuthenticationContext with the token cache of the currently signed in user, as kept in the app's database
    AuthenticationContext authenticationContext = new AuthenticationContext(aadInstance + tenantID, new ADALTokenCache(signedInUserID));
    AuthenticationResult authenticationResult = await authenticationContext.AcquireTokenSilentAsync(graphResourceID, clientcred, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));
    return authenticationResult.AccessToken;
}
using System.Configuration;
using System.Net.Http;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.Graph;
using Microsoft.IdentityModel.Clients.ActiveDirectory;

namespace <PROJECT_NAME>.Models
{
    class AzureAuthenticationProvider : IAuthenticationProvider
    {
        private string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
        private string appKey = ConfigurationManager.AppSettings["ida:ClientSecret"];
        private string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];

        public async Task AuthenticateRequestAsync(HttpRequestMessage request)
        {
            string signedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
            string tenantID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;

            // get a token for the Graph without triggering any user interaction (from the cache, via multi-resource refresh token, etc)
            ClientCredential creds = new ClientCredential(clientId, appKey);
            // initialize AuthenticationContext with the token cache of the currently signed in user, as kept in the app's database
            AuthenticationContext authenticationContext = new AuthenticationContext(aadInstance + tenantID, new ADALTokenCache(signedInUserID));
            AuthenticationResult authResult = await authenticationContext.AcquireTokenAsync("https://graph.microsoft.com/", creds);

            request.Headers.Add("Authorization", "Bearer " + authResult.AccessToken);
        }
    }
}
private ApplicationDbContext db=new ApplicationDbContext();
私有字符串clientId=ConfigurationManager.AppSettings[“ida:clientId”];
私有字符串appKey=ConfigurationManager.AppSettings[“ida:ClientSecret”];
私有字符串aadInstance=ConfigurationManager.AppSettings[“ida:aadInstance”];
专用字符串graphResourceID=”https://graph.windows.net";
公共异步任务GetAllUsers()
{
var userList=新集合();
尝试
{
字符串tenantID=ClaimsPrincipal.Current.FindFirst(“http://schemas.microsoft.com/identity/claims/tenantid1.价值;
Uri servicePointUri=新Uri(graphResourceID);
Uri serviceRoot=新Uri(servicePointUri,tenantID);
ActiveDirectoryClient ActiveDirectoryClient=新的ActiveDirectoryClient(serviceRoot,
async()=>等待GetTokenFolication());
//使用令牌查询图形以获取用户详细信息
var result=等待activeDirectoryClient.Users
//.Where(u=>u.JobTitle.Equals(“酷哥”)//在未注释时工作正常,否则会导致服务器错误
.ExecuteAsync();
while(result.morepagesavaailable)
{
userList=userList.Concat(result.CurrentPage.ToList())作为集合;
等待结果。GetNextPageAsync();
}
}
捕获(例外e)
{
if(Request.QueryString[“reauth”]=“True”)
{
//发送OpenID连接登录请求以获取一组新令牌。
//如果用户仍然拥有与Azure AD的有效会话,则他们不会
//提示输入他们的凭据。
//OpenID连接中间件将在
//已处理登录响应。
HttpContext.GetOwinContext()
.Authentication.Challenge(OpenIdConnectAuthenticationDefaults.AuthenticationType);
}
返回用户列表;
}
返回用户列表;
}
公共异步任务管理()
{
尝试
{
var user=wait GetAllUsers();
返回视图(用户
//.Where(u=>u.JobTitle.Equals(“Cool Dudes”)//如果未注释此内容,并且GetAllUsers中的内容被注释掉,我会收到一条错误消息:“访问图形API的令牌已过期。单击此处登录并获取新的访问令牌。”
);
}
catch(AdalException)
{
//返回错误页面。
返回视图(“错误”);
}
//如果上述操作失败,用户需要显式地重新验证应用程序以获得所需的令牌
捕获(例外)
{
返回视图(“重新登录”);
}
}
公共会话()
{
HttpContext.GetOwinContext().Authentication.Challenge(
新的AuthenticationProperties{RedirectUri=“/UserProfile”},
OpenIdConnectAuthenticationDefaults.AuthenticationType);
}
公共异步任务GetTokenForApplication()
{
字符串signedInUserID=ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
字符串tenantID=ClaimsPrincipal.Current.FindFirst(“http://schemas.microsoft.com/identity/claims/tenantid1.价值;
字符串userObjectID=ClaimsPrincipal.Current.FindFirst(“http://schemas.microsoft.com/identity/claims/objectidentifier1.价值;
//在不触发任何用户交互的情况下获取图形的令牌(从缓存,通过多资源刷新令牌等)
ClientCredential clientcred=新的ClientCredential(clientId,appKey);
//使用保存在应用程序数据库中的当前登录用户的令牌缓存初始化AuthenticationContext
AuthenticationContext AuthenticationContext=新的AuthenticationContext(aadInstance+tenantID,新的ADALTokenCache(SignedUserId));
AuthenticationResult AuthenticationResult=等待authenticationContext.AcquireTokenSilentAsync(graphResourceID,clientcred,新用户标识符(userObjectID,UserIdentifierType.UniqueId));
返回authenticationResult.AccessToken;
}
Admin.cshtml

@using Microsoft.Azure.ActiveDirectory.GraphClient
@model IEnumerable<IUser>

@{
    ViewBag.Title = "Admin";
}
<h2>@ViewBag.Title.</h2>

<table class="table table-bordered table-striped">
    @foreach (var user in Model)
    {
        <tr>
            <td>Display Name</td>
            <td>@user.DisplayName</td>
            <td>Job Title</td>
            <td>@user.JobTitle</td>
        </tr>
    }
</table>
@使用Microsoft.Azure.ActiveDirectory.GraphClient
@模型IEnumerable
@{
ViewBag.Title=“Admin”;
}
@ViewBag.Title。
@foreach(模型中的var用户)
{
显示名称
@user.DisplayName
职位名称
@user.JobTitle
}
我错过了什么?我的while循环逻辑是否错误?我是否正在使用一种现在已经过时的方式来阅读这些信息?这是权限问题吗

编辑:

缩小范围:

  • GetAllUsers
    (以及可选的
    Admin
    )具有
    Where
    子句时,
    Admin
    返回空页,但没有错误
  • 当只有
    Admin
    具有
    Where
    子句时,返回图形错误
  • 当两者都没有
    Where
    子句时,将返回服务器错误

因此我认为
GetAllUsers
没有正确返回数据。

根据错误消息,它不应该与
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Linq;
using System.Security.Claims;
using System.Web;
using System.Web.Mvc;
using System.Threading.Tasks;
using Microsoft.Azure.ActiveDirectory.GraphClient;  // Will eventually be removed
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.OpenIdConnect;
using <PROJECT_NAME>.Models;
using Microsoft.Graph;
using User = Microsoft.Graph.User;  // This is only here while I work on removing references to Microsoft.Azure.ActiveDirectory.GraphClient

namespace <PROJECT_NAME>.Controllers
{
    [Authorize]
    public class UserProfileController : Controller
    {
        public async Task<List<User>> GetAllUsers()
        {
            List<User> userResult = new List<User>();

            GraphServiceClient graphClient = new GraphServiceClient(new AzureAuthenticationProvider());
            IGraphServiceUsersCollectionPage users = await graphClient.Users.Request().Top(500).GetAsync(); // The hard coded Top(500) is what allows me to pull all the users, the blog post did this on a param passed in
            userResult.AddRange(users);

            while (users.NextPageRequest != null)
            {
                users = await users.NextPageRequest.GetAsync();
                userResult.AddRange(users);
            }

            return userResult;
        }

        // Return all users from Azure AD as a proof of concept
        public async Task<ActionResult> Admin()
        {
            try
            {
                var user = await GetAllUsers();

                return View(user
                    );
            }
            catch (AdalException)
            {
                // Return to error page.
                return View("Error");
            }
            // if the above failed, the user needs to explicitly re-authenticate for the app to obtain the required token
            catch (Exception)
            {
                return View("Relogin");
            }
        }
    }
}
@using Microsoft.Azure.ActiveDirectory.GraphClient
@model IEnumerable<IUser>
@using Microsoft.Graph
@model List<User>