0
votes

im building some .net core api for my angular app i want to use both - windows authentication and jwt for it and because request can have only ONE Authentication header - im passing my token in own 'CustomAuthorization' headher so windows auth can be present in default. so i added

  app.UseMiddleware<CheckCustomHeader>();

i builded my middleware

public  class CheckCustomHeader
{
    private readonly RequestDelegate _next;

    public CheckCustomHeader(RequestDelegate next)
    {
        _next = next;
    }
    public async Task Invoke(HttpContext context)
    {

        if (context.Request.Method == HttpMethods.Post)
        {
            string token = context.Request.Headers["CustomAuthorization"];

            try
            {
                string secret = "MySecreetKey";
                        var key = Encoding.ASCII.GetBytes(secret);
                        var handler = new JwtSecurityTokenHandler();
                        var validations = new TokenValidationParameters
                        {
                            ValidateIssuerSigningKey = true,
                            IssuerSigningKey = new SymmetricSecurityKey(key),
                            ValidateIssuer = false,
                            ValidateAudience = false
                        };           
                        var claims = handler.ValidateToken(token, validations, out var tokenSecure);
                        var x = claims.Identity.Name;
                       //toDo - check if this token identityName = windows auth identity 
            }
            catch (System.Exception)
            {
                context.Response.Clear();
                context.Response.ContentType = "text/plain; charset=utf-8";
                context.Response.StatusCode = StatusCodes.Status400BadRequest;
                await context.Response.WriteAsync("Invalid User Key");      
                // return ? // should it be there? i tryied both cases ;)           
            }
        }

        await _next(context);
    }

and it does work well - if key is ok then no problem but when jwt key is not ok i want to catch exception and return this badrequest. in postman it is ok - it returns 400 and this message in body, but from my angular app i get

 Access to XMLHttpRequest at 'http://localhost:51500/SP/t/generateReport/' from origin 
 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is 
 present on the requested resource.
 data.service.ts:43 unCatch DataService post error:0{"headers":{"normalizedNames": 
 {},"lazyUpdate":null,"headers":{}},"status":0,"statusText":"Unknown Error",url":"http://localhost:51500/SP/t/generateReport","ok":false,"name":"HttpErrorResponse","message":"Http failure response for http://localhost:51500/SP/t/generateReport/: 0 Unknown Error","error":{"isTrusted":true}}
 zone-evergreen.js:2828 POST http://localhost:51500/SP/t/generateReport/ net::ERR_FAILED

so like any cors blocked request - why ? i have corse configured and woths well for all other requests... should i manualy add some cors headers for this owerwriten by me request ? or how should i return this error in middleware?

thanks and regards !

edit cors policy is added this way

  string[] HostOrigins = new string[] { "http://localhost:4200", "https://localhost:4200"};

        services.AddCors(options =>    
        {

            options.AddPolicy("CorsPolicy", builder =>
            {
                builder.WithOrigins(a.CorsSettings.Origins)
                        .AllowAnyHeader().AllowAnyMethod().AllowCredentials();
            });

        });

and then

   app.UseCors("CorsPolicy");
2
how do you add the cors support ?Nan Yu
i added in editd00lar

2 Answers

0
votes

i found a solution it works when i add cors headers manualy

                context.Response.Clear();
                context.Response.Headers.Add("Access-Control-Allow-Origin", "http://localhost:4200");
                context.Response.Headers.Add("Access-Control-Allow-Methods", "POST");
                context.Response.Headers.Add("Access-Control-Allow-Credentials", "true");


                context.Response.ContentType = "text/plain; charset=utf-8";
                context.Response.StatusCode = StatusCodes.Status400BadRequest; 
                await context.Response.WriteAsync("Invalid User Key");

so yes it is cors issue - in this approach cors policy it is not used when response generated 'by hand'. but im not happy with this - anyone known how to tho this 'right way' ? regatds

-----edit------

so easy - order matters!! it is enough to have

 app.UseCors("CorsPolicy");

BEFORE

 app.UseMiddleware<CheckCustomHeader>();

i had after.... ;/ ;P

-1
votes

You can try the following :

Install 'Microsoft.AspNet.WebApi.Cors'. (By simply running following command in PM Console.

Install-Package Microsoft.AspNet.WebApi.Cors

Post this open the file App_Start/WebApiConfig.cs. Add the following code to the WebApiConfig.Register method:

config.EnableCors();

Your sample file will look like :

using System.Web.Http;
namespace WebService
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // New code
            config.EnableCors();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}

Next, add the [EnableCors] attribute to the Controller in which your middleware exists along with the origin, headers, and methods. To allow all requests use '*' in the headers and methods field.

Example :

using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Cors;

namespace WebService.Controllers
{
    [EnableCors(origins: "http://www.mywebsite.com", headers: "*", methods: "*")]
    public class TestController : ApiController
    {
        // Controller methods not shown...
    }
}

Note: This can be added at Action Level, Controller Level as well as globally for your application.

To make use of it globally, the WebApiConfig will look like :

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute("www.mywebsite.com", "*", "*");
        config.EnableCors(cors);
        // ...
    }
}