【问题标题】:getting user info if WebAPI is authenticated based on Client Credentials如果基于客户端凭据对 WebAPI 进行身份验证,则获取用户信息
【发布时间】:2017-02-19 02:23:21
【问题描述】:

在通过 Web 应用程序和 API 拥有 Azure AD 之前 -

用户在应用程序表单上输入 id 和密码 -> 用户登录(Asp.net 身份) -> 使用相同的凭据,在 WebAPI 处生成令牌(grant_type=password)-> 将此令牌存储为 cookie 以供以后使用开。

现在使用 Azure AD -

我有一个场景,我必须使用 Azure AD 对用户进行身份验证。 Azure 上的 webapi 传递包含登录用户信息的 JWT。从这些信息中,我提取用户电子邮件并强制我的 Web 应用程序登录用户(Asp.net 身份)。

Web App 调用 WebAPI 来获取令牌,因为我无法传递密码,所以我的令牌调用更改为 (grant_type=client_credentials)。但是,我丢失了登录到 Web API 的个人用户的信息。如果我检查 context.user 它指向唯一的客户端 ID,而不是任何用户。

我知道这很麻烦,但要求是使用相同的应用程序进行 Azure AD 身份验证以及本地表单身份验证。请建议是否有更简单的方法来实现这一点。

编辑:我正在使用 Owin oAuth

我对表单身份验证和 Azure AD 使用相同的应用程序。但是最近不得不在 web api 级别添加日志机制,该机制适用于使用用户 ID/密码进行日志记录的本地应用程序。但是,如果 webapi 使用客户端凭据发出令牌,它就不起作用。我尝试在验证客户端 ID(在 ValidateClientAuthentication 中)并登录用户时将用户名作为参数传递。但是 webapi 无法保留此用户信息。

【问题讨论】:

  • 如果我知道您使用的协议和技术会有所帮助。 OpenIdConnect,OAuth? Katana / Asp.net core 1.0 / 等等?

标签: asp.net asp.net-mvc azure asp.net-web-api azure-active-directory


【解决方案1】:

客户端凭据流用于守护程序应用程序或服务,以委托应用程序操作资源。在这种情况下,没有用户上下文信息。

据我了解,当我们使用 Azure AD 作为身份提供者时,我们使用 OpenId 连接协议从 Azure AD 获取 id_token。 OpenId 连接也支持hybrid 流在同一请求中获取授权码id_token

如果您使用带有 OWIN 组件的 MVC 进行开发,则默认情况下是此流程。我们只需要获取 Azure AD 返回的授权码(OAuth 2.0 代码授权流程)的访问令牌即可调用 Web API,这不需要用户再次登录。为了获取带有授权码的令牌,我们可以添加如下代码的通知:

public void ConfigureAuth(IAppBuilder app)
{
        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

        app.UseCookieAuthentication(new CookieAuthenticationOptions());

        app.UseOpenIdConnectAuthentication(
            new OpenIdConnectAuthenticationOptions
            {
                ClientId = clientId,
                Authority = Authority,
                PostLogoutRedirectUri = redirectUri,
                RedirectUri = redirectUri,
                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    //
                    // If there is a code in the OpenID Connect response, redeem it for an access token and refresh token, and store those away.
                    //
                    AuthorizationCodeReceived = OnAuthorizationCodeReceived,
                    AuthenticationFailed = OnAuthenticationFailed
                }

            });
}

private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedNotification context)
{
        var code = context.Code;

        ClientCredential credential = new ClientCredential(clientId, appKey);
        string userObjectID = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
        AuthenticationContext authContext = new AuthenticationContext(Authority, new NaiveSessionCache(userObjectID));

        // If you create the redirectUri this way, it will contain a trailing slash.  
        // Make sure you've registered the same exact Uri in the Azure Portal (including the slash).
        Uri uri = new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path));

        AuthenticationResult result = await authContext.AcquireTokenByAuthorizationCodeAsync(code, uri, credential, graphResourceId);
}

从 Web 应用调用 Web API 的完整代码示例,您可以参考 here

【讨论】:

    【解决方案2】:

    这是我为解决我的问题所做的 - 我没有为客户端分配 claimIdentity,而是生成了用户身份。 (_username 是局部变量,它从参数中获取“ValidateClientAuthentication”中的赋值。我知道这可能不是理想的方式,但现在我的应用程序现在可以在表单身份验证以及使用 JWT 令牌的 Azure AD 上运行)

     public override async Task GrantClientCredentials(OAuthGrantClientCredentialsContext context)
            {
                var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
    
                ApplicationUser user = await userManager.FindByNameAsync(_userName);
    
                ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, CookieAuthenticationDefaults.AuthenticationType);
    
                var ticket = new AuthenticationTicket(oAuthIdentity, null);
    
                context.Validated(ticket);
            }
    

    【讨论】:

      猜你喜欢
      • 2017-03-12
      • 1970-01-01
      • 2023-04-10
      • 1970-01-01
      • 2017-04-25
      • 1970-01-01
      • 2014-04-01
      • 1970-01-01
      • 2011-10-18
      相关资源
      最近更新 更多