问题
I have an app that is authenticating with Azure Active Directory using OpenIdConnect. Everything is working fine except when I link to my site from a Office Application (excel/ word). From these applications I get a "Exception: Correlation failed.".
From my research it seems to be that office is first doing the 302 redirect and then opening that page not the original link.
See: https://github.com/aspnet/Security/issues/1252
After a recommendation for how to handle this scenario. I don't want to have to make to many changes to the authentication flow and introduce bugs.
I have tried redirecting to a different page on my site when a user-agent of excel is detected. I thought then the correct cookie would be set and I could redirect from there to the requested page which would then trigger authorization. No luck though
OnRedirectToIdentityProvider = context =>
{
if (context.Request.Headers["User-Agent"].ToString().Contains("Microsoft Office Excel"))
{
string redirect = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase + "/Home/Office" + "?url=" + context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase + context.Request.Path;
context.Response.Clear();
context.Response.Redirect(redirect);
context.HandleResponse();
return Task.CompletedTask;
}
}
回答1:
I was able to implement a decent solution using owin middleware. Largely with the help of this post: https://github.com/aspnet/AspNetKatana/issues/78
I how ever did need to convert it to .net core 2.0. Here's the converted code:
public class MsOfficeLinkPrefetchMiddleware
{
RequestDelegate _next;
public MsOfficeLinkPrefetchMiddleware(RequestDelegate next)
{
_next = next;
}
public Task Invoke(HttpContext context)
{
if (Is(context, HttpMethod.Get, HttpMethod.Head) && IsMsOffice(context))
{
// Mitigate by preempting auth challenges to MS Office apps' preflight requests and
// let the real browser start at the original URL and handle all redirects and cookies.
// Success response indicates to Office that the link is OK.
context.Response.StatusCode = (int)HttpStatusCode.OK;
context.Response.Headers["Cache-Control"] = "no-cache, no-store, must-revalidate";
context.Response.Headers["Pragma"] = "no-cache";
context.Response.Headers["Expires"] = "0";
}
else if (_next != null)
{
return _next.Invoke(context);
}
return Task.CompletedTask;
}
private static bool Is(HttpContext context, params HttpMethod[] methods)
{
var requestMethod = context.Request.Method;
return methods.Any(method => StringComparer.OrdinalIgnoreCase.Equals(requestMethod, method.Method));
}
private static readonly Regex _msOfficeUserAgent = new Regex(
@"(^Microsoft Office\b)|([\(;]\s*ms-office\s*[;\)])",
RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled);
private static bool IsMsOffice(HttpContext context)
{
var headers = context.Request.Headers;
var userAgent = headers["User-Agent"];
return _msOfficeUserAgent.IsMatch(userAgent)
|| !string.IsNullOrWhiteSpace(headers["X-Office-Major-Version"]);
}
}
Startup
app.UseMiddleware<MsOfficeLinkPrefetchMiddleware>();
Hope this is able to help someone in the future.
回答2:
In Startup.ConfigureServices(), you'll need to add this line
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for
//non -essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
来源:https://stackoverflow.com/questions/52473531/openidconnect-correlation-cookie-not-found-when-user-click-link-from-office-appl