skip to Main Content

I’m currently working on an ASP.NET project where I’m using ASP.NET Identity to manage user accounts. There is also an API included in my web application. My current problem is that when a client makes an API request that they are not authenticated or authorized for, they are redirected to the login/forbidden page. However, I would like such API requests to return a JSON error instead of redirecting the user to the login page. Can anyone help me with how to customize this behavior in my ASP.NET application? Is there any specific middleware or settings I need to configure to achieve this behavior? Any help or advice would be greatly appreciated.

2

Answers


  1. In your subsequent description, I understand you

    wants to make API requests to return a JSON error instead of
    redirecting the user to the login page

    In my option I suggest you could to create a Middleware to handle API requests and web page requests:

    public class ApiRequestMiddleware
    {
        private readonly RequestDelegate _next;
    
        public ApiRequestMiddleware(RequestDelegate next)
        {
            _next = next;
        }
     
        public async Task Invoke(HttpContext context)
        {
            if (context.Request.Path.StartsWithSegments("/api"))
            {
                
                try
                {
                    
                    context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                    context.Response.ContentType = "application/json";
    
                    var errorResponse = new
                    {
                        message = "Unauthorized API requests",
                        error = "Authentication failed"
                    };
    
                    await context.Response.WriteAsync(JsonConvert.SerializeObject(errorResponse));
                }
                catch (Exception ex)
                {
                    
                    context.Response.StatusCode = StatusCodes.Status500InternalServerError;
                    context.Response.ContentType = "application/json";
    
                    var errorResponse = new
                    {
                        message = "serve error",
                        error = ex.Message
                    };
    
                    await context.Response.WriteAsync(JsonConvert.SerializeObject(errorResponse));
                }
            }
            else
            {
                
                await _next(context);
            }
        }
    }
    
    Login or Signup to reply.
  2. Based on what you suggest about my solution, I’ve made improvements to my code:

     public class ApiRequestMiddleware
        {
            private readonly RequestDelegate _next;
           
            public ApiRequestMiddleware(RequestDelegate next)
            {
                _next = next;
            }
    
            public async Task Invoke(HttpContext context)
            {
                if (context.Request.Path.StartsWithSegments("/api"))
                {
                    
                    try
                    {
                        if  (context.User.Identity.IsAuthenticated && context.User.IsInRole("Administrator"))
                            {
                            var user = context.User;
                            var userId = user.FindFirst(ClaimTypes.NameIdentifier)?.Value;
                            var username = user.FindFirst(ClaimTypes.Name)?.Value;
                          
                            context.Response.ContentType = "application/json";
                            var successResponse = new
                            {
                                message = "Authorization passed",
                                UserId = userId,
                                Username = username
                            };
                            await context.Response.WriteAsync(JsonConvert.SerializeObject(successResponse));
    
                        }
                        else
                        { 
                            context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                            context.Response.ContentType = "application/json";
    
                            var errorResponse = new
                            {
                                message = "Unauthorized API requests",
                                error = "Authentication failed"
                            };
    
                            await context.Response.WriteAsync(JsonConvert.SerializeObject(errorResponse));
                        }
                    }
                    catch (Exception ex)
                    { 
                        context.Response.StatusCode = StatusCodes.Status500InternalServerError;
                        context.Response.ContentType = "application/json";
    
                        var errorResponse = new
                        {
                            message = "serve error",
                            error = ex.Message
                        };
    
                        await context.Response.WriteAsync(JsonConvert.SerializeObject(errorResponse));
                    }
                }
                else
                {
                    await _next(context);
                }
            }
        }
    
    }
    

    When I passed Authorization the API will return the current user dataļ¼š
    enter image description here

    When I Unauthorized API requests it will return a json:

    enter image description here

    And there is other method :

    public async Task Invoke(HttpContext context)
    {
        if (context.Request.Path.StartsWithSegments("/api"))
        {
                    
            try
            {
                if  (context.User.Identity.IsAuthenticated && context.User.IsInRole("Administrator"))
                    {
                            
                    if (context.Request.Path.StartsWithSegments("/api/Test"))
                    {
                        await CallApiResource(context);
                    }
                }
                else
                { 
                    context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                    context.Response.ContentType = "application/json";
    
                    var errorResponse = new
                    {
                        message = "Unauthorized API requests",
                        error = "Authentication failed"
                    };
    
                    await context.Response.WriteAsync(JsonConvert.SerializeObject(errorResponse));
                }
            }
            catch (Exception ex)
            { 
                context.Response.StatusCode = StatusCodes.Status500InternalServerError;
                context.Response.ContentType = "application/json";
    
                var errorResponse = new
                {
                    message = "serve error",
                    error = ex.Message
                };
    
                await context.Response.WriteAsync(JsonConvert.SerializeObject(errorResponse));
            }
        }
        else
        {
            await _next(context);
        }
    }
    
    private async Task CallApiResource(HttpContext context)
    {
               
         var apiController = new TestApiController();
         var apiData = apiController.GetUsers() as ObjectResult;
    
         if (apiData != null)
         {
             var users = apiData.Value;
    
                   
             var successResponse = new
             {
                 message = "Authorization passed",
                 data = users
             };
    
             var json = JsonConvert.SerializeObject(successResponse);
    
             context.Response.ContentType = "application/json";
             context.Response.StatusCode = StatusCodes.Status200OK;
             await context.Response.WriteAsync(json);
         }
    }
    
    [Route("api/test")]
    [ApiController]
    public class TestApiController : ControllerBase
    {
        [HttpGet("users")]
        public IActionResult GetUsers()
        {
           
            var users = new List<string> { "User1", "User2", "User3" };
    
            return Ok(users);
        }
    }
    

    When I passed Authorization I could get users by CallApiResource:
    enter image description here

    When I Unauthorized:
    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search