适当的事件处理程序在有未经授权的请求时更改响应
Proper event handler to alter the responses when there is unauthorized request
当 Unauthorized
向 api 发出请求时,我试图 return 自定义错误响应消息。我已经尝试了几个事件处理程序来改变响应,但其中 none 似乎适用于我的情况。
什么是正确的 openiddict
事件处理程序来在存在未经授权的请求时更改响应?
到目前为止我尝试了什么。
public class CustomAuthorizationHandler : IOpenIddictServerEventHandler<OpenIddictServerEvents.ApplyTokenResponse>
{
public Task HandleAsync(OpenIddictServerEvents.ApplyTokenResponse notification, CancellationToken cancellationToken)
{
}
}
public class CustomAuthorizationResponseHandler : IOpenIddictServerEventHandler<OpenIddictServerEvents.ApplyAuthorizationResponse>
{
public Task HandleAsync(OpenIddictServerEvents.ApplyAuthorizationResponse notification, CancellationToken cancellationToken)
{
}
}
public class CustomValidateAuthorizationRequestHandler : IOpenIddictServerEventHandler<OpenIddictServerEvents.HandleAuthorizationRequest>
{
public Task HandleAsync(OpenIddictServerEvents.HandleAuthorizationRequest notification, CancellationToken cancellationToken)
{
}
}
在Startup.cs
中添加服务器
services.AddOpenIddict().AddCore(options =>
{
options.UseEntityFrameworkCore()
.UseDbContext<AWSContext>()
.ReplaceDefaultEntities<Guid>();
}).AddServer(options =>
{
options.UseMvc();
options.EnableAuthorizationEndpoint("/connect/authorize")
.EnableTokenEndpoint("/connect/token")
.EnableLogoutEndpoint("/connect/logout")
.EnableIntrospectionEndpoint("/connect/introspect")
.EnableUserinfoEndpoint("/api/userinfo");
options.AllowClientCredentialsFlow();
options.RegisterScopes(OpenIdConnectConstants.Scopes.Email,
OpenIdConnectConstants.Scopes.Profile,
OpenIddictConstants.Scopes.Roles);
options.AddEphemeralSigningKey();
options.AllowImplicitFlow();
options.DisableHttpsRequirement();
options.AddEventHandler<OpenIddictServerEvents.ApplyTokenResponse, CustomAuthorizationHandler>();
options.AddEventHandler<OpenIddictServerEvents.ApplyAuthorizationResponse, CustomAuthorizationResponseHandler>();
options.AddEventHandler<OpenIddictServerEvents.HandleAuthorizationRequest, CustomValidateAuthorizationRequestHandler>();
//options.AddDevelopmentSigningCertificate();
options.UseJsonWebTokens();
});//.AddValidation();
控制器
[HttpGet("~/home/message")]
[Authorize(AuthenticationSchemes = OpenIddictValidationDefaults.AuthenticationScheme)]
public async Task<IActionResult> GetMessage()
{
var subject = User.FindFirst(OpenIdConnectConstants.Claims.Subject)?.Value;
if (string.IsNullOrEmpty(subject))
{
return BadRequest();
}
var application = await _applicationManager.FindByClientIdAsync(subject, HttpContext.RequestAborted);
if (application == null)
{
return BadRequest();
}
return Content($"{application.DisplayName} has been successfully authenticated.");
}
邮递员收到 401 错误:
如果使用 AddJwtBearer
自定义响应错误,则只是一个代码示例:
services.AddAuthentication("myschema")
.AddJwtBearer("myschema", options =>
{
options.Authority = "http://localhost:54540/";
options.Audience = "resource_server";
options.RequireHttpsMetadata = false;
options.Events = new JwtBearerEvents();
options.Events.OnChallenge = context =>
{
// Skip the default logic.
context.HandleResponse();
if (string.IsNullOrEmpty(context.HttpContext.Request.Headers["Authorization"]))
{
var payload = new JObject
{
["error"] = "No token",
["error_description"] = "No token",
};
return context.Response.WriteAsync(payload.ToString());
}
else
{
var payload = new JObject
{
["error"] = context.Error,
["error_description"] = context.ErrorDescription,
["error_uri"] = context.ErrorUri
};
return context.Response.WriteAsync(payload.ToString());
}
};
});
并在您的行动中应用:
[Authorize(AuthenticationSchemes = "myschema")]
[HttpGet("message")]
public async Task<IActionResult> GetMessage()
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
return BadRequest();
}
return Content($"{user.UserName} has been successfully authenticated.");
}
当 Unauthorized
向 api 发出请求时,我试图 return 自定义错误响应消息。我已经尝试了几个事件处理程序来改变响应,但其中 none 似乎适用于我的情况。
什么是正确的 openiddict
事件处理程序来在存在未经授权的请求时更改响应?
到目前为止我尝试了什么。
public class CustomAuthorizationHandler : IOpenIddictServerEventHandler<OpenIddictServerEvents.ApplyTokenResponse>
{
public Task HandleAsync(OpenIddictServerEvents.ApplyTokenResponse notification, CancellationToken cancellationToken)
{
}
}
public class CustomAuthorizationResponseHandler : IOpenIddictServerEventHandler<OpenIddictServerEvents.ApplyAuthorizationResponse>
{
public Task HandleAsync(OpenIddictServerEvents.ApplyAuthorizationResponse notification, CancellationToken cancellationToken)
{
}
}
public class CustomValidateAuthorizationRequestHandler : IOpenIddictServerEventHandler<OpenIddictServerEvents.HandleAuthorizationRequest>
{
public Task HandleAsync(OpenIddictServerEvents.HandleAuthorizationRequest notification, CancellationToken cancellationToken)
{
}
}
在Startup.cs
中添加服务器 services.AddOpenIddict().AddCore(options =>
{
options.UseEntityFrameworkCore()
.UseDbContext<AWSContext>()
.ReplaceDefaultEntities<Guid>();
}).AddServer(options =>
{
options.UseMvc();
options.EnableAuthorizationEndpoint("/connect/authorize")
.EnableTokenEndpoint("/connect/token")
.EnableLogoutEndpoint("/connect/logout")
.EnableIntrospectionEndpoint("/connect/introspect")
.EnableUserinfoEndpoint("/api/userinfo");
options.AllowClientCredentialsFlow();
options.RegisterScopes(OpenIdConnectConstants.Scopes.Email,
OpenIdConnectConstants.Scopes.Profile,
OpenIddictConstants.Scopes.Roles);
options.AddEphemeralSigningKey();
options.AllowImplicitFlow();
options.DisableHttpsRequirement();
options.AddEventHandler<OpenIddictServerEvents.ApplyTokenResponse, CustomAuthorizationHandler>();
options.AddEventHandler<OpenIddictServerEvents.ApplyAuthorizationResponse, CustomAuthorizationResponseHandler>();
options.AddEventHandler<OpenIddictServerEvents.HandleAuthorizationRequest, CustomValidateAuthorizationRequestHandler>();
//options.AddDevelopmentSigningCertificate();
options.UseJsonWebTokens();
});//.AddValidation();
控制器
[HttpGet("~/home/message")]
[Authorize(AuthenticationSchemes = OpenIddictValidationDefaults.AuthenticationScheme)]
public async Task<IActionResult> GetMessage()
{
var subject = User.FindFirst(OpenIdConnectConstants.Claims.Subject)?.Value;
if (string.IsNullOrEmpty(subject))
{
return BadRequest();
}
var application = await _applicationManager.FindByClientIdAsync(subject, HttpContext.RequestAborted);
if (application == null)
{
return BadRequest();
}
return Content($"{application.DisplayName} has been successfully authenticated.");
}
邮递员收到 401 错误:
如果使用 AddJwtBearer
自定义响应错误,则只是一个代码示例:
services.AddAuthentication("myschema")
.AddJwtBearer("myschema", options =>
{
options.Authority = "http://localhost:54540/";
options.Audience = "resource_server";
options.RequireHttpsMetadata = false;
options.Events = new JwtBearerEvents();
options.Events.OnChallenge = context =>
{
// Skip the default logic.
context.HandleResponse();
if (string.IsNullOrEmpty(context.HttpContext.Request.Headers["Authorization"]))
{
var payload = new JObject
{
["error"] = "No token",
["error_description"] = "No token",
};
return context.Response.WriteAsync(payload.ToString());
}
else
{
var payload = new JObject
{
["error"] = context.Error,
["error_description"] = context.ErrorDescription,
["error_uri"] = context.ErrorUri
};
return context.Response.WriteAsync(payload.ToString());
}
};
});
并在您的行动中应用:
[Authorize(AuthenticationSchemes = "myschema")]
[HttpGet("message")]
public async Task<IActionResult> GetMessage()
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
return BadRequest();
}
return Content($"{user.UserName} has been successfully authenticated.");
}