Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 混合MSAL和MVC表单身份验证_Asp.net Mvc_Oauth 2.0_Forms Authentication_Azure Ad Graph Api_Msal - Fatal编程技术网

Asp.net mvc 混合MSAL和MVC表单身份验证

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

我正在开发一个拥有多个用户的单租户MVC web应用程序。此应用程序有多个针对不同客户的部署,有些客户希望通过Outlook 365发送邮件。该应用程序使用表单对存储在数据库中的用户进行身份验证

我试图在以下示例的基础上实现一些功能,但是它与表单身份验证冲突,因为即使登录成功,我也会返回表单登录页面

成功登录后,通过将用户定向到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;
    }
公共静态异步任务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是有效的,但在我的表单身份验证应用程序中缓存时遇到问题。请参阅上面更新的代码。