错误代码500&无法取消对邮件的保护。重定向至标识服务器4中的客户端时 [英] Error code 500 "Unable to unprotect the message.State" when redirecting to Client in IdentityServer4
本文介绍了错误代码500&无法取消对邮件的保护。重定向至标识服务器4中的客户端时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在使用IdentityServer4并尝试手动验证我的ASP.NET Core 3.1客户端(手动创建请求以了解流)。 这是我的客户登录:
[HttpGet]
public IActionResult ManualLogin()
{
var myNonce = Guid.NewGuid().ToString();
var myState = Guid.NewGuid().ToString();
var req = "https://localhost:5000/connect/authorize?" +
"client_id=mvc" +
"&redirect_uri=https://localhost:44381/signin-oidc" +
"&response_type=code id_token" +
"&scope=openid profile offline_access email" +
"&response_mode=form_post" +
$"&nonce={myNonce}" +
$"&state={myState}";
return Redirect(req);
}
此登录方法运行良好,一切正常,但我不想使用它:
//[HttpGet]
//public async Task LoginAsync()
//{
// await HttpContext.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties
// {
// RedirectUri = "https://localhost:44381/Home/external-login-callback"
// });
// }
我的客户的启动.cs:
public void ConfigureServices(IServiceCollection services)
{
// for using IHttpClientFactory
services.AddHttpClient();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
// adding Authentication services to DependencyInjection
services.AddAuthentication(config =>
{
config.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
config.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, config =>
{
config.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
config.Authority = "https://localhost:5000";
config.ClientId = "mvc";
config.ClientSecret = "secret";
config.SaveTokens = true;
config.UseTokenLifetime = false;
// Hybrid Flow
config.ResponseType = "code id_token";
config.Scope.Add("openid");
config.Scope.Add("offline_access");
config.Scope.Add("profile");
config.Scope.Add("email");
config.GetClaimsFromUserInfoEndpoint = true;
config.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = JwtClaimTypes.GivenName,
RoleClaimType = JwtClaimTypes.Role,
};
// config.AuthenticationMethod = OpenIdConnectRedirectBehavior.FormPost;
});
services.AddControllersWithViews();
}
我的客户定义:
new Client
{
ClientId = "mvc",
ClientName ="My mvc client testing",
ClientSecrets = { new Secret("secret".Sha256()) },
AllowedGrantTypes = GrantTypes.Hybrid,
// where to redirect to after login
RedirectUris = { "https://localhost:44381/signin-oidc" },
// where to redirect to after logout
PostLogoutRedirectUris = { "https://localhost:44381/signout-callback-oidc" },
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
},
AllowOfflineAccess = true,
UpdateAccessTokenClaimsOnRefresh = true,
AccessTokenType = AccessTokenType.Reference,
RequireConsent = false,
RequireClientSecret = true,
//AlwaysIncludeUserClaimsInIdToken = true,
RequirePkce = false,
}
我的IS4的启动.cs:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
var builder = services.AddIdentityServer()
.AddInMemoryIdentityResources(Config.IdentityResources)
.AddInMemoryApiScopes(Config.ApiScopes)
.AddInMemoryClients(Config.Clients)
.AddTestUsers(TestUsers.Users);
builder.AddDeveloperSigningCredential();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseRouting();
app.UseIdentityServer();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
}
客户端重定向成功到IS4登录页面,然后我就可以对用户进行身份验证了,当重定向回我客户端上的signin-oidc
url时,我得到了500 Internal Server Error
:
Unable to unprotect the message.State.
Exception: Unable to unprotect the message.State.
Unknown location
Exception: An error was encountered while handling the remote login.
Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler<TOptions>.HandleRequestAsync()
Exception: An error was encountered while handling the remote login.
Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler<TOptions>.HandleRequestAsync()
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
我没有多个oidc,只有一个!我错过了什么?
更新1:在@ToreNestenius评论之后:
我将请求的reDirect_uri更改为:
&redirect_uri=https://localhost:44381/home/MyCallback"
并将回调添加到IS4客户端的配置中,然后是我的回调:
[HttpPost]
[ActionName("mycallback")]
public async Task mycallbackAsync(
string code,
string scope,
string state,
string session_state,
string login_required)
{
var theRequest = $"https://localhost:5000/connect/token";
var client = _httpClientFactory.CreateClient();
var theContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string,string>("client_id","mvc"),
new KeyValuePair<string,string>("client_secret","secret"),
new KeyValuePair<string,string>("grant_type","hybrid"),
new KeyValuePair<string,string>("code",code),
new KeyValuePair<string,string>("redirect_uri", "https://localhost:5002/home/mycallback"),
});
theContent.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
var base64StringUserPass = Convert.ToBase64String(Encoding.ASCII.GetBytes($"mvc:secret"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", base64StringUserPass);
var response = await client.PostAsync(req, theContent);
if (!response.IsSuccessStatusCode)
{
Console.WriteLine(response.StatusCode);
return;
}
var content = await response.Content.ReadAsStringAsync();
var theAccessToken = JsonConvert.DeserializeObject<Token>(content);
// -----------------------------
// get user info
//var access_token = theAccessToken.access_token;
//string userInfo = await getUserInfoAsync(access_token);
}
现在我可以正确地处理回调,然后发出一个accesToken并获取userInfo。
推荐答案
您在代码中使用
"&redirect_uri=https://localhost:44381/signin-oidc" +
这意味着您正在尝试重定向回客户端中的OpenIDConnect身份验证处理程序/方案。但是它期望传入的请求包含它无法识别的状态和随机数值。因为初始身份验证请求不是来自该处理程序。
因为您希望学习OpenID-Connect并手动完成(就像我学习它时一样)。我建议您将redirectURI更改为您自己的控制器中的一个操作方法。像https://localhost:44381/test/callback";
一样我建议您在了解完整的手动流程之前,避免使用OpenIDConnect处理程序。
回调方法签名应如下所示:
/// <summary>
/// This method is called with the authorization code and state parameter
/// </summary>
/// <param name="code">authorization code generated by the authorization server. This code is relatively short-lived, typically lasting between 1 to 10 minutes depending on the OAuth service.</param>
/// <param name="state"></param>
/// <returns></returns>
[HttpPost]
public IActionResult Callback(string code, string state)
{
//To be secure then the state parameter should be compared
to the state sent in the previous step
var url = new Url(_openIdSettings.token_endpoint);
//Get the tokens based on the code, using https://flurl.dev/docs/fluent-http/
var token = url.PostUrlEncodedAsync(new
{
client_id = "authcodeflowclient",
client_secret = "mysecret",
grant_type = "authorization_code",
code_verifier = code_verifier,
code = code,
redirect_uri = "https://localhost:5001/CodeFlow/callback"
}).ReceiveJson<Token>().Result;
return View(token);
}
这篇关于错误代码500&无法取消对邮件的保护。重定向至标识服务器4中的客户端时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文