Asp POST 不允许网络核心错误 405 方法
Asp net core Error 405 method not allowed on POST
我有一个使用 .NET 5 开发的 asp 网络核心应用程序。
在此应用程序中,有一个控制器 (ACSController) 管理来自身份提供者的响应。 控制器 是以下:
public class ACSController : Controller
{
private readonly IRequestRepository _requestRepository;
private readonly IHttpClientFactory _httpClientFactory;
private readonly IIdpRepository _idpRepository;
private readonly IResponseRepository _responseRepository;
private readonly AppSessionViewModel _session;
public ACSController(IRequestRepository requestRepository, IHttpClientFactory httpClientFactory,
IIdpRepository idpRepository, IResponseRepository responseRepository, AppSessionViewModel session)
{
_requestRepository = requestRepository;
_httpClientFactory = httpClientFactory;
_idpRepository = idpRepository;
_responseRepository = responseRepository;
_session = session;
}
[HttpPost]
public async Task<IActionResult> IndexAsync(IFormCollection form)
{
var base64Response = form["SAMLResponse"].ToString();
var response = SAMLHelper.GetAuthnResponse(base64Response);
var cachedRequest = _requestRepository.Read();
var idpMetadata = await SamlHandler.DownloadIdPMetadata(_httpClientFactory,
_idpRepository.Read().OrganizationUrlMetadata);
var validationResult = ResponseValidator.ValidateAuthnResponse(response, cachedRequest, idpMetadata);
if (validationResult.IsSuccess)
{
_responseRepository.Write(response);
_session.Logged = true;
ViewData["UserInfo"] = CreateUserInfo(response);
return View();
}
else
{
ViewData["Message"] = validationResult.Error;
return View("Error");
}
}
[HttpPost]
public IActionResult Logout(IFormCollection form)
{
var base64Response = form["SAMLResponse"].ToString();
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
#region Utilities
private Dictionary<string, string> CreateUserInfo(AuthnResponse response)
{
if (response == null) throw new ArgumentException(nameof(response));
var attributes = response.GetAssertion().GetAttributeStatement().Items;
var userDictionary = new Dictionary<string, string>();
foreach (var attribute in attributes)
{
var attr = (AttributeType)attribute;
userDictionary.Add(attr.Name, (string)attr.AttributeValue.First());
}
return userDictionary;
}
#endregion
}
在我的例子中,当 POST 请求调用 acs/index 方法时没有问题。
当我(从另一个控制器)调用注销过程时,我的应用程序正确发送了请求,但是当 IdP 响应我时,我在浏览器上获得了这个响应:
https:///acs/logout?SAMLResponse=fVLBSsNAEL0L%2FYeS%2Bya72b … 出现 405 错误。
这是我的 Startup.cs :
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddSingleton<IRequestRepository, RequestRepository>();
services.AddSingleton<IIdpRepository, IdpRepository>();
services.AddSingleton<IResponseRepository, ResponseRepository>();
services.AddSingleton<AppSessionViewModel>();
services.AddHttpClient();
services.Configure<Spid>(Configuration.GetSection("Spid"));
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
//app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
//app.UseSession();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
这是我的 launchSettings.json(我使用 SPID_Test 作为网络浏览器):
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:15378",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
"SPID_Test": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Production"
},
"dotnetRunMessages": "true",
"applicationUrl": "http://localhost:5000"
}
尝试将[HttpPost]
改为[HttpGet]
,然后将IFormCollection form
改为string SAMLResponse
。Model binding默认从Query字符串参数中获取数据,所以可以通过 default.Here 将 string SAMLResponse
与 SAMLResponse=xxx
绑定是一个演示:
[HttpGet]
public IActionResult Logout(string SAMLResponse)
{
var base64Response = SAMLResponse;
return View();
}
结果:
更新:
如果你想解码一个base64字符串,尝试使用:
byte[] data = Convert.FromBase64String(SAMLResponse);
string decodedString = Encoding.UTF8.GetString(data);
我有一个使用 .NET 5 开发的 asp 网络核心应用程序。
在此应用程序中,有一个控制器 (ACSController) 管理来自身份提供者的响应。 控制器 是以下:
public class ACSController : Controller
{
private readonly IRequestRepository _requestRepository;
private readonly IHttpClientFactory _httpClientFactory;
private readonly IIdpRepository _idpRepository;
private readonly IResponseRepository _responseRepository;
private readonly AppSessionViewModel _session;
public ACSController(IRequestRepository requestRepository, IHttpClientFactory httpClientFactory,
IIdpRepository idpRepository, IResponseRepository responseRepository, AppSessionViewModel session)
{
_requestRepository = requestRepository;
_httpClientFactory = httpClientFactory;
_idpRepository = idpRepository;
_responseRepository = responseRepository;
_session = session;
}
[HttpPost]
public async Task<IActionResult> IndexAsync(IFormCollection form)
{
var base64Response = form["SAMLResponse"].ToString();
var response = SAMLHelper.GetAuthnResponse(base64Response);
var cachedRequest = _requestRepository.Read();
var idpMetadata = await SamlHandler.DownloadIdPMetadata(_httpClientFactory,
_idpRepository.Read().OrganizationUrlMetadata);
var validationResult = ResponseValidator.ValidateAuthnResponse(response, cachedRequest, idpMetadata);
if (validationResult.IsSuccess)
{
_responseRepository.Write(response);
_session.Logged = true;
ViewData["UserInfo"] = CreateUserInfo(response);
return View();
}
else
{
ViewData["Message"] = validationResult.Error;
return View("Error");
}
}
[HttpPost]
public IActionResult Logout(IFormCollection form)
{
var base64Response = form["SAMLResponse"].ToString();
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
#region Utilities
private Dictionary<string, string> CreateUserInfo(AuthnResponse response)
{
if (response == null) throw new ArgumentException(nameof(response));
var attributes = response.GetAssertion().GetAttributeStatement().Items;
var userDictionary = new Dictionary<string, string>();
foreach (var attribute in attributes)
{
var attr = (AttributeType)attribute;
userDictionary.Add(attr.Name, (string)attr.AttributeValue.First());
}
return userDictionary;
}
#endregion
}
在我的例子中,当 POST 请求调用 acs/index 方法时没有问题。
当我(从另一个控制器)调用注销过程时,我的应用程序正确发送了请求,但是当 IdP 响应我时,我在浏览器上获得了这个响应: https:///acs/logout?SAMLResponse=fVLBSsNAEL0L%2FYeS%2Bya72b … 出现 405 错误。
这是我的 Startup.cs :
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddSingleton<IRequestRepository, RequestRepository>();
services.AddSingleton<IIdpRepository, IdpRepository>();
services.AddSingleton<IResponseRepository, ResponseRepository>();
services.AddSingleton<AppSessionViewModel>();
services.AddHttpClient();
services.Configure<Spid>(Configuration.GetSection("Spid"));
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
//app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
//app.UseSession();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
这是我的 launchSettings.json(我使用 SPID_Test 作为网络浏览器):
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:15378",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
"SPID_Test": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Production"
},
"dotnetRunMessages": "true",
"applicationUrl": "http://localhost:5000"
}
尝试将[HttpPost]
改为[HttpGet]
,然后将IFormCollection form
改为string SAMLResponse
。Model binding默认从Query字符串参数中获取数据,所以可以通过 default.Here 将 string SAMLResponse
与 SAMLResponse=xxx
绑定是一个演示:
[HttpGet]
public IActionResult Logout(string SAMLResponse)
{
var base64Response = SAMLResponse;
return View();
}
结果:
更新:
如果你想解码一个base64字符串,尝试使用:
byte[] data = Convert.FromBase64String(SAMLResponse);
string decodedString = Encoding.UTF8.GetString(data);