OpenID Connect/OAuth2 server framework for OWIN/Katana and ASP.NET Core
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(this.Configuration["OAuth:SecurityKey"]));
services.AddAuthentication(
options => {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}
)
.AddOpenIdConnectServer(options=> {
options.TokenEndpointPath = "/oauth/token";
options.AuthorizationEndpointPath = "/oauth/authorize";
options.SigningCredentials.AddKey(signingKey);
options.AccessTokenHandler = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler {
OutboundClaimTypeMap = new Dictionary<string, string>()
};
options.Provider = new AuthorizationServerProvider();
options.ApplicationCanDisplayErrors = true;
options.AllowInsecureHttp = true;
});
Yes.
here is my
public override async Task HandleAuthorizationRequest(HandleAuthorizationRequestContext context)
{
if (context.Request.IsImplicitFlow())
{
var clientId = context.Request.ClientId;
var rdi = context.Request.RedirectUri;
var state = context.Request.State;
var scope = context.Request.Scope;
if (string.IsNullOrEmpty(clientId))
{
context.Reject(error: OpenIdConnectConstants.Errors.InvalidClient,
description: "client id cannot be null");
return;
}
else if (string.IsNullOrEmpty(rdi))
{
context.Reject(
error: OpenIdConnectConstants.Errors.InvalidClient,
description: "redirect_uri cannot be empty"
);
return;
}
else if (string.IsNullOrEmpty(scope))
{
context.Reject(
error: OpenIdConnectConstants.Errors.InvalidClient,
description: "scope cannot be empty"
);
return;
}
var identity = new ClaimsIdentity(
OpenIdConnectServerDefaults.AuthenticationScheme,
OpenIdConnectConstants.Claims.Name,
OpenIdConnectConstants.Claims.Role);
var clientService = context.HttpContext.RequestServices.GetRequiredService<IClientService>();
var clientService = await partnerService.GetPartnerBrokerAuthClientByClientAccessId(clientId);
if (clientService == null)
{
context.Reject(error: OpenIdConnectConstants.Errors.InvalidClient,
description: "client id cannot be found");
return;
}
if (string.IsNullOrEmpty(clientService .AllowedOrigin))
{
context.Reject(error: OpenIdConnectConstants.Errors.InvalidClient,
description: "The redirect url of the client cannot be null");
return;
}
if (!clientService .AllowedOrigin.Split(',').Any(x => string.Equals(x, rdi, StringComparison.OrdinalIgnoreCase)))
{
context.Reject(
error: OpenIdConnectConstants.Errors.InvalidClient,
description: "The supplied redirect uri is incorrect"
);
return;
}
if (clientService .Scopes == null || ( clientService .Scopes != null && clientService .Scopes.Count == 0 ))
{
context.Reject(error: OpenIdConnectConstants.Errors.InvalidClient,
description: "Ths definition of the client's scopes cannot be null");
return;
}
}
ticket.SetAccessTokenLifetime(TimeSpan.FromSeconds(clientService.AccessTokenLifeTime));
ticket.SetIdentityTokenLifetime(TimeSpan.FromSeconds(clientService.AccessTokenLifeTime));
context.Validate(ticket);
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