Open Closed

Issues deploying application to test server #802


User avatar
0
scott7106 created

Check the docs before asking a question: https://docs.abp.io/en/commercial/latest/ Check the samples, to see the basic tasks: https://docs.abp.io/en/commercial/latest/samples/index The exact solution to your question may have been answered before, please use the search on the homepage.

  • ABP Framework version: v4.0.2
  • UI type: Angular
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Seperated (Angular): no

We are looking to deploy our application on an IIS web server which is behind a load balancer with SSL terminated at the load balancer. This is a common deployment strategy for our clients. I am testing this setup with a prototype (single set of CRUD pages) generated using Suite 4.0.0 and later upgraded to 4.0.2.

  1. If I attempt to deploy the API as an application instead of a website in IIS, I get a variety of 404 errors due to absolute paths. For example, https://{mywebsite}/libs/abp/core/abp.js is referenced instead of https://{mywebsite}/{myapp}/libs/abp/core/abp.js.

Question: Does the API require a separate website or can I deploy it as an application within a website? Ideally, I want to deploy the API and the Angular client as as single website, but this isn't going to work if the API must be deployed at the root of a website. Normally, I would create a webite and then deploy the Angular client at the root and the API as a sub application within the website.

  1. There is an error and a warning in the log file when the application starts. Setting SameSite attributes in the web.config file does not have any effect.

2021-01-12 15:54:35.018 +00:00 [INF] Hosting environment: Production 2021-01-12 15:54:35.018 +00:00 [INF] Content root path: {location}\Portal.Api 2021-01-12 15:54:35.036 +00:00 [INF] Request starting HTTP/1.1 GET http://{mywebsite}/portal-prototype-api/Account/Login?ReturnUrl=%2Fportal-prototype-api - - 2021-01-12 15:54:36.956 +00:00 [INF] Executing endpoint '/Account/Login' 2021-01-12 15:54:37.026 +00:00 [INF] Route matched with {page = "/Account/Login", action = "", controller = "", area = ""}. Executing page /Account/Login 2021-01-12 15:54:37.028 +00:00 [INF] Skipping the execution of current filter as its not the most effective filter implementing the policy Microsoft.AspNetCore.Mvc.ViewFeatures.IAntiforgeryPolicy 2021-01-12 15:54:37.795 +00:00 [INF] Executing handler method Volo.Abp.Account.Public.Web.Pages.Account.LoginModel.OnGetAsync - ModelState is "Valid" 2021-01-12 15:54:37.819 +00:00 [INF] Executed handler method OnGetAsync, returned result . 2021-01-12 15:54:37.822 +00:00 [INF] Executing an implicit handler method - ModelState is "Valid" 2021-01-12 15:54:37.822 +00:00 [INF] Executed an implicit handler method, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult. 2021-01-12 15:54:38.006 +00:00 [ERR] An exception was thrown while deserializing the token. Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException: The antiforgery token could not be decrypted. ---> System.Security.Cryptography.CryptographicException: The key {ac856cb7-2721-43c2-820b-6df7287dbb9a} was not found in the key ring. at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status) at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.DangerousUnprotect(Byte[] protectedData, Boolean ignoreRevocationErrors, Boolean& requiresMigration, Boolean& wasRevoked) at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData) at Microsoft.AspNetCore.Antiforgery.DefaultAntiforgeryTokenSerializer.Deserialize(String serializedToken) --- End of inner exception stack trace --- at Microsoft.AspNetCore.Antiforgery.DefaultAntiforgeryTokenSerializer.Deserialize(String serializedToken) at Microsoft.AspNetCore.Antiforgery.DefaultAntiforgery.GetCookieTokenDoesNotThrow(HttpContext httpContext) 2021-01-12 15:54:38.190 +00:00 [WRN] The cookie 'XSRF-TOKEN' has set 'SameSite=None' and must also set 'Secure'.


11 Answer(s)
  • User Avatar
    0
    gterdem created
    Senior .NET Developer

    Hello @scott7106,

    It seems like a problem with data protection key persistency.

    Can you try persisting data protection keys to file system or redis (if you have already) in your HostModule service configuration? For file persistency something like;

    context.Services.AddDataProtection().PersistKeysToFileSystem(new System.IO.DirectoryInfo(@"/var/my-af-keys/"));

    for windows use a directory like c:/my-af-keys/ etc.

  • User Avatar
    0
    scott7106 created

    The issue with the persisted keys does not occur when the API is the root application of a website. I backed up and decided to attempt combining the applications so that the API is at the root and the angular client is deployed as a subfolder within the API.

    • HttpApi.Host\client

    In the Startup.cs file of the HttpApi.Host project, I added the following code to the ConfigureServices method:

    services.AddSpaStaticFiles(configuration =>
    {
        configuration.RootPath = "client";
    });
    

    In the Configure method, I added the following:

    app.UseSpaStaticFiles(new StaticFileOptions
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(env.ContentRootPath, "client")),
            RequestPath = "/client"
    });
    
    app.UseSpa(spa =>
    {
        spa.Options.SourcePath = "client";
    });
    

    I created a local environment in Angular with the URI settings needed for this configuration, ran ng build for the new environment with a base-href value of /client/ and then used xcopy to place resulting dist files in my API project.

    With this configuration, I can access both the client and the API locally. However, while the login/logout process works and the GET methods from the API work for the client, as soon as I attempt to post something from the client, I get an error which is not sent by the server and the following entry in the log files. [ERR] The required antiforgery header value "RequestVerificationToken" is not present.

  • User Avatar
    0
    bunyamin created

    Hello,

    It looks like your problem could be related to the case explained in the note within this docs

    If you serve your apis from the root, just set url to empty as follows:

    export const environment = {
      production: true,
      // ....
      apis: {
        default: {
          url: '', // <- use the context root here
         // ...
        },
      },
    } as Config.Environment;
    
    

    Would you try this?

  • User Avatar
    0
    MILLENNIUM created

    Dears, Any update on this? we cannot publish any abp project, event if it is autogenerated by suite!

  • User Avatar
    0
    bunyamin created

    Hello @MILLENNIUM,

    Could you post your environment.ts and environment.prod.ts here? This error is usually about misconfiguration.

  • User Avatar
    0
    scott7106 created

    Hello @MILLENNIUM, We have not solved the issue with deploying this as a single website with the angular client as a sub folder. We have been successful deploying them as 2 separate web applications.

    Here is an exampe of the environment.ts file. This is the local setup, we replace the localhost with a public DNS for our test/production sites.

    import { Environment } from '@abp/ng.core';
    
    const baseUrl = 'https://localhost:44316/client';
    
    export const environment = {
      production: false,
      application: {
        baseUrl,
        name: 'Portal',
      },
      oAuthConfig: {
        issuer: 'https://localhost:44316',
        redirectUri: baseUrl,
        clientId: 'Portal_App',
        responseType: 'code',
        scope: 'offline_access openid profile email phone Portal',
      },
      apis: {
        default: {
          url: '',
          rootNamespace: 'OtisEd.Portal',
        },
      },
    } as Environment;
    
  • User Avatar
    0
    bunyamin created

    Hello scott,

    Could you post an example of your request made from browser to the production site with request and response (headers as well)?

    We use a similar setup for our demo and it works. You can check it out here

  • User Avatar
    0
    MILLENNIUM created

    Dears, I think the issue was because I was publishing the system with microservices to localhost, and they was an exception because of use self-signed certificate on my local server, I managed to solve the issue by changing the following code:

    context.Services.AddAuthentication() .AddJwtBearer(options => { options.Authority = configuration["AuthServer:Authority"]; options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]); ; options.Audience = "WorkflowDemo"; options.BackchannelHttpHandler = new HttpClientHandler() { ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator }; });

  • User Avatar
    0
    bunyamin created

    Hello @MILLENNIUM,

    I'm glad you were able to solve your problem.

    @scott, could your problem also be related to some other configuration?

  • User Avatar
    0
    scott7106 created

    @bunyamin, thank you for the assistance. We were able to deploy our application successfully as a single application in Azure. We may still have issues deploying it behind an SSL terminated load balancer, but that has been deferred to a later date.

  • User Avatar
    0
    bunyamin created

    I'm glad your problem is solved. Closing this issue,

    Have a nice day.

Made with ❤️ on ABP v9.1.0-preview. Updated on December 13, 2024, 06:09