OWIN OpenIdConnect 中间件 - 动态设置 RedirectUri
OWIN OpenIdConnect middleware - set RedirectUri dynamically
有什么方法可以根据请求范围而不是应用程序范围为 OpenIdConnectMessage 设置 RedirectUri 属性?
我的应用服务于多个域(myapp.com、myapp.fr、..),它会根据域确定内容的默认语言。我需要在通过 IdP 登录后将用户带回同一域,因此我需要找到一种方法,如何根据请求范围设置 RedirectUri,而不是通过在 startup.cs 中配置中间件选项完成的应用程序范围。
这可以通过 Notification
事件 RedirectToIdentityProvider
完成。像这样:
Notifications = new OpenIdConnectAuthenticationNotifications
{
RedirectToIdentityProvider = async n =>
{
n.ProtocolMessage.RedirectUri = n.OwinContext.Request.Uri.Host;
n.ProtocolMessage.PostLogoutRedirectUri = n.OwinContext.Request.Uri.Host;
},
//other notification events...
}
`
如果您使用 ResponseType = OpenIdConnectResponseType.CodeIdToken
,则需要在多个通知事件中设置 RedirectUri
。
在 AuthorizationCodeReceived
通知中,您可以在 TokenEndpointRequest
上设置 RedirectUri
以确保在令牌请求中也传递相同的值。
RedirectToIdentityProvider = n =>
{
n.ProtocolMessage.RedirectUri = redirectUrl;
// other settings
}
AuthorizationCodeReceived = n =>
{
n.TokenEndpointRequest.RedirectUri = redirectUrl;
// other settings
}
我知道这是一篇旧文章post,答案已经提到了。但是我还是花了一段时间才弄清楚如何设置动态 RedirectUri。
我在 OpenIdConnectAuthenticationOptions 和 RedirectToIdentityProvider 中分配 RedirectUri,这导致了问题。
我们应该只在 RedirectToIdentityProvider 事件中分配 RedirectUri。
需要帮助的可以查看我的代码here
当您将站点发布到 Microsoft Azure 时,多个域指向同一站点并打开:身份验证-> 允许未经身份验证的访问(您的站点有 public和私人页面); Microsoft Azure 随机回调您的重定向 URI 之一。要控制这种随机行为,您需要根据 Owin 上下文请求显式设置 RedirectUri 属性。
不要问我为什么,你还需要更改 URI 地址删除 “.auth/login/aad/callback” 除了 localhost。 (如果有人知道这个原因请告诉我)
这个代码对我有用:
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
PostLogoutRedirectUri = postLogoutRedirectUri,
Notifications = new OpenIdConnectAuthenticationNotifications()
{
AuthenticationFailed = (context) =>
{
return System.Threading.Tasks.Task.FromResult(0);
},
RedirectToIdentityProvider = (context) =>
{
string strPostLogoutRedirectUri;
string strRedirectUri = EnsureTrailingSlash(context.OwinContext.Request.Uri.ToString());
int nPos = strRedirectUri.IndexOf("://");
if (nPos > 0)
{
nPos += 3;
strPostLogoutRedirectUri = "https://" + strRedirectUri.Substring(nPos, strRedirectUri.IndexOf("/", nPos) - nPos + 1);
strRedirectUri = strPostLogoutRedirectUri;
if (strRedirectUri.Contains("localhost"))
{
strRedirectUri = strPostLogoutRedirectUri + ".auth/login/aad/callback";
}
}
else
{
strRedirectUri = "https://YOURSITE.com/";
strPostLogoutRedirectUri = "https://YOURSITE.com/";
}
context.ProtocolMessage.RedirectUri = strRedirectUri;
context.ProtocolMessage.PostLogoutRedirectUri = strPostLogoutRedirectUri;
return System.Threading.Tasks.Task.FromResult(0);
}
}
}
);
// This makes any middleware defined above this line run before the Authorization rule is applied in web.config
app.UseStageMarker(PipelineStage.Authenticate);
}
private static string EnsureTrailingSlash(string value)
{
if (value == null)
{
value = string.Empty;
}
if (!value.EndsWith("/", StringComparison.Ordinal))
{
return value + "/";
}
return value;
}
有什么方法可以根据请求范围而不是应用程序范围为 OpenIdConnectMessage 设置 RedirectUri 属性?
我的应用服务于多个域(myapp.com、myapp.fr、..),它会根据域确定内容的默认语言。我需要在通过 IdP 登录后将用户带回同一域,因此我需要找到一种方法,如何根据请求范围设置 RedirectUri,而不是通过在 startup.cs 中配置中间件选项完成的应用程序范围。
这可以通过 Notification
事件 RedirectToIdentityProvider
完成。像这样:
Notifications = new OpenIdConnectAuthenticationNotifications
{
RedirectToIdentityProvider = async n =>
{
n.ProtocolMessage.RedirectUri = n.OwinContext.Request.Uri.Host;
n.ProtocolMessage.PostLogoutRedirectUri = n.OwinContext.Request.Uri.Host;
},
//other notification events...
}
`
如果您使用 ResponseType = OpenIdConnectResponseType.CodeIdToken
,则需要在多个通知事件中设置 RedirectUri
。
在 AuthorizationCodeReceived
通知中,您可以在 TokenEndpointRequest
上设置 RedirectUri
以确保在令牌请求中也传递相同的值。
RedirectToIdentityProvider = n =>
{
n.ProtocolMessage.RedirectUri = redirectUrl;
// other settings
}
AuthorizationCodeReceived = n =>
{
n.TokenEndpointRequest.RedirectUri = redirectUrl;
// other settings
}
我知道这是一篇旧文章post,答案已经提到了。但是我还是花了一段时间才弄清楚如何设置动态 RedirectUri。
我在 OpenIdConnectAuthenticationOptions 和 RedirectToIdentityProvider 中分配 RedirectUri,这导致了问题。
我们应该只在 RedirectToIdentityProvider 事件中分配 RedirectUri。
需要帮助的可以查看我的代码here
当您将站点发布到 Microsoft Azure 时,多个域指向同一站点并打开:身份验证-> 允许未经身份验证的访问(您的站点有 public和私人页面); Microsoft Azure 随机回调您的重定向 URI 之一。要控制这种随机行为,您需要根据 Owin 上下文请求显式设置 RedirectUri 属性。
不要问我为什么,你还需要更改 URI 地址删除 “.auth/login/aad/callback” 除了 localhost。 (如果有人知道这个原因请告诉我)
这个代码对我有用:
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
PostLogoutRedirectUri = postLogoutRedirectUri,
Notifications = new OpenIdConnectAuthenticationNotifications()
{
AuthenticationFailed = (context) =>
{
return System.Threading.Tasks.Task.FromResult(0);
},
RedirectToIdentityProvider = (context) =>
{
string strPostLogoutRedirectUri;
string strRedirectUri = EnsureTrailingSlash(context.OwinContext.Request.Uri.ToString());
int nPos = strRedirectUri.IndexOf("://");
if (nPos > 0)
{
nPos += 3;
strPostLogoutRedirectUri = "https://" + strRedirectUri.Substring(nPos, strRedirectUri.IndexOf("/", nPos) - nPos + 1);
strRedirectUri = strPostLogoutRedirectUri;
if (strRedirectUri.Contains("localhost"))
{
strRedirectUri = strPostLogoutRedirectUri + ".auth/login/aad/callback";
}
}
else
{
strRedirectUri = "https://YOURSITE.com/";
strPostLogoutRedirectUri = "https://YOURSITE.com/";
}
context.ProtocolMessage.RedirectUri = strRedirectUri;
context.ProtocolMessage.PostLogoutRedirectUri = strPostLogoutRedirectUri;
return System.Threading.Tasks.Task.FromResult(0);
}
}
}
);
// This makes any middleware defined above this line run before the Authorization rule is applied in web.config
app.UseStageMarker(PipelineStage.Authenticate);
}
private static string EnsureTrailingSlash(string value)
{
if (value == null)
{
value = string.Empty;
}
if (!value.EndsWith("/", StringComparison.Ordinal))
{
return value + "/";
}
return value;
}