C# MVC5应用程序中来自Azure ADB2C的AccessToken

C# MVC5应用程序中来自Azure ADB2C的AccessToken,c#,oauth-2.0,access-token,openid-connect,azure-ad-b2c,C#,Oauth 2.0,Access Token,Openid Connect,Azure Ad B2c,我们正在开发一个MVC5 web应用程序,它使用OpenIdConnect对Azure AD B2C进行身份验证。当用户通过身份验证后,我们希望能够从Azure AD B2C获取AccessToken,以便将其用于我们的API 这是我们的Startup.cs等效代码: protected override void ProcessCore(IdentityProvidersArgs args) { Assert.ArgumentNotNull(args, nameof(args));

我们正在开发一个MVC5 web应用程序,它使用OpenIdConnect对Azure AD B2C进行身份验证。当用户通过身份验证后,我们希望能够从Azure AD B2C获取AccessToken,以便将其用于我们的API

这是我们的Startup.cs等效代码:

protected override void ProcessCore(IdentityProvidersArgs args)
{
    Assert.ArgumentNotNull(args, nameof(args));

    List<B2CConfig> ssoSettings = _ssoConfigurationRepository.GetAllSettings();

    foreach (var config in ssoSettings)
    {
        args.App.UseOpenIdConnectAuthentication(CreateOptionsFromSiteConfig(config));
    }
}

private OpenIdConnectAuthenticationOptions CreateOptionsFromSiteConfig(B2CConfig config)
{
    OpenIdConnectAuthenticationOptions options = new OpenIdConnectAuthenticationOptions();
    options.MetadataAddress = string.Format(_aadInstance, _tenant, config.Policy);
    options.AuthenticationType = config.Policy;
    options.AuthenticationMode = AuthenticationMode.Passive;
    options.RedirectUri = config.AzureReplyUri;
    options.PostLogoutRedirectUri = config.LogoutRedirectUri;
    options.TokenValidationParameters = new TokenValidationParameters
    {
        NameClaimType = "emails"
    };

    var identityProvider = GetIdentityProvider();

    options.Notifications = new OpenIdConnectAuthenticationNotifications()
    {
        AuthenticationFailed = AuthenticationFailed,
        RedirectToIdentityProvider = notification =>
        {
            return Task.FromResult(notification.ProtocolMessage.UiLocales = config.UiLocale ?? string.Empty);
        },
        SecurityTokenValidated = notification =>
        {
            notification.AuthenticationTicket.Identity.AddClaim(new Claim("idp", "azureadb2c"));

            // transform all claims
            ClaimsIdentity identity = notification.AuthenticationTicket.Identity;
            notification.AuthenticationTicket.Identity.ApplyClaimsTransformations(new TransformationContext(FederatedAuthenticationConfiguration, identityProvider));

            return Task.CompletedTask;
        }
    };

    options.ClientId = config.ClientId;
    options.Scope = "openid";
    options.ResponseType = "id_token";

    return options;
}

private Task AuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
{
    notification.HandleResponse();

    // Handle the error code that Azure AD B2C throws when trying to reset a password from the login page
    // because password reset is not supported by a "sign-up or sign-in policy"
    if (notification.ProtocolMessage.ErrorDescription != null && notification.ProtocolMessage.ErrorDescription.Contains("AADB2C90118"))
    {
        SsoLogger.Warn("User triggered reset password");
        notification.Response.Redirect(SsoConfiguration.Routes.ResetPassword);
    }
    else if (notification.Exception.Message == "access_denied")
    {
        notification.Response.Redirect("/");
    }
    else
    {
        SsoLogger.Warn("AuthenticationFailed", notification.Exception);
        notification.Response.Redirect(SsoConfiguration.Routes.LoginError);
    }

    return Task.FromResult(0);
}
protected override void ProcessCore(IdentityProvidersArgs args)
{
Assert.ArgumentNotNull(args,nameof(args));
列出ssoSettings=\u ssoConfigurationRepository.GetAllSettings();
foreach(ssoSettings中的变量配置)
{
args.App.UseOpenIdConnectAuthentication(CreateOptionsFromSiteConfig(config));
}
}
私有OpenIdConnectAuthenticationOptions CreateOptionsFromSiteConfig(B2CConfig配置)
{
OpenIdConnectAuthenticationOptions=新的OpenIdConnectAuthenticationOptions();
options.MetadataAddress=string.Format(_aadInstance,_tenant,config.Policy);
options.AuthenticationType=config.Policy;
options.AuthenticationMode=AuthenticationMode.Passive;
options.RedirectUri=config.AzureReplyUri;
options.postlogutredirecturi=config.logutredirecturi;
options.TokenValidationParameters=新的TokenValidationParameters
{
NameClaimType=“电子邮件”
};
var identityProvider=GetIdentityProvider();
options.Notifications=新的OpenIdConnectAuthenticationNotifications()
{
AuthenticationFailed=AuthenticationFailed,
RedirectToIdentityProvider=通知=>
{
返回Task.FromResult(notification.ProtocolMessage.UiLocales=config.UiLocale??string.Empty);
},
SecurityTokenValidated=通知=>
{
通知.AuthenticationTicket.Identity.AddClaim(新索赔(“idp”、“azureadb2c”));
//转换所有索赔
ClaimsIdentity identity=notification.AuthenticationTicket.identity;
notification.AuthenticationTicket.Identity.applycaimstransformations(新转换上下文(FederatedAuthenticationConfiguration,identityProvider));
返回Task.CompletedTask;
}
};
options.ClientId=config.ClientId;
options.Scope=“openid”;
options.ResponseType=“id\u令牌”;
返回选项;
}
私有任务身份验证失败(身份验证失败通知)
{
notification.HandleResponse();
//处理Azure AD B2C在尝试从登录页面重置密码时抛出的错误代码
//因为“注册或登录策略”不支持密码重置
if(notification.ProtocolMessage.ErrorDescription!=null&¬ification.ProtocolMessage.ErrorDescription.Contains(“AADB2C90118”))
{
SSOLOGER.Warn(“用户触发重置密码”);
通知、响应、重定向(SsoConfiguration.Routes.ResetPassword);
}
else if(notification.Exception.Message==“访问被拒绝”)
{
通知.响应.重定向(“/”);
}
其他的
{
ssogger.Warn(“AuthenticationFailed”,notification.Exception);
通知.响应.重定向(SsoConfiguration.Routes.LoginError);
}
返回Task.FromResult(0);
}
在Asp.NETCore中,您似乎要在HttpContext上调用
GetTokenAsync
,但该扩展方法在.NET4.72中不可用


有谁能帮我们弄清楚,如何从AzureAD B2C检索accesstoken,它可以用于调用我们的WebApi?或者我可以只存储从SecurityTokenValidated事件获得的accesstoken并将其用于所有API请求吗?

这是一种可能的解决方案:


如果有人有更好的方法,我很乐意接受另一个答案。

您可以参考此示例:。相关文档如下:。身份验证部分起作用-我只需要知道以后如何获取AccessToken
Notifications = new OpenIdConnectAuthenticationNotifications
{
    SecurityTokenValidated = notification =>
    {
        var identity = notification.AuthenticationTicket.Identity;
        identity.AddClaim(claim: new Claim(type: "auth_token", value: 
           notification.ProtocolMessage.AccessToken));
        return Task.CompletedTask;
    }
}