C# MVC5应用程序中来自Azure ADB2C的AccessToken
我们正在开发一个MVC5 web应用程序,它使用OpenIdConnect对Azure AD B2C进行身份验证。当用户通过身份验证后,我们希望能够从Azure AD B2C获取AccessToken,以便将其用于我们的API 这是我们的Startup.cs等效代码: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));
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;
}
}