Skip to content

Instantly share code, notes, and snippets.

Created July 20, 2019 22:46
Show Gist options
  • Save bachoang/942a8223a689ceba77987b9c3f54ab61 to your computer and use it in GitHub Desktop.
Save bachoang/942a8223a689ceba77987b9c3f54ab61 to your computer and use it in GitHub Desktop.
detect if the requests come from Office process
Workaround below to detect Office request comes from the user smichtch in
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Globalization;
using System.Linq;
using System.Web;
using Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Microsoft.Owin;
using System.Threading.Tasks;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Net;
public void ConfigureAuth(IAppBuilder app)
app.UseCookieAuthentication(new CookieAuthenticationOptions());
new OpenIdConnectAuthenticationOptions
ClientId = clientId,
Authority = authority,
PostLogoutRedirectUri = postLogoutRedirectUri,
// RedirectUri = ""
RedirectUri = ""
Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;
public class MsOfficeLinkPrefetchMiddleware : OwinMiddleware
public MsOfficeLinkPrefetchMiddleware(OwinMiddleware next) : base(next) { }
public override Task Invoke(IOwinContext 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(IOwinContext 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(IOwinContext context)
var headers = context.Request.Headers;
var userAgent = headers["User-Agent"] ?? string.Empty;
return _msOfficeUserAgent.IsMatch(userAgent)
|| !string.IsNullOrWhiteSpace(headers["X-Office-Major-Version"]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment