asp.net-mvc - 混合 MSAL 和 MVC 表单身份验证
问题描述
我正在开发具有多个用户的单租户 MVC Web 应用程序。此应用程序针对不同的客户有多种部署,一些客户希望通过 Outlook 365 发送邮件。该应用程序对存储在数据库中的用户使用表单身份验证。
我已经尝试根据以下示例进行工作 - https://github.com/Azure-Samples/ms-identity-aspnet-webapp-openidconnect - 但是它与表单身份验证冲突,因为我被循环回即使登录成功,表单登录页面。
成功登录后,我可以通过将用户定向到 Azure AD 登录来成功检索访问令牌:
var url = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?" +
"client_id=" + AuthenticationConfig.ClientId +
"&response_type=code" +
"&redirect_uri=" + AuthenticationConfig.RedirectUri +
"&response_mode=query" +
"&scope=" + AuthenticationConfig.BasicSignInScopes +
"&state=12345";
然后在回调中使用以下内容获取访问令牌:
public static async Task<string> GetAccessToken(string code)
{
var app = ConfidentialClientApplicationBuilder
.Create(AuthenticationConfig.ClientId)
.WithClientSecret(AuthenticationConfig.ClientSecret)
.WithRedirectUri(AuthenticationConfig.RedirectUri)
.WithAuthority(AuthenticationConfig.Authority)
.Build();
var scopes = new List<string> { "offline_access", "user.read", "mail.read", "mail.send" };
var authenticationResult = await app.AcquireTokenByAuthorizationCode(scopes, code).ExecuteAsync();
return authenticationResult.AccessToken;
}
但是,身份验证结果中不会返回刷新令牌。我希望获取访问令牌/到期和刷新令牌/到期并存储它们,以便用户通过 Azure AD 进行一次身份验证,然后我可以在将来使用刷新令牌静默更新访问令牌。
我已经阅读了很多资料,但我能找到的大部分信息都是基于对您的应用使用 Azure AD 登录。我需要保留表单登录和身份验证,仅用于发送电子邮件。这可能吗?
更新以尝试针对用户缓存令牌并将其读回:
public static async Task OnAuthorisationCodeReceived(string code)
{
var app = ConfidentialClientApplicationBuilder
.Create(AuthenticationConfig.ClientId)
.WithClientSecret(AuthenticationConfig.ClientSecret)
.WithRedirectUri(AuthenticationConfig.RedirectUri)
.WithAuthority(AuthenticationConfig.Authority)
.Build();
var scopes = new List<string> { "offline_access", "user.read", "mail.read", "mail.send" };
var authenticationResult = await app.AcquireTokenByAuthorizationCode(scopes, code).ExecuteAsync();
var account = authenticationResult.Account;
var identity = new ClaimsIdentity();
identity.AddClaim(new System.Security.Claims.Claim(ClaimConstants.ObjectId, account.HomeAccountId.ObjectId));
identity.AddClaim(new System.Security.Claims.Claim(ClaimConstants.TenantId, account.HomeAccountId.TenantId));
identity.AddClaim(new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.Upn, account.Username));
var claimsPrincipal = new ClaimsPrincipal(identity);
// as per example store the cache
var userTokenCache = new MSALPerUserMemoryTokenCache(app.UserTokenCache, claimsPrincipal);
// no accounts returned
var accounts = await app.GetAccountsAsync();
var newres = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault()).ExecuteAsync().ConfigureAwait(false);
}
没有返回任何帐户,我可以看到缓存令牌的唯一方法是如果我保留默认值,那么它们不会针对用户存储。
解决方案
不幸的是,MSAL.NET(以及一般的 MSAL)不公开刷新令牌。
可以看到AuthenticationResult中没有“refreshToken”。
您可以通过调用 AcquireTokenSilent 自动处理刷新令牌。
推荐阅读
- python - 如何找出Dataframe中两列的组合?当数据框中有多个列时?
- mongodb - 是否可以在 MongoDb 中更新 $jsonSchema?
- eclipse-rcp - Eclipse RCP 产品导出:收集要安装的项目时出错
- reactjs - reactjs中如何将类组件更改为功能组件?
- django - 如果找不到图像,则使 Django 静默失败
- android - 在 React with Cordova 中点击通知点击重定向到页面或屏幕
- vue.js - Vue.js Vue3 子组件的不同模板
- ios - 带有 gem 本机扩展的 Cocoapods 错误失败
- ansi - 在DOSBOX中检测QB45中的ANSI
- c - 加载数据构造三叉树不能正常工作(C)