StateDataFormat.Unprotect()中的CryptographicException

时间:2017-06-07 11:44:08

标签: c# asp.net cryptography openid-connect azure-ad-b2c

我最近发布了一个问题已经得到解答但导致了这个新问题。如果有兴趣,可以在Previous post看到。

简介

我目前正在开发一个使用AD-B2C作为我的身份提供者的应用程序。它使用AD B2C图表中的指南集成到解决方案中,该图表使用openid-connect。

我需要使用一种电子邮件激活形式(在他们的注册政策之外),因此我需要能够通过电子邮件中的URL传递值,通过B2C的注册过程并返回到重定向网址。

为此,我们使用state参数。

问题

在我的 OnRedirectToIdentityProvider 中我加密状态

 private Task OnMessageReceived(MessageReceivedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
    {
        string mycustomparameter;
        var protectedState = notification.ProtocolMessage.State.Split('=')[1];

        var state = notification.Options.StateDataFormat.Unprotect(protectedState);
        state.Dictionary.TryGetValue("mycustomparameter", out mycustomparameter);
        return Task.FromResult(0);
    }

这适用于我能说的一切。

现在,用户已转到 AD B2C 上的登录状态,并在重定向后重新定向到 OnMessageReceived 被触发的位置。

System.Web.dll!System.Web.Security.Cryptography.HomogenizingCryptoServiceWrapper.HomogenizeErrors(System.Func<byte[], byte[]> func, byte[] input)   Unknown
System.Web.dll!System.Web.Security.Cryptography.HomogenizingCryptoServiceWrapper.Unprotect(byte[] protectedData)    Unknown
System.Web.dll!System.Web.Security.MachineKey.Unprotect(System.Web.Security.Cryptography.ICryptoServiceProvider cryptoServiceProvider, byte[] protectedData, string[] purposes) Unknown
System.Web.dll!System.Web.Security.MachineKey.Unprotect(byte[] protectedData, string[] purposes)    Unknown
Microsoft.Owin.Host.SystemWeb.dll!Microsoft.Owin.Host.SystemWeb.DataProtection.MachineKeyDataProtector.Unprotect(byte[] protectedData)  Unknown
Microsoft.Owin.Security.dll!Microsoft.Owin.Security.DataProtection.AppBuilderExtensions.CallDataProtectionProvider.CallDataProtection.Unprotect(byte[] protectedData)   Unknown
Microsoft.Owin.Security.dll!Microsoft.Owin.Security.DataHandler.SecureDataFormat<Microsoft.Owin.Security.AuthenticationProperties>.Unprotect(string protectedText)  Unknown

这是它破裂的地方。在 ... StateDataFormat.Unprotect(protectedState)

它引发错误 System.Security.Cryptography.CryptographicException ,并显示消息&#34;加密操作期间发生错误。&#34;

编辑:Stacktrace:

private Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
    {
        var policy = notification.OwinContext.Get<string>("Policy");

        if (!string.IsNullOrEmpty(policy) && !policy.Equals(DefaultPolicy))
        {
            notification.ProtocolMessage.Scope = OpenIdConnectScopes.OpenId;
            notification.ProtocolMessage.ResponseType = OpenIdConnectResponseTypes.IdToken;
            notification.ProtocolMessage.IssuerAddress = notification.ProtocolMessage.IssuerAddress.ToLower().Replace(DefaultPolicy.ToLower(), policy.ToLower());
        }

        // Accept Invitation Email
        string testValue= notification.OwinContext.Get<string>("testValue");
        string testValue2= notification.OwinContext.Get<string>("testValue2");

        if (!string.IsNullOrEmpty(testValue) && !string.IsNullOrEmpty(testValue2))
        {
            var stateQueryString = notification.ProtocolMessage.State.Split('=');
            var protectedState = stateQueryString[1];
            var state = notification.Options.StateDataFormat.Unprotect(protectedState);
            state.Dictionary.Add("testValue", testValue);
            state.Dictionary.Add("testValue2", testValue2);
            notification.ProtocolMessage.State = stateQueryString[0] + "=" + notification.Options.StateDataFormat.Protect(state);
        }
        return Task.FromResult(0);
    }

private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedNotification notification)
    {
        // Extract the code from the response notification
        var code = notification.Code;

        string signedInUserID = notification.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
        TokenCache userTokenCache = new MSALSessionCache(signedInUserID, notification.OwinContext.Environment["System.Web.HttpContextBase"] as HttpContextBase).GetMsalCacheInstance();
        ConfidentialClientApplication cca = new ConfidentialClientApplication(ClientId, Authority, RedirectUri, new ClientCredential(ClientSecret), userTokenCache, null);
        try
        {
            AuthenticationResult result = await cca.AcquireTokenByAuthorizationCodeAsync(code, Scopes);

            // Look for acceptInvitation
            string testValue;
            string testValue2;

            var protectedState = notification.ProtocolMessage.State.Split('=')[1];
            var state = notification.Options.StateDataFormat.Unprotect(protectedState);
            state.Dictionary.TryGetValue("testValue", out testValue);
            state.Dictionary.TryGetValue("testValue2", out testValue2);

            // InvitationAccept / store values
            if(!string.IsNullOrEmpty(testValue) && !string.IsNullOrEmpty(testValue2))
            {
                // How can I pass values to the redirect controller?
                // Can I somehow transfer it from here to that destination
            }
        }
        catch (Exception ex)
        {
            //TODO: Handle
            throw;
        }
    }
  

IntellifyPortal.dll!IntellifyPortal.Startup.OnMessageReceived(Microsoft.Owin.Security.Notifications.MessageReceivedNotification notification)第171行C#

我的尝试

我尝试在 Web.config

中指定机器密钥

我尝试使用 OpenIdConnectAuthenticationOptions 中的&#34; CallbackPath 属性,但没有成功。

我尝试了很多不同的调整,但我似乎无法弄清楚为什么我不能解除&#34;解除保护&#34;入境国。

感谢任何帮助,

致以最诚挚的问候。

更新:解决方案

我决定使用另一种方法,我发现它可以工作(希望它可能对其他人有用): Azure-sample which I used as guidance

node_modules

最终问题

我现在可以按预期收到值。这些值必须用于创建新帐户与应用程序中其他帐户/组之间的关系。

因此,我希望将这些值返回传输到应用程序(控制器)进行处理。我已经尝试将值存储在上下文,响应标头和声明中,但无济于事。我想这是因为这是&#34;中间件&#34;并且实际的&#34;重定向&#34;直接来自 AD B2C ,因此没有持有我的参数。

我是否可以以某种方式将params返回到控制器,而不依赖于请求URI(源自原始用户链接) - 最好直接在声明中,以便已经登录的用户不必&# 34;重新登入&#34;点击链接后。

如何将我的值(处于OnMessageRecieved中处理的状态)传递给重定向到的控制器?

0 个答案:

没有答案