gpt4 book ai didi

c# - Microsoft.AspNetCore.Authorization.DefaultAuthorizationService - 授权失败

转载 作者:行者123 更新时间:2023-12-02 03:04:49 29 4
gpt4 key购买 nike

我有什么:

我必须开发去年开发的网络应用程序,而不是我自己开发的。它由 Web 服务后端和 Web 应用程序前端组成。后端用 C# 7 编写,在 .NET Core 2.1 运行时上运行并使用 ASP.NET Core MVC 框架。前端是一个用 HTML 5、CSS3、TypeScript 和 React 编写的 Web 应用程序。

我想要什么:

我想在我的电脑上设置一个开发环境(使用 Windows 10 作为操作系统)。

我做了什么:

我运行了 webpack-dev-server 来为前端提供服务 http://localhost:8080 。然后我在 Visual Studio 中使用 ASP.NET Core 运行后端,以提供 http://localhost:44311 处的 Web 服务。 。然后我到达主页中的登录表单http://localhost:8080

问题:

在登录阶段,我收到以下错误(我使用有效的用户和密码):

Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action method MyProject.Controllers.AuthenticationController.Login (MyProject), returned result Microsoft.AspNetCore.Mvc.OkResult in 549.6866ms.
Microsoft.AspNetCore.Mvc.StatusCodeResult:Information: Executing HttpStatusCodeResult, setting HTTP status code 200
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action MyProject.Controllers.AuthenticationController.Login (MyProject) in 620.9287ms
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 634.4833ms 200
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 OPTIONS http://localhost:44311/Authentication/GetUser
Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: Policy execution successful.
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 2.9016ms 204
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:44311/Authentication/GetUser application/json
Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: Policy execution successful.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Route matched with {action = "GetUser", controller = "Authentication"}. Executing controller action with signature Microsoft.AspNetCore.Mvc.IActionResult GetUser() on controller MyProject.Controllers.AuthenticationController (MyProject).
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization failed.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
Microsoft.AspNetCore.Mvc.ChallengeResult:Information: Executing ChallengeResult with authentication schemes (Cookies).
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler:Information: AuthenticationScheme: Cookies was challenged.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action MyProject.Controllers.AuthenticationController.GetUser (MyProject) in 25.582ms
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 33.6489ms 302
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 OPTIONS http://localhost:44311/Account/Login?ReturnUrl=%2FAuthentication%2FGetUser
Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: Policy execution successful.
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 3.2166ms 204
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:44311/Account/Login?ReturnUrl=%2FAuthentication%2FGetUser application/json
Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: Policy execution successful.
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 2.7855ms 404

这是我的Startup.cs:

    public class Startup
{
private readonly IHostingEnvironment _env;
private readonly IConfiguration _config;

public Startup(IHostingEnvironment env, IConfiguration config)
{
_env = env;
_config = config;
}

public void ConfigureServices(IServiceCollection services)
{
JwtConfiguration jwtConfiguration = _config.GetSection("JwtConfiguration").Get<JwtConfiguration>();
CustomJwtDataFormat jwtDataFormat = CustomJwtDataFormat.Create(jwtConfiguration);

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSingleton<IConfiguration>(_config);
services.AddSingleton<IEmailConfiguration>(_config.GetSection("EmailConfiguration").Get<EmailConfiguration>());
services.AddSingleton(new LogService(_config.GetSection("AzureLogConfiguration").Get<AzureLogConfiguration>()));
services.AddSingleton(jwtDataFormat);
services.AddAuthentication().AddCookie(options => {
options.Cookie.Name = AuthenticationCookie.COOKIE_NAME;
options.TicketDataFormat = jwtDataFormat;
});

Database.ConnectionString = _config["ConnectionStrings:PostgresDatabase"];
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder.SetBasePath(env.ContentRootPath);
configurationBuilder.AddJsonFile("appsettings.json", false, true);

if (env.IsDevelopment()) {
app.UseCors(
builder => builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
);
app.UseDeveloperExceptionPage();
configurationBuilder.AddUserSecrets<Startup>();
}
else {
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc(routes => {
routes.MapRoute(name: "default", template: "{controller=Site}/{action=Index}");
});
}
}

AuthenticationController.cs(用于在登录阶段对用户进行身份验证):

    public class AuthenticationController : Controller
{
private readonly IEmailConfiguration _emailConfiguration;
private readonly LogService _logService;
private readonly CustomJwtDataFormat _jwt;

public AuthenticationController(IEmailConfiguration emailConfiguration, LogService logService, CustomJwtDataFormat jwt)
{
_emailConfiguration = emailConfiguration;
_logService = logService;
_jwt = jwt;
}

[AllowAnonymous]
public IActionResult Login([FromBody] LoginNto loginNto)
{
string requestString = string.Format("Username: '{0}', Type: '{1}'", loginNto.Email, loginNto.Type);
try
{
var requestType = ToLoginType(loginNto.Type);
var userType = UsersMapper.GetUserType(loginNto.Email, loginNto.Pass);
if (userType != requestType)
throw new UnauthorizedAccessException();
AuthenticationCookie.CreateAndAddToResponse(HttpContext, loginNto.Email, _jwt);
_logService.RequestResponse("[Authentication/Login]", HttpContext.Connection.RemoteIpAddress, null, requestString, Ok().StatusCode);
return Ok();
}
catch (UnauthorizedAccessException e)
{
_logService.RequestResponse("[Authentication/Login]", HttpContext.Connection.RemoteIpAddress, null, requestString, Unauthorized().StatusCode, e);
return Unauthorized();
}
catch (Exception e)
{
_logService.RequestResponse("[Authentication/Login]", HttpContext.Connection.RemoteIpAddress, null, requestString, 500, e);
return StatusCode(500);
}
}

[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
public IActionResult GetUser()
{
try
{
User user = UsersMapper.Get(AuthenticationCookie.GetAuthenticatedUserEmail(HttpContext, _jwt));
_logService.RequestResponse("[Authentication/GetUser]", HttpContext.Connection.RemoteIpAddress, AuthenticationCookie.GetAuthenticatedUserEmail(HttpContext, _jwt), null, Ok().StatusCode);
return Ok(Json(user.ForNet()));
}
catch (UnauthorizedAccessException e)
{
_logService.RequestResponse("[Authentication/GetUser]", HttpContext.Connection.RemoteIpAddress, AuthenticationCookie.GetAuthenticatedUserEmail(HttpContext, _jwt), null, Unauthorized().StatusCode, e);
return Unauthorized();
}
catch (Exception e)
{
_logService.RequestResponse("[Authentication/GetUser]", HttpContext.Connection.RemoteIpAddress, AuthenticationCookie.GetAuthenticatedUserEmail(HttpContext, _jwt), null, 500, e);
return StatusCode(500);
}
}
}

AuthenticationCookie.cs(用于管理 JWT cookie...我认为...):

    public class AuthenticationCookie
{
public const string COOKIE_NAME = "authentication_cookie";

public static void CreateAndAddToResponse(HttpContext httpContext, string email, CustomJwtDataFormat jwtDataFormat) {
httpContext.Response.Cookies.Append(COOKIE_NAME, jwtDataFormat.GenerateToken(email));
}

public static string GetAuthenticatedUserEmail(HttpContext httpContext, CustomJwtDataFormat jwt) {
var tokenValue = httpContext.Request.Cookies[COOKIE_NAME];
var authenticationTicket = jwt.Unprotect(tokenValue);
return authenticationTicket.Principal.Claims.First().Value;
}

public static void Delete(HttpContext httpContext) {
httpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}
}

最佳答案

原因

根本原因是您没有在 UseMvc() 之前添加 UseAuthentication() :

    app.UseAuthentication();     // MUST Add this line before UseMvc()    app.UseMvc(routes => {...});    
As a result, ASP.NET Core won't create a User Principal for user even he has already signed in. And then you got a message of :

Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization failed.

Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.

Microsoft.AspNetCore.Mvc.ChallengeResult:Information: Executing ChallengeResult with authentication schemes (Cookies).

Since you didn't configure the Login Path for cookie:

services.AddAuthentication().AddCookie(options => {
options.Cookie.Name = AuthenticationCookie.COOKIE_NAME;
options.TicketDataFormat = jwtDataFormat;
});

因此它使用默认的,即/Account/Login。但是您没有这样的 AccountControllerLogin 操作方法,您会得到 404 响应:

Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:44311/Account/Login?ReturnUrl=%2FAuthentication%2FGetUser application/json

Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: Policy execution successful.

Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 2.7855ms 404

如何修复

  1. UseMvc() 之前添加 UseAuthentication() :
    app.UseAuthentication();  // MUST add this line before UseMvc()
    app.UseMvc(routes => {...});
  2. 创建一个 Controller / View 供用户登录(如果您没有)。然后告诉 ASP.NET Core 如何在 Startup 中重定向用户:

    services.AddAuthentication().AddCookie(options => {
    options.Cookie.Name = AuthenticationCookie.COOKIE_NAME;
    options.TicketDataFormat = jwtDataFormat;
    options.LoginPath= "/the-path-to-login-in"; // change this line
    });

[编辑]

  1. 您的 Login([FromBody] LoginNto loginNto) 方法接受 HttpGet 请求,但期望获取正文。 HTTP Get 根本没有主体。您需要将其更改为 HttpPost:

    [HttpPost]
    [AllowAnonymous]
    public async Task<IActionResult> Login([FromBody] LoginNto loginNto)
    {
    ...
    }
  2. 用户登录的方式似乎不正确。更改您的 Login() 方法以发送标准 cookie,如下所示:

    [HttpPost]
    [AllowAnonymous]
    public async Task<IActionResult> Login([FromBody] LoginNto loginNto)
    {
    string requestString = string.Format("Username: '{0}', Type: '{1}'", loginNto.Email, loginNto.Type);
    try
    {
    ...
    if (userType != requestType)
    throw new UnauthorizedAccessException();
    //AuthenticationCookie.CreateAndAddToResponse(HttpContext, loginNto.Email, _jwt);
    await SignInAsync(loginNto.Email, _jwt);
    ...
    return Ok();
    }
    ...

    }
    async Task SignInAsync(string email, CustomJwtDataFormat jwtDataFormat){
    var schemeName = CookieAuthenticationDefaults.AuthenticationScheme;
    var claims = new List<Claim>(){
    new Claim(ClaimTypes.NameIdentifier, email),
    new Claim(ClaimTypes.Name, email),
    new Claim(ClaimTypes.Email, email),
    // ... other claims according to the jwtDataFormat
    };
    var id = new ClaimsIdentity(claims, schemeName);
    var principal = new ClaimsPrincipal(id);
    // send credential cookie using the standard
    await HttpContext.SignInAsync(schemeName,principal);
    }
  3. GetUser 也可以简化:

    [Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
    public IActionResult GetUser()
    {
    var email = HttpContext.User.FindFirstValue(ClaimTypes.Email);
    User user = UsersMapper.Get(AuthenticationCookie.GetAuthenticatedUserEmail(HttpContext, _jwt));
    _logService.RequestResponse("[Authentication/GetUser]", HttpContext.Connection.RemoteIpAddress, AuthenticationCookie.GetAuthenticatedUserEmail(HttpContext, _jwt), null, Ok().StatusCode);
    var payload= new {
    Email = email,
    // ... other claims that're kept in cookie
    };
    // return Ok(Json(user.ForNet()));
    return Json(payload);
    }

关于c# - Microsoft.AspNetCore.Authorization.DefaultAuthorizationService - 授权失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59271983/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com