我的自定义授权属性(用于基本身份验证)有什么问题?
What is wrong about my custom authorization attribute (for Basic Authentication)?
我有一个 .NET 6.0 网络应用程序,它使用基于 Cookie 的用户身份验证。
今天我想添加一个 API 具有非常简单的 BASIC AUTHENTICATION 机制的控制器。
这是我的控制器:
public class DemaController : Controller
{
[HttpGet("test")]
[BasicAuthentication(username: "test", password: "abc")]
public bool Test()
{
return true;
}
}
这是我超级简单的基本身份验证属性:
public class BasicAuthenticationAttribute : Attribute, IAuthorizationFilter
{
private readonly string _username;
private readonly string _password;
public BasicAuthenticationAttribute(string username, string password)
{
_username = username;
_password = password;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
try
{
var authorizationHeader = context.HttpContext.Request.Headers["Authorization"];
(string username, string password) = this.GetUsernameAndPassword(authorizationHeader: authorizationHeader);
if (username != null && password != null)
{
if (username == _username && password == _password)
return; // Grant access
}
}
catch (FormatException)
{
}
context.Result = new UnauthorizedResult();
}
static System.Text.Encoding ISO_8859_1_ENCODING = System.Text.Encoding.GetEncoding("ISO-8859-1");
private (string, string) GetUsernameAndPassword(string authorizationHeader)
{
if (authorizationHeader == null || !authorizationHeader.Contains("Basic "))
return (null, null);
string encodedUsernamePassword = authorizationHeader.Substring("Basic ".Length).Trim();
string usernamePassword = ISO_8859_1_ENCODING.GetString(Convert.FromBase64String(encodedUsernamePassword));
string username = usernamePassword.Split(':')[0];
string password = usernamePassword.Split(':')[1];
return (username, password);
}
}
当我 运行 本地计算机上的应用程序 (Visual Studio 2022 + IIS Express) 并使用 Postman 访问 Api 时一切正常。正如预期的那样,响应为“true”。
这是我喂邮递员的方式:
- 获取 https://localhost:44360/test
- 授权类型:基本授权
- 用户名:test
- 密码:abc
所以我的自定义 BasicAuthenticationAttribute 似乎有效。我可以设置断点(被击中)和对 Postman 凭据的任何更改 returns Http-401 错误。
到目前为止一切顺利。
现在我将我的应用程序发布到我的生产服务器 (IIS)。在 Postman 中,我将“localhost:44360”替换为我的实际生产域。
我的问题:将请求发送到我的生产服务器 returns 一个 401(以及整个 ASP.NET 核心默认错误页面)。
我更进一步,在我的服务器上设置了 MS Visual Studio 远程调试器。然后我在我的自定义 BasicAuthenticationAttribute 中设置了一个断点。永远不会命中断点。换句话说:401 不是来自我的属性内部。似乎我的 BasicAuthenticationAttribute 在我的服务器上根本没有被触及(但它肯定在我的开发机器上被触及,如前所述)。
让我猜猜:我需要在 Startup.cs?
中添加或更改某些内容
它的价值:我知道基本身份验证并不是很安全。但就我的需要而言,这完全没问题。无论如何,我想绕过复杂的策略、OAuth 等
有人知道我需要做什么吗?
Now I published my application to my production server (IIS). In Postman, I replaced "localhost:44360" by my real production domain.
My problem: Sending the request to my production server returns a 401 (and a whole ASP.NET Core default error page).
尝试检查 IIS 是否有基本身份验证或 Windows authentication.If 所以,在 IIS 中禁用它们并重试。
我有一个 .NET 6.0 网络应用程序,它使用基于 Cookie 的用户身份验证。
今天我想添加一个 API 具有非常简单的 BASIC AUTHENTICATION 机制的控制器。
这是我的控制器:
public class DemaController : Controller
{
[HttpGet("test")]
[BasicAuthentication(username: "test", password: "abc")]
public bool Test()
{
return true;
}
}
这是我超级简单的基本身份验证属性:
public class BasicAuthenticationAttribute : Attribute, IAuthorizationFilter
{
private readonly string _username;
private readonly string _password;
public BasicAuthenticationAttribute(string username, string password)
{
_username = username;
_password = password;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
try
{
var authorizationHeader = context.HttpContext.Request.Headers["Authorization"];
(string username, string password) = this.GetUsernameAndPassword(authorizationHeader: authorizationHeader);
if (username != null && password != null)
{
if (username == _username && password == _password)
return; // Grant access
}
}
catch (FormatException)
{
}
context.Result = new UnauthorizedResult();
}
static System.Text.Encoding ISO_8859_1_ENCODING = System.Text.Encoding.GetEncoding("ISO-8859-1");
private (string, string) GetUsernameAndPassword(string authorizationHeader)
{
if (authorizationHeader == null || !authorizationHeader.Contains("Basic "))
return (null, null);
string encodedUsernamePassword = authorizationHeader.Substring("Basic ".Length).Trim();
string usernamePassword = ISO_8859_1_ENCODING.GetString(Convert.FromBase64String(encodedUsernamePassword));
string username = usernamePassword.Split(':')[0];
string password = usernamePassword.Split(':')[1];
return (username, password);
}
}
当我 运行 本地计算机上的应用程序 (Visual Studio 2022 + IIS Express) 并使用 Postman 访问 Api 时一切正常。正如预期的那样,响应为“true”。
这是我喂邮递员的方式:
- 获取 https://localhost:44360/test
- 授权类型:基本授权
- 用户名:test
- 密码:abc
所以我的自定义 BasicAuthenticationAttribute 似乎有效。我可以设置断点(被击中)和对 Postman 凭据的任何更改 returns Http-401 错误。
到目前为止一切顺利。
现在我将我的应用程序发布到我的生产服务器 (IIS)。在 Postman 中,我将“localhost:44360”替换为我的实际生产域。
我的问题:将请求发送到我的生产服务器 returns 一个 401(以及整个 ASP.NET 核心默认错误页面)。
我更进一步,在我的服务器上设置了 MS Visual Studio 远程调试器。然后我在我的自定义 BasicAuthenticationAttribute 中设置了一个断点。永远不会命中断点。换句话说:401 不是来自我的属性内部。似乎我的 BasicAuthenticationAttribute 在我的服务器上根本没有被触及(但它肯定在我的开发机器上被触及,如前所述)。
让我猜猜:我需要在 Startup.cs?
中添加或更改某些内容它的价值:我知道基本身份验证并不是很安全。但就我的需要而言,这完全没问题。无论如何,我想绕过复杂的策略、OAuth 等
有人知道我需要做什么吗?
Now I published my application to my production server (IIS). In Postman, I replaced "localhost:44360" by my real production domain.
My problem: Sending the request to my production server returns a 401 (and a whole ASP.NET Core default error page).
尝试检查 IIS 是否有基本身份验证或 Windows authentication.If 所以,在 IIS 中禁用它们并重试。