OpenID Connect/OAuth2 server framework for OWIN/Katana and ASP.NET Core
ValidateAuthorizationRequest
and remove options.ApplicationCanDisplayErrors = true
.
await this._next(context);
var openIdConnectResponse = context.GetOpenIdConnectResponse();
if (openIdConnectResponse != null && !string.IsNullOrEmpty(openIdConnectResponse.Error) && !string.IsNullOrEmpty(openIdConnectResponse.ErrorDescription))
{
if (!context.Response.HasStarted)
{
context.Response.Headers.Clear();
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
var result = JsonConvert.SerializeObject(new Infrastructure.Utils.HttpClient.GenericResponse<string>()
{
Exception = openIdConnectResponse.ErrorDescription ?? openIdConnectResponse.Error,
StatusCode = HttpStatusCode.BadRequest
});
this._logger.LogError("The openIdConnect error with path" + context.Request.Path + ", ##IP:" + context.Connection.RemoteIpAddress + "## result: " + result);
await context.Response.WriteAsync(result);
return;
}
}
if (string.IsNullOrEmpty(clientId))
{
//context.HttpContext.Response.
context.Reject(error: OpenIdConnectConstants.Errors.InvalidClient,
description: "client id cannot be null");
return;
}
[18:05:10 Error] AspNet.Security.OAuth.Apple.Internal.DefaultAppleClientSecretGenerator
Failed to generate new client secret for the Apple authentication scheme.
Interop+Crypto+OpenSslCryptographicException: error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error
at Internal.Cryptography.Pal.CertificatePal.FromBlob(Byte[] rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
at AspNet.Security.OAuth.Apple.Internal.DefaultAppleClientSecretGenerator.CreateAlgorithmLinuxOrMac(Byte[] keyBlob, String password)
at AspNet.Security.OAuth.Apple.Internal.DefaultAppleClientSecretGenerator.CreateAlgorithm(Byte[] keyBlob, String password)
at AspNet.Security.OAuth.Apple.Internal.DefaultAppleClientSecretGenerator.GenerateNewSecretAsync(AppleGenerateClientSecretContext context)
at AspNet.Security.OAuth.Apple.Internal.DefaultAppleClientSecretGenerator.GenerateAsync(AppleGenerateClientSecretContext context)
[18:05:10 Information] AspNet.Security.OAuth.Apple.AppleAuthenticationHandler
Error from RemoteAuthentication: error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error.
[18:05:10 Error] Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware
An unhandled exception has occurred while executing the request.
System.Exception: An error was encountered while handling the remote login. ---> Interop+Crypto+OpenSslCryptographicException: error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error
at Internal.Cryptography.Pal.CertificatePal.FromBlob(Byte[] rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
at AspNet.Security.OAuth.Apple.Internal.DefaultAppleClientSecretGenerator.CreateAlgorithmLinuxOrMac(Byte[] keyBlob, String password)
at AspNet.Security.OAuth.Apple.Internal.DefaultAppleClientSecretGenerator.CreateAlgorithm(Byte[] keyBlob, String password)
at AspNet.Security.OAuth.Apple.Internal.DefaultAppleClientSecretGenerator.GenerateNewSecretAsync(AppleGenerateClientSecretContext context)
at AspNet.Security.OAuth.Apple.Internal.DefaultAppleClientSecretGenerator.GenerateAsync(AppleGenerateClientSecretContext context)
at AspNet.Security.OAuth.Apple.AppleAuthenticationEvents.<>c.<<-ctor>b__10_0>d.MoveNext()
Providing the secret using the UsePrivateKey extension of the apple package. When running it on windows using:
var bytes = Convert.FromBase64String("base64-string");
var privateKey = Encoding.UTF8.GetString(bytes);
if (privateKey.StartsWith("-----BEGIN PRIVATE KEY-----", StringComparison.Ordinal))
{
string[] lines = privateKey.Split(new char[1]
{
'\n'
});
privateKey = string.Join(string.Empty, lines.Skip(1).Take(lines.Length - 2));
}
bytes = Convert.FromBase64String(privateKey);
var key = CngKey.Import(bytes, CngKeyBlobFormat.Pkcs8PrivateBlob);
var k = new ECDsaCng(key) { HashAlgorithm = CngAlgorithm.Sha256 };
it works using the same base64 string as in the container
Hi! Sorry for bothering but I have a question related to the authorization code flow described here https://kevinchalet.com/2016/07/13/creating-your-own-openid-connect-server-with-asos-implementing-the-authorization-code-and-implicit-flows/
I have implemented this, very similar to the code that is described there. I use the Authorize attribute on the Authorize endpoint to make sure the user is logged in before they see the authorization page, but unauthenticated users are not being redirected to the login page, it just returns a 401.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler:Debug: AuthenticationScheme: Identity.Application was not authenticated.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler:Debug: AuthenticationScheme: Identity.External was not authenticated.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler:Debug: AuthenticationScheme: Identity.TwoFactorRememberMe was not authenticated.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler:Debug: AuthenticationScheme: Identity.TwoFactorUserId was not authenticated.
AspNet.Security.OAuth.Validation.OAuthValidationHandler:Debug: Authentication was skipped because no bearer token was received.
AspNet.Security.OAuth.Validation.OAuthValidationHandler:Debug: AuthenticationScheme: Bearer was not authenticated.
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 (Identity.Application, Identity.External, Identity.TwoFactorRememberMe, Identity.TwoFactorUserId, Bearer).
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler:Information: AuthenticationScheme: Identity.Application was challenged.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler:Information: AuthenticationScheme: Identity.External was challenged.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler:Information: AuthenticationScheme: Identity.TwoFactorRememberMe was challenged.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler:Information: AuthenticationScheme: Identity.TwoFactorUserId was challenged.
AspNet.Security.OAuth.Validation.OAuthValidationHandler:Information: AuthenticationScheme: Bearer was challenged.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action ..Controllers.OAuthController.Authorize (...) in 67.3042ms
Identity.Application
to redirect the user to the login page.
That's OK, it was enough to get me started. Combined with the repo on Github I could find most of the things I needed.
There's one thing I haven't fixed yet, and that I have been searching for a while now. I derived from OpenIdConnectServerProvider and have overridden the serialize/deserialize methods so I can store the tokens in our database. However, it seems that at this point the tokens are not generated yet. I'm now generating them manually, but I'd really like to keep using the ones that OIDC generates.