Base solution for your next web application

Activities of "adam.langley"

I am using AspNetZero Core+Angular.

I am receiving an "internal server error" response to an ajax call, but there is no output in the log file to figure out what is throwing the exception.

The HTTP response looks like this:

{"error":"Internal Server Error","result":null,"success":false}

And there are no errors in the Log.txt (there is Info logging, so I know logging is working).

I have writing an exception handler, but it never fires.

public class MyExceptionHandler : IEventHandler<AbpHandledExceptionData>, ITransientDependency
{
    public void HandleEvent(AbpHandledExceptionData eventData)
    {
        //TODO: Check eventData.Exception!
    }
}

I have tried overriding the exception filter which (I think) is producing the ajax wrapped exception response object, and injected it - but it also does not fire.

public class MyExceptionFilter : AbpExceptionFilter, ITransientDependency
{

    public MyExceptionFilter(IErrorInfoBuilder errorInfoBuilder, IAbpAspNetCoreConfiguration configuration)
        :base(errorInfoBuilder, configuration)
    {
    }

    protected override void HandleAndWrapException(ExceptionContext context, WrapResultAttribute wrapResultAttribute)
    {
        base.HandleAndWrapException(context, wrapResultAttribute);
    }

}

Where do I go from here?

Thanks

Ok - I've figured it out.

The template contains a web.config which contains hard-coded environment variable overrides:

    <environmentVariables>
        <!--environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" /-->
        <environmentVariable name="COMPLUS_ForceENC" value="1" />
      </environmentVariables>

I commented this out, and it is now correctly loading the environment from Azure App Settings.

Hi,

I've done some more investigation.

It does appear that the app is not loading 'appsettings.Staging.json'.

I have logged into Azure console, and check the environment variables:

ASPNETCORE_ENVIRONMENT=Staging

Has been set...

And my settings file name (as per the template)

appsettings.Staging.json

I can put an error in this json file, and reload the web service (by touching the web.config) - and no error is shown. If I put a syntax error in appsettings.json and reload the app - I do get an error.

So, it's clear that the web app is loading appsettings.json, NOT appsettings.Staging.json - even though the ASPNETCORE_ENVIRONMENT environment variable has been set.

Please advise,

Thanks,

Another test result - the following works, for ALL subdomains - not just single-level ones

builder
    .WithOrigins(
        // App:CorsOrigins in appsettings.json can contain more than one address separated by comma.
        "http://*.myredactedhost.com"
            .Split(",", StringSplitOptions.RemoveEmptyEntries)
            .Select(o => o.RemovePostFix("/"))
            .ToArray()
    )
    .SetIsOriginAllowedToAllowWildcardSubdomains()
    .AllowAnyHeader()
    .AllowAnyMethod()
    .AllowCredentials();

It looks like there are are some known issues here, but no AzpNetZero sanctioned resolution. Can you please confirm what the resolution process is?

https://support.aspnetzero.com/QA/Questions/7212/Chat-feature-is-not-working-on-Angular-app-deployed-as-a-container-in-Azure https://support.aspnetzero.com/QA/Questions/8864/CORS-configuration-problem---850

Hi @ismcagdas,

I have made some progress. I realised that: builder.AllowAnyOrigin();

and

builder.AllowCredentials();

are not compatible - interestingly, this error was not made visible in the issue I was having. When I removed "AllowAnyOrigin" and replaced it with a specific host - it worked correctly.

What this indicates, is that there is something wrong with the configuration.

I have investigated further, and found this to be the problem.

This configuration works: "CorsOrigins": "http://portal.myredactedhost.com:80,http://subdomain.portal.myredactedhost.com:80"

This configuration does NOT work ("Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource."):

 "CorsOrigins": "http://portal.myredactedhost.com:80,http://*.portal.myredactedhost.com:80"

I am using the ASPnet Zero code for setting the CORS options:

        //Configure CORS for angular2 UI
        services.AddCors(options =>
        {
            options.AddPolicy(DefaultCorsPolicyName, builder =>
            {
                //App:CorsOrigins in appsettings.json can contain more than one address with splitted by comma.
                builder
                    .WithOrigins(
                        // App:CorsOrigins in appsettings.json can contain more than one address separated by comma.
                        _appConfiguration["App:CorsOrigins"]
                            .Split(",", StringSplitOptions.RemoveEmptyEntries)
                            .Select(o => o.RemovePostFix("/"))
                            .ToArray()
                    )
                    .SetIsOriginAllowedToAllowWildcardSubdomains()
                    .AllowAnyHeader()
                    .AllowAnyMethod()
                    .AllowCredentials();
            });
        });

So, it appears that it is the wildcards that are causing the server to not send the CORS allowed domains header.

Prerequisites

  • What is your product type: Angular
  • What is product framework type .net core

I have a basically default template, and everything works on localhost, but not when I deploy to Azure.

My Azure deployment is, the Angular site is hosted as an Azure Blob Storage static website, and the .net Core API is an App Service.

These are the symptoms I am experiencing.

  1. When using the default CORS code (I have added my blob storage URI to the CorsOrigins setting "http://MYREDACTEDSITE.z8.web.core.windows.net"), I get the dreaded "Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource." When I check the various response headers, I indeed see that no CORS origins header exists.
  2. When I use Azure App Service CORS settings, and add the wildcard origin ( * ) it works - but SignalR doesnt work. I have read various ABP and Zero forum postings where it is said "dont use Azure CORS" - so I'd rather rely on the C# code.
  3. When I use Azure App Service CORS specific origin host it does NOT work - again, I see no CORS headers are returned - this is weird, wildcard returns the headers, but specific hosts do not?
  4. I. have also commented out the code in Startup.cs, and replace it with Rick Strahls "enable all origins" code (see below) to rule out the possibility that my config is not being picked up somehow. Also this does not work.

Note: I do ensure that I reset the Azure CORS config when I'm testing the ASP ones

Thanks,

Appendix: Rick Strahls enable all origins

        services.AddCors(options =>
        {
            options.AddPolicy(DefaultCorsPolicyName,
                builder => builder.AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials());
        });
Answer

Thanks @bobingham - nice design.

I'm using Flutter.

Your proposal doesn't quite fit for me however - as registration can happen either through the app or via the web.

Even if the user initially registers through the app - they will likely log on using other devices, which is not another registration - just a login.

The only way I can see (and the cleanest) is for the server to offer a list of tenants, once the user has been authenticated against at least one of the tenants.

Something like this (server-side pseudo code):

var listOfTenants = tenants.Where(x => x.email == userSubmittedEmail && x.password == userSubmittedPassword)

if (listOfTenants.Count == 0)
    return InvalidLoginAttempt()
else
{
    var firstTenant = listOfTenants.First();
    GenerateAuthenticationToken(firstTenant);
    if (listOfTenants.Count == 1)
        return RedirectToWelcomePage(firstTenant)
    else
        return RedirectToTenantChooser(listOfTenants)
 }
Question

Hi,

I am building a mobile front-end for our application - and the requirement for the user to enter the tenant name is cumbersome.

For the web, this makes sense, and is not a problem, because each customer will be given a custom domain (3rd level), which provides the requisite tenancy information for the backend code.

For mobile applications, however - one cannot create a copy of the app in the app store, for each tenant (Apple app store violation - and would also just be a PITA) - so I understand why the user needs to specify a tenant when logging in.

It is, however, cumbersome for the user.

I could provide a dropdown to choose the tenant - however, because this would need to be a public API call (unauthenticated), it's a security/privacy concern - exposing the list of customer names.

Ideally, the user would log in using email/password, then be presented with a list of all tenancies which matched those credentials, allowing the user to pick one.

What would be your recommendation around achieving this?

Hi,

I got this to work, now I want to package this into a Module. How now do I get access to the "Services" collection from inside an AbpModule to I can register the filter?

// how can I get access to "services" within AbpModule.Initialize, or PostInitialize... etc? services.Configure<MvcOptions>(options => { options.Filters.Add(typeof(YourFilter)); });

Thanks,

Showing 1 to 10 of 19 entries