C# .NET 5.0使用JWT和OpenId授权

C# .NET 5.0使用JWT和OpenId授权,c#,azure,asp.net-core,authorization,asp.net-core-5.0,C#,Azure,Asp.net Core,Authorization,Asp.net Core 5.0,我有一个针对定制JWT授权的web API,如下所示: services.AddAuthentication(x => { x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(x => { x.Events =

我有一个针对定制JWT授权的web API,如下所示:

services.AddAuthentication(x =>
{
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(x =>
{
    x.Events = new JwtBearerEvents
    {
        OnTokenValidated = context =>
        {
            var userService = context.HttpContext.RequestServices.GetRequiredService<IUserService>();
            var userId = new Guid(context.Principal.Identity.Name);
            var user = userService.GetById(userId);
            if (user == null)
            {
                context.Fail("Unauthorized");
            }
            return Task.CompletedTask;
        }
    };
    x.RequireHttpsMetadata = false;
    x.SaveToken = true;
    x.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration["Jwt:Key"])),
        ValidateIssuer = false,
        ValidateAudience = false,
        ValidateLifetime = true
    };
});
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Identity.Web;
using Microsoft.Graph;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using _2_1_Call_MSGraph.Models;
using System.IO;

namespace _2_1_Call_MSGraph.Controllers
{
    [Authorize]
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;

        private readonly GraphServiceClient _graphServiceClient;

        public HomeController(ILogger<HomeController> logger,
                          GraphServiceClient graphServiceClient)
        {
            _logger = logger;
            _graphServiceClient = graphServiceClient;
        }

        [AuthorizeForScopes(ScopeKeySection = "DownstreamApi:Scopes")]
        public async Task<IActionResult> Index()
        {
            var user = await _graphServiceClient.Me.Request().GetAsync();
            ViewData["ApiResult"] = user.DisplayName;

            return View();
        }

        [AuthorizeForScopes(ScopeKeySection = "DownstreamApi:Scopes")]
        public async Task<IActionResult> Profile()
        {
            var me = await _graphServiceClient.Me.Request().GetAsync();
            ViewData["Me"] = me;

            try
            {
                // Get user photo
                using (var photoStream = await _graphServiceClient.Me.Photo.Content.Request().GetAsync())
                {
                    byte[] photoByte = ((MemoryStream)photoStream).ToArray();
                    ViewData["Photo"] = Convert.ToBase64String(photoByte);
                }
            }
            catch (System.Exception)
            {
                ViewData["Photo"] = null;
            }

            return View();
        }
        public IActionResult Privacy()
        {
            return View();
        }

        [AllowAnonymous]
        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}
像这样

services.AddAuthentication(x =>
{
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(x =>
{
    x.Events = new JwtBearerEvents
    {
        OnTokenValidated = context =>
        {
            var userService = context.HttpContext.RequestServices.GetRequiredService<IUserService>();
            var userId = new Guid(context.Principal.Identity.Name);
            var user = userService.GetById(userId);
            if (user == null)
            {
                context.Fail("Unauthorized");
            }
            return Task.CompletedTask;
        }
    };
    x.RequireHttpsMetadata = false;
    x.SaveToken = true;
    x.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration["Jwt:Key"])),
        ValidateIssuer = false,
        ValidateAudience = false,
        ValidateLifetime = true
    };
}).AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
.AddMicrosoftGraph(Configuration.GetSection("MicrosoftApi"))
.AddInMemoryTokenCaches();
services.AddAuthentication(x=>
{
x、 DefaultAuthenticateScheme=JwtBearerDefaults.AuthenticationScheme;
x、 DefaultChallengeScheme=JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(x=>
{
x、 事件=新JWTBeareEvents
{
OnTokenValidated=上下文=>
{
var userService=context.HttpContext.RequestServices.GetRequiredService();
var userId=新Guid(context.Principal.Identity.Name);
var user=userService.GetById(userId);
if(user==null)
{
上下文。失败(“未经授权”);
}
返回Task.CompletedTask;
}
};
x、 RequireHttpsMetadata=false;
x、 SaveToken=true;
x、 TokenValidationParameters=新的TokenValidationParameters
{
ValidateSuersigningKey=true,
IssuerSigningKey=new-SymmetricSecurityKey(Encoding.ASCII.GetBytes(配置[“Jwt:Key”]),
validateisuer=false,
ValidateAudience=false,
ValidateLifetime=true
};
}).AddMicrosoftIdentityWebApp(Configuration.GetSection(“AzureAd”))
.EnableTokenAcquisitionTollDownstreamAPI(初始范围)
.AddMicrosoftGraph(Configuration.GetSection(“MicrosoftApi”))
.AddInMemoryTokenCaches();
我不知道如何操作OpenId部分,并且从未调用OAuth工作流

如何在特定控制器上集成github示例中的附加Microsoft OAuth工作流,而不破坏当前的身份验证方案?我知道
AuthenticationSchemes
-名称缺失,但我不知道在哪里添加它

我是否首先选择了正确的OAuth工作流(用户调用API,API触发Microsoft OAuth获取令牌,API然后使用令牌获取日历数据,API处理日历数据,然后API将处理后的日历数据传递给用户):?

如您所见,它提到了以下信息:

到目前为止,您所做的似乎是正确的,根据您提供的文档和GitHub示例,您必须将
GraphServiceClient
添加为目标控制器中的参数之一,并通过将其值分配给控制器的变量来使用它。控制器的示例代码如下所示:

services.AddAuthentication(x =>
{
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(x =>
{
    x.Events = new JwtBearerEvents
    {
        OnTokenValidated = context =>
        {
            var userService = context.HttpContext.RequestServices.GetRequiredService<IUserService>();
            var userId = new Guid(context.Principal.Identity.Name);
            var user = userService.GetById(userId);
            if (user == null)
            {
                context.Fail("Unauthorized");
            }
            return Task.CompletedTask;
        }
    };
    x.RequireHttpsMetadata = false;
    x.SaveToken = true;
    x.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration["Jwt:Key"])),
        ValidateIssuer = false,
        ValidateAudience = false,
        ValidateLifetime = true
    };
});
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Identity.Web;
using Microsoft.Graph;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using _2_1_Call_MSGraph.Models;
using System.IO;

namespace _2_1_Call_MSGraph.Controllers
{
    [Authorize]
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;

        private readonly GraphServiceClient _graphServiceClient;

        public HomeController(ILogger<HomeController> logger,
                          GraphServiceClient graphServiceClient)
        {
            _logger = logger;
            _graphServiceClient = graphServiceClient;
        }

        [AuthorizeForScopes(ScopeKeySection = "DownstreamApi:Scopes")]
        public async Task<IActionResult> Index()
        {
            var user = await _graphServiceClient.Me.Request().GetAsync();
            ViewData["ApiResult"] = user.DisplayName;

            return View();
        }

        [AuthorizeForScopes(ScopeKeySection = "DownstreamApi:Scopes")]
        public async Task<IActionResult> Profile()
        {
            var me = await _graphServiceClient.Me.Request().GetAsync();
            ViewData["Me"] = me;

            try
            {
                // Get user photo
                using (var photoStream = await _graphServiceClient.Me.Photo.Content.Request().GetAsync())
                {
                    byte[] photoByte = ((MemoryStream)photoStream).ToArray();
                    ViewData["Photo"] = Convert.ToBase64String(photoByte);
                }
            }
            catch (System.Exception)
            {
                ViewData["Photo"] = null;
            }

            return View();
        }
        public IActionResult Privacy()
        {
            return View();
        }

        [AllowAnonymous]
        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}
使用系统;
使用系统诊断;
使用System.Threading.Tasks;
使用Microsoft.AspNetCore.Authorization;
使用Microsoft.Identity.Web;
使用Microsoft.Graph;
使用Microsoft.AspNetCore.Mvc;
使用Microsoft.Extensions.Logging;
使用_2_1_Call _MSGraph.Models;
使用System.IO;
命名空间_2_1_调用_MSGraph.Controllers
{
[授权]
公共类HomeController:控制器
{
专用只读ILogger\u记录器;
专用只读GraphServiceClient(GraphServiceClient);
公共家庭控制器(ILogger logger,
GraphService客户端GraphService客户端)
{
_记录器=记录器;
_graphServiceClient=graphServiceClient;
}
[AuthorizeForScopes(ScopeKeySection=“DownstreamApi:Scopes”)]
公共异步任务索引()
{
var user=await_graphServiceClient.Me.Request().GetAsync();
ViewData[“ApiResult”]=user.DisplayName;
返回视图();
}
[AuthorizeForScopes(ScopeKeySection=“DownstreamApi:Scopes”)]
公共异步任务配置文件()
{
var me=await_graphServiceClient.me.Request().GetAsync();
ViewData[“Me”]=Me;
尝试
{
//获取用户照片
使用(var photoStream=await _graphServiceClient.Me.Photo.Content.Request().GetAsync())
{
byte[]photoByte=((内存流)photoStream.ToArray();
ViewData[“Photo”]=转换.tobase64字符串(photoByte);
}
}
捕获(系统异常)
{
ViewData[“照片”]=null;
}
返回视图();
}
公共IActionResult隐私()
{
返回视图();
}
[异名]
[ResponseCache(持续时间=0,位置=ResponseCache位置。无,NoStore=true)]
公共IActionResult错误()
{
返回视图(新的ErrorViewModel{RequestId=Activity.Current?.Id??HttpContext.TraceIdentifier});
}
}
}

我仍然收到错误消息
{“code:generalException\r\n消息:发送请求时出错。\r\n”}
。请检查是否已设置所有正确的设置。