Asp.net mvc 混合MSAL和MVC表单身份验证
我正在开发一个拥有多个用户的单租户MVC web应用程序。此应用程序有多个针对不同客户的部署,有些客户希望通过Outlook 365发送邮件。该应用程序使用表单对存储在数据库中的用户进行身份验证 我试图在以下示例的基础上实现一些功能,但是它与表单身份验证冲突,因为即使登录成功,我也会返回表单登录页面 成功登录后,通过将用户定向到Azure AD登录,我可以成功检索访问令牌:Asp.net mvc 混合MSAL和MVC表单身份验证,asp.net-mvc,oauth-2.0,forms-authentication,azure-ad-graph-api,msal,Asp.net Mvc,Oauth 2.0,Forms Authentication,Azure Ad Graph Api,Msal,我正在开发一个拥有多个用户的单租户MVC web应用程序。此应用程序有多个针对不同客户的部署,有些客户希望通过Outlook 365发送邮件。该应用程序使用表单对存储在数据库中的用户进行身份验证 我试图在以下示例的基础上实现一些功能,但是它与表单身份验证冲突,因为即使登录成功,我也会返回表单登录页面 成功登录后,通过将用户定向到Azure AD登录,我可以成功检索访问令牌: var url = "https://login.microsoftonline.com/common/oauth2/v2
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;
}
公共静态异步任务GetAccessToken(字符串代码)
{
var app=机密客户端应用程序生成器
.Create(AuthenticationConfig.ClientId)
.WithClientSecret(AuthenticationConfig.ClientSecret)
.WithRedirectUri(AuthenticationConfig.RedirectUri)
.WithAuthority(AuthenticationConfig.Authority)
.Build();
var scopes=新列表{“脱机访问”、“用户读取”、“邮件读取”、“邮件发送”};
var authenticationResult=wait app.AcquireTokenByAuthorizationCode(作用域,代码).ExecuteAsync();
返回authenticationResult.AccessToken;
}
但是,身份验证结果中不返回刷新令牌。我希望获得访问令牌/到期日和刷新令牌/到期日并存储它们,以便用户通过Azure AD进行一次身份验证,然后我可以在将来使用刷新令牌以静默方式续订访问令牌
我读了很多书,但我能找到的大部分信息都是基于在你的应用程序中使用Azure广告登录的。我需要保留表单登录和身份验证,仅用于发送电子邮件。这可能吗
更新以尝试针对用户缓存令牌并将其读回:
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);
}
AuthorizationCodeReceived上的公共静态异步任务(字符串代码)
{
var app=机密客户端应用程序生成器
.Create(AuthenticationConfig.ClientId)
.WithClientSecret(AuthenticationConfig.ClientSecret)
.WithRedirectUri(AuthenticationConfig.RedirectUri)
.WithAuthority(AuthenticationConfig.Authority)
.Build();
var scopes=新列表{“脱机访问”、“用户读取”、“邮件读取”、“邮件发送”};
var authenticationResult=wait app.AcquireTokenByAuthorizationCode(作用域,代码).ExecuteAsync();
var account=authenticationResult.account;
var identity=new ClaimsIdentity();
identity.AddClaim(新系统.Security.Claims.Claims(ClaimConstants.ObjectId,account.HomeAccountId.ObjectId));
identity.AddClaim(新系统.Security.Claims.Claims(ClaimConstants.TenantId,account.HomeAccountId.TenantId));
identity.AddClaim(新的System.Security.Claims.Claims(System.Security.Claims.Claims.ClaimTypes.Upn,account.Username));
var claimsPrincipal=新的claimsPrincipal(标识);
//根据示例存储缓存
var userTokenCache=new MSALPerUserMemoryTokenCache(app.userTokenCache,claimsPrincipal);
//没有账户被退回
var accounts=wait app.GetAccountsAsync();
var newres=await app.AcquireTokenSilent(作用域、帐户.FirstOrDefault()).ExecuteAsync().ConfigureAwait(false);
}
没有返回任何帐户,查看缓存令牌的唯一方法是保留默认值,这样它们就不会针对用户进行存储。不幸的是,MSAL.NET(以及一般的MSALs)不会公开刷新令牌
您可以看到AuthenticationResult中没有“refreshToken”
您可以通过调用AcquireTokenSilent来自动处理刷新令牌。当我运行带有Azure AD的应用程序进行身份验证时,使用AcquireTokenSilent是有效的,但在我的表单身份验证应用程序中缓存时遇到问题。请参阅上面更新的代码。