Enabling SSL in ASP.NET MVC 5 app results in OpenI

2019-03-13 03:32发布

I have an ASP.NET MVC 5 app that authenticates against Azure Active Directory. I wanted to enable SSL on it across the app. and hence leveraged global filters as follows:

public class FilterConfig
{
    /// <summary>
    /// Registers the global filters.
    /// </summary>
    /// <param name="filters">The filters.</param>
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new RequireHttpsAttribute());
    }
}

After this I also set 'Enable SSL' in the project's properties to true. This gave me the following SSL URL -> https://localhost:34567. I updated the project to have this in its IIS Express path under the 'Web Tab' under Servers in 'Project URL'. However on running the site I run in to the following error:

IDX10311: RequireNonce is 'true' (default) but validationContext.Nonce is null. A nonce cannot be validated. If you don't need to check the nonce, set OpenIdConnectProtocolValidator.RequireNonce to 'false'.

I have auth. enabled on the site. I use Azure Active directory.

The security code is as follows:

app.UseOpenIdConnectAuthentication(
            new OpenIdConnectAuthenticationOptions
            {
                ClientId = clientId,
                Authority = authority,
                PostLogoutRedirectUri = postLogoutRedirectUri                    
            });

        app.UseWindowsAzureActiveDirectoryBearerAuthentication(
            new WindowsAzureActiveDirectoryBearerAuthenticationOptions
            {
                Audience = audience,
                Tenant = tenant,      
            });

The auth. values are being read from the web.config and are as follows:

<add key="ida:ClientId" value="<some_guid>" />
<add key="ida:Audience" value="https://localhost:34567/" />
<add key="ida:AADInstance" value="https://login.windows.net/{0}" />
<add key="ida:Tenant" value="microsoft.onmicrosoft.com" />
<add key="ida:PostLogoutRedirectUri" value="https://localhost:34567/" />

I tried setting RequireNonce to false as directed in the error message as follows:

ProtocolValidator = new OpenIdConnectProtocolValidator
                {
                    RequireNonce = false
                }

But this just resulted in an invalid request error.

Could someone help me understand what the problem is here? Everything worked great until SSL was enabled.

8条回答
女痞
2楼-- · 2019-03-13 03:48

Well it would probably be best to look at the katana source code, from that i found the exception type to be OpenIdConnectProtocolInvalidNonceException so i handle it like this.

        if (n.Exception is OpenIdConnectProtocolInvalidNonceException &&
            n.OwinContext.Authentication.User.Identity.IsAuthenticated)
        {
            n.SkipToNextMiddleware();
            return;
        }

I have this exception popup on browsers that cache the pages and users that click the back button after login.

查看更多
兄弟一词,经得起流年.
3楼-- · 2019-03-13 03:52

I manage to work around this problem using following method in the Global.asax file. At least this won't show the exception to the client. I use ELMAH to catch exceptions.

protected void Application_Error(object sender, EventArgs args)
    {
        var ex = Server.GetLastError();
        if (ex.Message.Contains("IDX10311:"))
        {
            Server.ClearError();
            Response.Redirect("https://www.yoursitename.com");                 
        }
查看更多
聊天终结者
4楼-- · 2019-03-13 03:52

Just adding another case I just ran into: the network you connect to may be modifying HTML content.

A customer called with an issue: he could not get past this error. It was a new laptop where he had not logged on before. After about one hour of trying several possible solutions, I decided to check the network he was connected to.

It turns out he was connected to a network in an airport, open and unsecured, and not using a VPN service (lacking some SETA there). I don't know exactly who operated that network or what they were doing, but the Azure AD service must have detected some type of tampering with the nonce.

The moment the user connected to a trusted network, the issue was resolved.

查看更多
我只想做你的唯一
5楼-- · 2019-03-13 03:58

I can reproduce this error by pressing back button couple of times on my web application, even after successful login. can you try these 2 things: in your code below:

app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                    ClientId = mViewWebSite.ClientId,
                    Authority = mViewWebSite.Authority,
                    PostLogoutRedirectUri = mViewWebSite.PostLogoutRedirectUri
                });

add protocol validator as on of the authentication options, as what error suggest:

ProtocolValidator = new Microsoft.IdentityModel.Protocols.OpenIdConnectProtocolValidator(){
                            RequireNonce = false
                        }

or add notification, by this you can catch this error and redirect it to some error page. I do that to make it graceful. Until Katana people fixes it.

Notifications = new OpenIdConnectAuthenticationNotifications
                        {
                            AuthenticationFailed = context =>
                            {
                                context.HandleResponse();
                                context.Response.Redirect("/Error.aspx?message=" + context.Exception.Message);
                                return Task.FromResult(0);
                            }
                        },
查看更多
太酷不给撩
6楼-- · 2019-03-13 04:03

From the Azure management portal, check that your application under the corresponding active directory has the same Sign On URL and reply URL.

If they are not same, you will get this error.

This happens when you enable SSL because it changes only the sign on URL to the HTTPS URL while the reply URL remains the same HTTP URL.

Edit: Read on if you want to know exactly why this is happening,

When you try to access your app using the https URL, it sets a cookie with a unique number(nonce) in your browser and hits Azure AD for authentication. After authentication, the browser has to give access to that cookie. But since the sign on URL and reply URL are different the browser does not recognise your app and does not give access to that cookie and hence the application throws this error.

查看更多
叛逆
7楼-- · 2019-03-13 04:09

You can ignore exceptions if the error message starts with OICE_20004 or contains IDX10311. Note: do it on your own risk.

Notifications = new OpenIdConnectAuthenticationNotifications()
{
    RedirectToIdentityProvider = (context) =>
    {
        // Ensure the URI is picked up dynamically from the request;
        string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase + context.Request.Uri.PathAndQuery;
        context.ProtocolMessage.RedirectUri = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase + context.Request.Uri.PathAndQuery;
        context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;
        return Task.FromResult(0);
    },
    AuthenticationFailed = (context) =>
    {
        if (context.Exception.Message.StartsWith("OICE_20004") || context.Exception.Message.Contains("IDX10311"))
        {
            context.SkipToNextMiddleware();
            return Task.FromResult(0);
        }
        return Task.FromResult(0);
    },
}
查看更多
登录 后发表回答