我最近发布了一个问题已经得到解答但导致了这个新问题。如果有兴趣,可以在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中处理的状态)传递给重定向到的控制器?