我在 .netcore 3.1 中有一个应用程序,我需要使用以下技术为我的组织嵌入 power bi 板:userOwnsData。我遇到的问题是我的应用程序已经通过活动目录进行了日志记录,并且在尝试添加功能 bi embed 的逻辑时,它以某种方式与正在运行的内容发生冲突或冲突。颜色数据 ?: Tenant + appId + Secret 是同一个键。也许有一种方法可以将我的活动目录生成的令牌放入 power bi,我不知道。
我开始下载微软在本指南中提供的代码,在输入TenantId、applicationid和secret时正确执行。这个应用程序运行良好,问题是当我尝试将此代码集成到我现有的应用程序中时。
Embed Power BI content using a sample embed for your organization
我的应用程序也使用活动目录进行用户登录,嵌入和显示 power bi 报告部分是它的一个模块。所以,我想我在尝试使用两种不同的配置来使用 azure 工具登录时遇到了问题......我在下面分享了我的应用程序设置代码,启动和控制器嵌入仪表板。
{
"Logging": {
"LogLevel": {
"Default": "Information","microsoft": "Warning","microsoft.Hosting.Lifetime": "Information"
}
},"Mail": {
"ApiKeySendGrid": "xxxsecretxxx"
},"AllowedHosts": "*",//active Directory
"AzureAd": {
"Instance": "https://login.microsoftonline.com","Domain": "organization domain","TenantId": "xxxsecretxxx","ClientId": "xxxsecretxxx","CallbackPath": "/signin-oidc","SignedOutCallbackPath": "/signout-oidc"
},//PBI EMBED USER OWNS DATA
"AzureAd2": {
"Instance": "https://login.microsoftonline.com/","Domain": "https://api.powerbi.com","ClientSecret": "xxxsecretxxx","CallbackPath": "/signin-oidc2",},"PowerBiHostname": "https://app.powerbi.com"
}
我的启动:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NFP.Repository.Contexts;
using DB_Admin.Filters;
using microsoft.AspNetCore.Builder;
using microsoft.AspNetCore.Hosting;
using microsoft.AspNetCore.Http;
using microsoft.AspNetCore.HttpsPolicy;
using microsoft.EntityFrameworkCore;
using microsoft.Extensions.Configuration;
using microsoft.Extensions.DependencyInjection;
using microsoft.Extensions.Hosting;
using NFP.IRepository;
using NFP.Repository.MySQL;
using NFP.IAplication;
using NFP.Aplication;
using microsoft.AspNetCore.Authentication.AzureAD.UI;
using microsoft.AspNetCore.Authentication;
using microsoft.AspNetCore.Authentication.OpenIdConnect;
using microsoft.AspNetCore.Authorization;
using microsoft.AspNetCore.Mvc.Authorization;
using microsoft.Identity.Web;
using microsoft.Identity.Web.UI;
using microsoft.AspNetCore.Rewrite;
using microsoft.AspNetCore.Mvc.Filters;
using microsoft.AspNetCore.Http.Features;
namespace NFP.DataClinic.Presentation
{
public static class InjectionStart
{
public static IServiceCollection ResolveThisContext(this IServiceCollection services,IConfiguration Configuration) => services
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Graph api base url
var graphBaseUrl = "https://graph.microsoft.com/v1.0";
// Graph scope for reading logged in user's info
var userReadScope = "user.read";
// List of scopes required
string[] initialScopes = new string[] { userReadScope };
services.AddmicrosoftIdentityWebAppAuthentication(Configuration,"AzureAd");
services.AddmicrosoftIdentityWebAppAuthentication(Configuration,"AzureAd2")
.EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
.AddmicrosoftGraph(graphBaseUrl,userReadScope)
.AddSessionTokenCaches();
services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
});
services.AddRazorPages().AddMvcOptions(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
}).AddmicrosoftIdentityUI();
//Dependency Injection
services.ResolveThisContext(Configuration);
services.AddSingleton<IHttpContextaccessor,HttpContextaccessor>();
services.Configure<FormOptions>(options => options.ValueCountLimit = 5000);
services.AddMvc(config =>
{
config.Filters.Add(new CustomactionFilter());
});
services.AddMvc()
.AddMvcOptions(options =>
{
options.MaxModelBindingCollectionSize = int.MaxValue;
options.MaxModelValidationErrors = 999999;
});
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromDays(1); // It depends on user requirements.
});
var config = new ConfigurationBuilder() //newForAD
.SetBasePath(System.IO.Directory.getcurrentDirectory())//newForAD
.AddJsonFile("appsettings.json",false)//newForAD
.Build();//newForAD
}
[AttributeUsage(Attributetargets.Class | Attributetargets.Method,AllowMultiple = false,Inherited = true)]
public class RequestFormSizeLimitAttribute : Attribute,IAuthorizationFilter,IOrderedFilter
{
private readonly FormOptions _formOptions;
public RequestFormSizeLimitAttribute(int valueCountLimit)
{
_formOptions = new FormOptions()
{
ValueCountLimit = valueCountLimit
};
}
public int Order { get; set; }
public void OnAuthorization(AuthorizationFilterContext context)
{
var features = context.HttpContext.Features;
var formFeature = features.Get<IFormFeature>();
if (formFeature == null || formFeature.Form == null)
{
// Request form has not been read yet,so set the limits
features.Set<IFormFeature>(new FormFeature(context.HttpContext.Request,_formOptions));
}
}
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios,see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticfiles();
app.UseRouting();
//app.UseCookiePolicy();
app.UseAuthentication();
app.UseAuthorization();
app.UseSession(); //cambio
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",pattern: "{controller=Home}/{action=Index}/{id?}");
//endpoints.MapRazorPages();
});
}
}
}
在此声明中,问题似乎是,如果我保留原始版本:
services.AddmicrosoftIdentityWebAppAuthentication (Configuration)
我的应用程序像以前一样运行,通过活动目录正确登录,指南建议添加它,以便它也可以登录到 power bi(最后 3 行),但会产生会话错误,甚至活动目录停止工作。
所以,目前正在尝试这个,它告诉我: System.InvalidOperationException: 'Scheme already exists: Cookies'
services.AddmicrosoftIdentityWebAppAuthentication(Configuration,userReadScope)
.AddSessionTokenCaches();
请注意,由于我缺乏经验,我尝试将 AzureAd2 调用到我的新应用设置配置中,认为这样我可以很好地接受它们,但它也不起作用。
更新:
既然我知道需要获取 AD 令牌并使用它来验证低谷 power bi,我在这里列出负责执行令牌获取方法的控制器......
/ ----------------------------------------------------------------------------
// Copyright (c) microsoft Corporation.
// Licensed under the MIT license.
// ----------------------------------------------------------------------------
namespace DataClinic.Presentation.Controllers
{
using Domain.PbiEmbedUOD;
using microsoft.AspNetCore.Authorization;
using microsoft.AspNetCore.Mvc;
using microsoft.Identity.Web;
using microsoft.Graph;
using System.Threading.Tasks;
[Authorize]
public class ReportsController : Controller
{
private readonly GraphServiceclient m_graphServiceclient;
private readonly ITokenAcquisition m_tokenAcquisition;
public ReportsController(ITokenAcquisition tokenAcquisition,GraphServiceclient graphServiceclient)
{
this.m_tokenAcquisition = tokenAcquisition;
this.m_graphServiceclient = graphServiceclient;
}
public IactionResult Index()
{
return View();
}
// Redirects to login page to request increment consent
[AuthorizeForScopes(Scopes = new string[] { PowerBiScopes.ReadDashboard,PowerBiScopes.ReadReport,PowerBiScopes.ReadWorkspace } )]
public async Task<IactionResult> Embed()
{
// Generate token for the signed in user
var accessToken = await m_tokenAcquisition.GetaccessTokenForUserAsync(new string[] { PowerBiScopes.ReadDashboard,PowerBiScopes.ReadWorkspace });
// Get username of logged in user
var userInfo = await m_graphServiceclient.Me.Request().Getasync();
var username = userInfo.DisplayName;
AuthDetails authDetails = new AuthDetails
{
username = username,accessToken = accessToken
};
return View(authDetails);
}
}
}