我想在azure active directory中为应用程序(应用程序级别)创建自定义角色。我尝试使用图形api,但得到的异常是"上下文已经在跟踪实体。"。我在下面附上我的代码。请找出问题所在。请告诉我如何添加自定义应用程序角色。
using Microsoft.Azure.ActiveDirectory.GraphClient;
using Microsoft.Azure.ActiveDirectory.GraphClient.Extensions;
using Microsoft.Owin.Security.OpenIdConnect;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using WebAppGraphAPI.Utils;
namespace WebAppGraphAPI.Controllers
{
public class ApplicationRoleController : Controller
{
private static readonly string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
// GET: ApplicationRole
public async Task<ActionResult> Index()
{
var roleList = new List<AppRole>();
try
{
ActiveDirectoryClient client = AuthenticationHelper.GetActiveDirectoryClient();
IPagedCollection<IApplication> pagedCollection = await client.Applications.Where(x => x.AppId == clientId).ExecuteAsync();
if (pagedCollection != null)
{
do
{
List<IApplication> applicationItemList = pagedCollection.CurrentPage.ToList();
foreach (IApplication application in applicationItemList)
{
roleList.Add((AppRole)application.AppRoles);
}
pagedCollection = await pagedCollection.GetNextPageAsync();
} while (pagedCollection != null && pagedCollection.MorePagesAvailable);
}
}
catch (Exception e)
{
if (Request.QueryString["reauth"] == "True")
{
//
// Send an OpenID Connect sign-in 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);
}
//
// The user needs to re-authorize. Show them a message to that effect.
//
ViewBag.ErrorMessage = "AuthorizationRequired";
return View(roleList);
}
return View(roleList);
}
/// <summary>
/// Creates a view to for adding a new <see cref="User" /> to Graph.
/// </summary>
/// <returns>A view with the details to add a new <see cref="User" /> objects</returns>
public ActionResult CreateRole()
{
return View();
}
[HttpPost]
public async Task<ActionResult> CreateRole(
[Bind(
Include =
"DisplayName,Value"
)] AppRole role)
{
ActiveDirectoryClient client = null;
try
{
client = AuthenticationHelper.GetActiveDirectoryClient();
}
catch (Exception e)
{
if (Request.QueryString["reauth"] == "True")
{
//
// Send an OpenID Connect sign-in 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);
}
//
// The user needs to re-authorize. Show them a message to that effect.
//
ViewBag.ErrorMessage = "AuthorizationRequired";
return View();
}
try
{
////Get Current application from active directory
IPagedCollection<IApplication> pagedCollection = await client.Applications.Where(x => x.AppId == clientId).ExecuteAsync();
var appObject = pagedCollection.CurrentPage.ToList().FirstOrDefault();
appObject.AppRoles.Add(role as AppRole);
////
////Am Getting Exception Here as "The context is already tracking the entity."....
////
await client.Applications.AddApplicationAsync(appObject);
return RedirectToAction("Index");
}
catch (Exception exception)
{
ModelState.AddModelError("", exception.Message);
return View();
}
}
}
}
很抱歉延迟了响应。以下是如何向用户添加应用程序角色分配。这个代码片段也是我们在github上的控制台应用程序示例的一部分:https://github.com/AzureADSamples/ConsoleApp-GraphAPI-DotNet.您将在示例中找到其他有用的操作。
#region Assign Direct Permission
try
{
User user =
(User)activeDirectoryClient.Users.ExecuteAsync().Result.CurrentPage.ToList().FirstOrDefault();
if (appObject.ObjectId != null && user != null && newServicePrincpal.ObjectId != null)
{
AppRoleAssignment appRoleAssignment = new AppRoleAssignment();
appRoleAssignment.Id = appRole.Id;
appRoleAssignment.ResourceId = Guid.Parse(newServicePrincpal.ObjectId);
appRoleAssignment.PrincipalType = "User";
appRoleAssignment.PrincipalId = Guid.Parse(user.ObjectId);
user.AppRoleAssignments.Add(appRoleAssignment);
user.UpdateAsync().Wait();
Console.WriteLine("User {0} is successfully assigned direct permission.", retrievedUser.DisplayName);
}
}
catch (Exception e)
{
Console.WriteLine("Direct Permission Assignment failed: {0} {1}", e.Message,
e.InnerException != null ? e.InnerException.Message : "");
}