带有SSO的ASP.NET 6 WebAPI身份验证



我有一个ASP.NET 6.0 Web API项目。我想为它添加身份验证和授权,但它必须通过Azure使用SSO。

我们已经有一个SPA应用程序可以做到这一点,它使用Angular MSAL库将用户重定向到SSO登录页面,然后使用访问令牌返回SPA。然后将访问令牌添加到Web API的每个请求的头中,Web使用它来强制进行身份验证。

现在,我们想与组织内的其他团队共享我们的web API,我们希望登录过程只是另一个API调用,而不是一个网页。

从概念上讲,客户机将访问API的/login端点,传入用户ID和密码。然后,web API将从Azure获取访问令牌,然后将其作为登录请求的有效负载返回。然后由客户端将该令牌添加到后续的请求头中。

我已经使用常规的ASP.NET Identity实现了这一点,其中所有用户和角色数据都存储在SQL数据库中,但由于我们的组织通过Azure Active Directory使用SSO,我们宁愿使用它。

我在网上研究过这个话题,到目前为止,我看到的所有例子都使用了一个单独的SPA,就像我们已经使用过的一样。但由于这是一个web api,而不是前端,我们需要一个api方法来代替它。

这可能吗?我知道微软不希望用户凭据通过我们自己的网络服务器,不诚实的程序员可能会将它们存储在那里,以备日后滥用。我理解。但我不确定有没有办法解决这个问题。

谢谢。

我相信您正在寻找资源所有者密码(ROP(流。您可以使用IdentityModel.OidcClient来实现它。

样本代码:

public class Program
{
static async Task Main()
{
// call this in your /login endpoint and return the access token to the client
var response = await RequestTokenAsync("bob", "bob");

if (!response.IsError)
{
var accessToken = response.AccessToken;
Console.WriteLine(accessToken);
}
}
static async Task<TokenResponse> RequestTokenAsync(string userName, string password)
{
var client = new HttpClient();
var disco = await client.GetDiscoveryDocumentAsync(Constants.Authority);
if (disco.IsError) throw new Exception(disco.Error);
var response = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
{
Address = disco.TokenEndpoint,
ClientId = "roclient",
ClientSecret = "secret",
UserName = userName,
Password = password,
Scope = "resource1.scope1 resource2.scope1",
Parameters =
{
{ "acr_values", "tenant:custom_account_store1 foo bar quux" }
}
});
if (response.IsError) throw new Exception(response.Error);
return response;
}
}

示例取自IdentityServer4存储库,您可以在其中找到更多ROP流客户端示例。

我建议您不要使用此实现,而是让所有客户端直接从Azure AD获得访问令牌,就像您使用Angular SPA一样。

最新更新