C# StateDataFormat.Unprotect()中的加密异常
我最近发布了一个问题,这个问题已经得到了回答,但导致了这个新问题。如果感兴趣,可在以下网址查看 介绍 我目前正在开发一个应用程序,使用AD-B2C作为我的身份提供商。在使用openid connect的AD B2C graph上,这是使用他们的指南集成到解决方案中的 我需要使用一种形式的电子邮件激活(在他们的注册策略之外),因此我需要能够从电子邮件中的URL传递一个值,通过B2C的注册过程,然后返回重定向URL 为此,我们使用状态参数 问题 在OnRedirectToIdentityProvider中,我加密状态C# StateDataFormat.Unprotect()中的加密异常,c#,asp.net,cryptography,openid-connect,azure-ad-b2c,C#,Asp.net,Cryptography,Openid Connect,Azure Ad B2c,我最近发布了一个问题,这个问题已经得到了回答,但导致了这个新问题。如果感兴趣,可在以下网址查看 介绍 我目前正在开发一个应用程序,使用AD-B2C作为我的身份提供商。在使用openid connect的AD B2C graph上,这是使用他们的指南集成到解决方案中的 我需要使用一种形式的电子邮件激活(在他们的注册策略之外),因此我需要能够从电子邮件中的URL传递一个值,通过B2C的注册过程,然后返回重定向URL 为此,我们使用状态参数 问题 在OnRedirectToIdentityProvid
private Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
{
var temp = notification.ProtocolMessage.State;
// To be used later
var mycustomparameter = notification.OwinContext.Get<string>("mycustomparameter");
if (notification.ProtocolMessage.State != null)
{
var stateQueryString = notification.ProtocolMessage.State.Split('=');
var protectedState = stateQueryString[1];
var state = notification.Options.StateDataFormat.Unprotect(protectedState);
state.Dictionary.Add("mycustomparameter", "testing");
notification.ProtocolMessage.State = stateQueryString[0] + "=" + notification.Options.StateDataFormat.Protect(state);
}
return Task.FromResult(0);
}
私有任务OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification)
{
var temp=notification.ProtocolMessage.State;
//待用
var mycustomparameter=notification.OwinContext.Get(“mycustomparameter”);
if(notification.ProtocolMessage.State!=null)
{
var stateQueryString=notification.ProtocolMessage.State.Split('=');
var protectedState=stateQueryString[1];
var state=notification.Options.StateDataFormat.Unprotect(protectedState);
state.Dictionary.Add(“mycustomparameter”、“testing”);
notification.ProtocolMessage.State=stateQueryString[0]+“=”+notification.Options.StateDataFormat.Protect(状态);
}
返回Task.FromResult(0);
}
据我所知,这是可行的
现在,用户被传递到广告B2C上的登录,并在登录后重定向回触发OnMessageReceived的位置
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);
}
MessageReceived上的私有任务(MessageReceivedNotification通知)
{
字符串mycustomparameter;
var protectedState=notification.ProtocolMessage.State.Split('=')[1];
var state=notification.Options.StateDataFormat.Unprotect(protectedState);
state.Dictionary.TryGetValue(“mycustomparameter”,out mycustomparameter);
返回Task.FromResult(0);
}
这就是它断裂的地方。在…StateDataFormat.Unprotect(protectedState)中
它抛出一个错误System.Security.Cryptography.CryptographyException,消息为“加密操作期间出错”
编辑:堆栈跟踪:
System.Web.dll!System.Web.Security.Cryptography.同质化CryptoServiceWrapper.同质化错误(System.Func Func,byte[]输入)未知
System.Web.dll!System.Web.Security.Cryptography.UniformingCryptoServiceWrapper.Unprotect(字节[]protectedData)未知
System.Web.dll!System.Web.Security.MachineKey.Unprotect(System.Web.Security.cryptoServiceProvider cryptoServiceProvider cryptoServiceProvider,字节[]protectedData,字符串[]用途)未知
System.Web.dll!System.Web.Security.MachineKey.Unprotect(字节[]protectedData,字符串[]用途)未知
Microsoft.Owin.Host.SystemWeb.dll!Microsoft.Owin.Host.SystemWeb.DataProtection.MachineKeyDataProtector.Unprotect(字节[]protectedData)未知
Microsoft.Owin.Security.dll!Microsoft.Owin.Security.DataProtection.AppBuilderExtensions.CallDataProtectionProvider.CallDataProtection.Unprotect(字节[]protectedData)未知
Microsoft.Owin.Security.dll!Microsoft.Owin.Security.DataHandler.SecureDataFormat.Unprotect(字符串protectedText)未知
IntellifyPortal.dll!IntellifyPortal.Startup.OnMessageReceived(Microsoft.Owin.Security.Notifications.MessageReceivedNotification)第171 C行#
我的尝试
我已尝试在Web.config中指定机器密钥
我尝试过在OpenIdConnectAuthenticationOptions中处理“CallbackPath属性,但没有成功
我尝试了很多不同的调整,但我似乎不明白为什么我不能“取消”入站状态的保护
感谢您的帮助
致以最良好的祝愿
更新:解决方案
我已经决定使用另一种方法,我发现它很有效(希望它对其他人有用):
私有任务OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification)
{
var policy=notification.OwinContext.Get(“策略”);
如果(!string.IsNullOrEmpty(策略)和&!policy.Equals(DefaultPolicy))
{
notification.ProtocolMessage.Scope=OpenIdConnectScopes.OpenId;
notification.ProtocolMessage.ResponseType=OpenIDConnectResponseType.IdToken;
notification.ProtocolMessage.IssuerAddress=notification.ProtocolMessage.IssuerAddress.ToLower().Replace(DefaultPolicy.ToLower(),policy.ToLower());
}
//接受邀请电子邮件
字符串testValue=notification.OwinContext.Get(“testValue”);
字符串testValue2=notification.OwinContext.Get(“testValue2”);
如果(!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(状态);
}
返回Task.FromResult(0);
}
AuthorizationCodeReceived上的专用异步任务(AuthorizationCodeReceivedNotification通知)
{
//从响应通知中提取代码
var代码=notification.code;
string SignedUserId=notification.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
TokenCache userTokenCache=新MSALSessionCache(SignedUserId,notification.owIncote)
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
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;
}
}