liang.good
liang.good

Reputation: 273

How to return a value instead of a status if request is not authorised?

[authorise]
public string Get()
{
    return "value1";
}

if I am not authorised it will return a status of 401 not authorised.

can it return a value such as json "{status:false,code:"401"}". ?

Upvotes: 2

Views: 1143

Answers (4)

Brando Zhang
Brando Zhang

Reputation: 27997

According to your description, I suggest you could try to use custommiddleware to achieve your requirement.

You could captured the 401 error in middleware and then rewrite the response body to {status:false,code:"401"}

More details, you could add below codes into Configure method above the app.UseAuthentication();:

        app.Use(async (context, next) =>
        {
            await next();
            if (context.Response.StatusCode == 401)
            {
                await context.Response.WriteAsync("{status:false,code:'401'}");
            }
        });

Result:

enter image description here

Upvotes: 1

Vivek Nuna
Vivek Nuna

Reputation: 1

You can return the below if using Asp.Net Core 3.1, It returns UnauthorizedObjectResult.

return Unauthorized(new { status: false, code: 401 });

Upvotes: 0

Tân
Tân

Reputation: 1

can it return a value such as json "{status:false,code:"401"}". ?

Sure, you can.

[ApiController]
[Produces("application/json")]
public class TestController : ControllerBase
{
    public IActionResult Get()
    {
        if (User.Identity.IsAuthenticated) 
        { 
            return new OkObjectResult(new { status: true, code: 200 });
        }
        return new OkObjectResult(new { status: false, code: 401 });
    }
}

But notice that, the request will return with the real status code 200 (OK)


You can also use UnauthorizedObjectResult like @vivek's comment:

return new UnauthorizedObjectResult(new { status: false, code: 401 });

Upvotes: 0

kapuetze
kapuetze

Reputation: 35

You can create a custom authorize attribute using IAsyncAuthorizationFilter.

public class CustomAuthorizeFilter : IAsyncAuthorizationFilter
{
    public AuthorizationPolicy Policy { get; }

    public CustomAuthorizeFilter(AuthorizationPolicy policy)
    {
        Policy = policy ?? throw new ArgumentNullException(nameof(policy));
    }

    public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        // Allow Anonymous skips all authorization
        if (context.Filters.Any(item => item is IAllowAnonymousFilter))
        {
            return;
        }

        var policyEvaluator = context.HttpContext.RequestServices.GetRequiredService<IPolicyEvaluator>();
        var authenticateResult = await policyEvaluator.AuthenticateAsync(Policy, context.HttpContext);
        var authorizeResult = await policyEvaluator.AuthorizeAsync(Policy, authenticateResult, context.HttpContext, context);

        if (authorizeResult.Challenged)
        {
            // Return custom 401 result
            context.Result = new CustomUnauthorizedResult("Authorization failed.");
        }
        else if (authorizeResult.Forbidden)
        {
            // Return default 403 result
            context.Result = new ForbidResult(Policy.AuthenticationSchemes.ToArray());
        }
    }
}

public class CustomUnauthorizedResult : JsonResult
{
    public CustomUnauthorizedResult(string message)
        : base(new CustomError(message))
    {
        StatusCode = StatusCodes.Status401Unauthorized;
    }
}

public class CustomError
{
    public string Error { get; }

    public CustomError(string message)
    {
        Error = message;
    }
} 

The code in this article does exactly what you want. click here

Upvotes: 0

Related Questions