提问人:Suiarm1 提问时间:11/3/2023 最后编辑:Zhi LvSuiarm1 更新时间:11/6/2023 访问量:111
在 ASP.NET Identity 中处理未经身份验证或未经授权的 API 请求
Handling unauthenticated or unauthorized API requests in ASP.NET Identity
问:
我目前正在从事一个 ASP.NET 项目,我正在使用 ASP.NET Identity 来管理用户帐户。我的 Web 应用程序中还包含一个 API。我目前的问题是,当客户端发出未经身份验证或授权的 API 请求时,它们会被重定向到登录/禁止页面。但是,我希望此类 API 请求返回 JSON 错误,而不是将用户重定向到登录页面。谁能帮我了解如何在我的 ASP.NET 应用程序中自定义此行为?我是否需要配置任何特定的中间件或设置来实现此行为?任何帮助或建议将不胜感激。
答:
0赞
Yuning Duan
11/3/2023
#1
在你随后的描述中,我理解你
想要发出 API 请求以返回 JSON 错误而不是 将用户重定向到登录页面
在我的选择中,我建议您可以创建一个中间件来处理 API 请求和网页请求:
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);
}
}
}
评论
0赞
Suiarm1
11/3/2023
您的解决方案将为每个 API 请求返回一个 JSON 错误,无论它是授权的还是未经授权的。
0赞
Yuning Duan
11/6/2023
#2
根据您对我的解决方案的建议,我对我的代码进行了改进:
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);
}
}
}
}
当我未经授权的 API 请求时,它将返回一个 json:
还有其他方法:
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);
}
}
评论