首页 > 解决方案 > 如何在多个网站 OpenIdConnect Azure AD B2C 中登录用户?

问题描述

我想OpenIdConnectAuthentication用于多个项目。我正在使用以下代码对我的用户进行身份验证,website1这工作正常,但是如何在website2同一个访问令牌中访问和管理它以对另一个网站中的用户进行身份验证?

public void ConfigureAuth(IAppBuilder app) {
// Required for Azure webapps, as by default they force TLS 1.2 and this project attempts 1.0
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions {
    // Generate the metadata address using the tenant and policy information
    MetadataAddress = String.Format(Globals.WellKnownMetadata, Globals.Tenant, Globals.DefaultPolicy),

    // These are standard OpenID Connect parameters, with values pulled from web.config
    ClientId = Globals.ClientId,
    RedirectUri = Globals.RedirectUri,
    PostLogoutRedirectUri = Globals.RedirectUri,
    AuthenticationType = Globals.DefaultPolicy,
    // Specify the callbacks for each type of notifications
    Notifications = new OpenIdConnectAuthenticationNotifications {
        RedirectToIdentityProvider = OnRedirectToIdentityProvider,
        AuthorizationCodeReceived = OnAuthorizationCodeReceived,
        AuthenticationFailed = OnAuthenticationFailed,
    },
    Scope = "openid",
    ResponseType = "id_token",
    // Specify the claim type that specifies the Name property.
    TokenValidationParameters = new TokenValidationParameters {
        NameClaimType = "name",
        SaveSigninToken = true,
        ValidateIssuer = false
    }//,

    // Specify the scope by appending all of the scopes requested into one string (separated by a blank space)
    //Scope = $"openid profile offline_access {Globals.ReadTasksScope} {Globals.WriteT//asksScope}"
});

注意:网站 1 是 MVC 项目,网站 2 是用于验证 api 调用的 API 项目。我们该如何管理呢?

标签: asp.net-mvcopenid-connectazure-ad-b2c

解决方案


我可以看到您需要更改一些内容才能使其正常工作。首先,由于这是您正在使用的服务器应用程序,您可以使用authorization code flowhybrid flow来验证用户身份。

可以这样实现:

// for authorization code flow
ResponseType = "code",

// for hybrid flow
ResponseType = "code id_token"

请注意,在使用这两个流程时,您还需要提供客户端密码。

一旦用户在身份提供者上通过身份验证,它将使用授权代码重定向回您的应用程序,您可以使用该授权代码将其交换为 access_token 和 refresh_token。

所以,在OnRedirectToIdentityProvider方法中

OnAuthorizationCodeReceived = async n =>
{
    // swap authorization code for an access token
    // i think for AAD B2C the endpoint for retreiving tokens is (not sure though you'll need to double check) 
    // https://<tenant-name>.b2clogin.com/<tenant-name>.onmicrosoft.com/<policy-name>/oauth2/v2.0/token
    var tokenClient = new TokenClient("http://localhost:5000/connect/token", Globals.ClientId, Globals.ClientSecret);
    var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(
                    n.Code, n.RedirectUri);

    // use access token to call the user info endpoint
    // also check what the userinfo endpoint URL is
    var userInfoClient = new UserInfoClient("http://localhost:5000/connect/userinfo");
    var userInfoResponse = await userInfoClient.GetAsync(tokenResponse.AccessToken);

    // create a new identity using the claims from the user info endpoint (including tokens)
    var id = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType);
    id.AddClaims(userInfoResponse.Claims);
    id.AddClaim(new Claim("access_token", tokenResponse.AccessToken));
    id.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));

    n.AuthenticationTicket = new AuthenticationTicket(
                    new ClaimsIdentity(id.Claims, n.AuthenticationTicket.Identity.AuthenticationType),
                    n.AuthenticationTicket.Properties);
}

您可以从元数据端点获取所需的所有 URL。

完成所有这些操作后,访问令牌将成为用户声明的一部分,并将存储在身份验证 cookie 中。

然后,一旦你完成了所有这些,你就可以使用 access_token 来调用你JwtBearerAuthentication设置的 API 上提供的受保护 API,方法是在对所述 API 的请求的标头中提供 access_token。

该类TokenClient是名为 IdentityModel 的库的一部分,它可以更轻松地与 openidconnect 端点进行通信


推荐阅读