ASP.NET and OWIN Cookies Azure Open ID is not working
Asked Answered
G

1

3

I have try to use OpenID to connect with Azure AD, and I use the exact code from the tutorial https://learn.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-asp-webapp with no luck.

My Startup:

public class Startup
{
     string clientId = System.Configuration.ConfigurationManager.AppSettings["ClientId"];
     string redirectUri = System.Configuration.ConfigurationManager.AppSettings["RedirectUri"];
     static string tenant = System.Configuration.ConfigurationManager.AppSettings["Tenant"];
     string authority = String.Format(System.Globalization.CultureInfo.InvariantCulture, 
                        System.Configuration.ConfigurationManager.AppSettings["Authority"], tenant);

/// <summary>
/// Configure OWIN to use OpenIdConnect
/// </summary>
/// <param name="app"></param>
public void Configuration(IAppBuilder app)
{
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

    app.UseCookieAuthentication(new CookieAuthenticationOptions());
    app.UseOpenIdConnectAuthentication(
        new OpenIdConnectAuthenticationOptions
        {
            ClientId = clientId,
            Authority = authority,
            RedirectUri = redirectUri,
            PostLogoutRedirectUri = redirectUri,
            Scope = OpenIdConnectScope.OpenIdProfile,
            ResponseType = OpenIdConnectResponseType.IdToken,
            TokenValidationParameters = new TokenValidationParameters()
            {
                ValidateIssuer = true
            },
            
            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                AuthenticationFailed = OnAuthenticationFailed
            }
        }
    );
}

/// <summary>
/// Handle failed authentication requests by redirecting the user to the home page with an error in the query string
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
private Task OnAuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context)
{
    context.HandleResponse();
    context.Response.Redirect("/?errormessage=" + context.Exception.Message);
    return Task.FromResult(0);
}

My Login Page Code:

protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            if (!IsPostBack)
            {
                if (!Request.IsAuthenticated)
                {
                    HttpContext.Current.GetOwinContext().Authentication.Challenge(
                        new AuthenticationProperties { RedirectUri = "/AMS/Dashboard" },
                        OpenIdConnectAuthenticationDefaults.AuthenticationType);
                }
                else
                {
                    var userClaims = User.Identity as System.Security.Claims.ClaimsIdentity;
                    lblErrorMessage.InnerHtml = userClaims?.FindFirst("preferred_username")?.Value;
                    //check user info, and create session then redirect to Dashboard
                }
            }
        }
        catch (Exception ex)
        {
             //handle error
        }
  }

My Website structure is a little bit complicated as follow:

I have a website on the server x: mydomain.com and I have a subdomain in server y: subdomain.mydomain.com and I have my website AMS on server z with a redirect to subdomain.mydomain.com/AMS

now to solve cross-site cookie I use the following in web config

<outboundRules>
    <rule name="Ensure httpOnly Cookies" preCondition="Missing httpOnly cookie">
        <match serverVariable="RESPONSE_Set_Cookie" pattern="^(.*; path=/)" negate="false" />
        <action type="Rewrite" value="{R:1}AMS; SameSite=none; secure; HttpOnly" />
    </rule>
    <preConditions>
        <preCondition name="Missing httpOnly cookie">
            <!-- Don't remove the first line! -->
            <add input="{RESPONSE_Set_Cookie}" pattern="." />
            <add input="{RESPONSE_Set_Cookie}" pattern="; SameSite=none; secure; HttpOnly" negate="true" />
        </preCondition>
    </preConditions>
</outboundRules>

My Problem is Request.IsAuthenticated is always false, so the page keep redirect to the Microsoft login page

Any ideas? Thanks in advance

Gonfalon answered 10/10, 2020 at 21:58 Comment(3)
Are any cookies getting blocked? The Chrome network tab has an option called "Has blocked cookies" to check on this.Phenix
@Phenix Yes itsGonfalon
Does it work if you turn off the same site cookie enforcement in chrome? support.siteimprove.com/hc/en-gb/articles/…Phenix
K
0

Instead of the rewrite rule try this:

app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    CookieSameSite = Microsoft.Owin.SameSiteMode.None,
    CookieSecure = CookieSecureOption.Always
});

Also ensure the secure attribute is set as well

From https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite

SameSite NONE - Cookies will be sent in all contexts, i.e in responses to both first-party and cross-origin requests. If SameSite=None is set, the cookie Secure attribute must also be set (or the cookie will be blocked).

Kentigera answered 16/6, 2021 at 19:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.