Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CORS issue when working with authentication #116

Open
dl2alf opened this issue Feb 11, 2024 · 0 comments
Open

CORS issue when working with authentication #116

dl2alf opened this issue Feb 11, 2024 · 0 comments

Comments

@dl2alf
Copy link

dl2alf commented Feb 11, 2024

In a cross domain scenario all browsers do a CORS preflight request to check permissions of the requested web site. VRS basically does handle CORS when CORS support is activated in Tools/Options/Website. But if both CORS support and user authentication is enabled I got an CORS error reported and the browser refuses to work with the data received.

What I could investigate so far:
Browsers always send CORS preflight requests without authentication in order to keep the credentials secure.
In VRS, the standard pipeline build for websites puts the authentication filter before the CORS handler.
As a result, VRS web server answers the preflight request with Error 403 (not authenticated), stops the pipeline and we are done.

I am not very familiar with VRS architecture but a solution might be to skip authentication filter in case of CORS preflight requests.
Furthermore, browsers need a "Access-Control-Allow-Credentials" header set to TRUE on CORS GET repsonses to pass the last browser check.

I could manage to compile a working VRS web server from the current source tree by modifying the following two procedures:

  1. in BasicAuthenticationFilter.cs

    _/// <summary>
    /// Returns true if the request is authenticated, false otherwise. If the request has not been
    /// authenticated then pipeline processing should be stopped.
    /// </summary>
    /// <param name="environment"></param>
    /// <returns></returns>
    private bool Authenticated(IDictionary<string, object> environment)
    {
        var result = true;
    
        var sharedConfig = _SharedConfiguration.Get();
        var context = OwinContext.Create(environment);
    
        // skip authentication check in case of CORS preflight request (OPTIONS)
        if (context.RequestHttpMethod != HttpMethod.Options)
        {
            // proceed with basic authentication check
            var isAdminOnlyPath = _AuthenticationConfiguration.IsAdministratorPath(context.RequestPathNormalised);
            var isGlobalAuthenticationEnabled = sharedConfig.WebServerSettings.AuthenticationScheme == AuthenticationSchemes.Basic;
    
            if (isAdminOnlyPath || isGlobalAuthenticationEnabled)
            {
                result = false;
    
                string userName = null;
                string password = null;
                if (ExtractCredentials(context, ref userName, ref password))
                {
                    var cachedUser = _BasicAuthentication.GetCachedUser(userName);
                    var cachedUserTag = _BasicAuthentication.GetCachedUserTag(cachedUser);
                    var isPasswordValid = _BasicAuthentication.IsPasswordValid(cachedUser, cachedUserTag, password);
    
                    result = isPasswordValid && (!isAdminOnlyPath || cachedUser.IsAdministrator);
                    if (result)
                    {
                        context.RequestPrincipal = _BasicAuthentication.CreatePrincipal(cachedUser, cachedUserTag);
                    }
                }
    
                if (!result)
                {
                    SendNeedsAuthenticationResponse(context);
                }
            }
        }
    
        return result;
    }_
    
  2. In CorsHandler.cs

    __/// <summary>
    /// Adds Allow-Origin headers to simple requests that match the origin.
    /// </summary>
    /// <param name="context"></param>
    /// <param name="origin"></param>
    private void HandleSimpleRequest(OwinContext context, string origin)
    {
        if(OriginIsAllowed(origin)) {
            context.ResponseHeadersDictionary["Access-Control-Allow-Origin"] = origin;
        }
    
        // add access control header to pass CORS check of browsers
        var sharedConfig = _SharedConfiguration.Get();
        if (sharedConfig.WebServerSettings.AuthenticationScheme == AuthenticationSchemes.Basic)
        {
    
            context.ResponseHeadersDictionary["Access-Control-Allow-Credentials"] = "true";
        }
    
    
    }__
    

I kindly ask the maintainers to verify this and to push approbiate code changes to the repository.
Thank you in advance!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant