当用户未分配给客户端应用程序时,使用 ASP.Net Core 的 OKTA 身份验证会引发未处理的异常
OKTA Authentication with ASP.Net Core throws unhandled exception when user not assigned to client application
我已经通过以下教程将 OKTA 集成到我的 ASP.Net 核心应用程序中:
https://developer.okta.com/quickstart/#/okta-sign-in-page/dotnet/aspnetcore
如果用户被分配到我的 OKTA 应用程序,它工作正常,但如果没有,我在授权回调中得到一个未处理的异常:
OpenIdConnectProtocolException: Message contains error:
'access_denied', error_description: 'User is not assigned to the
client application.', error_uri: 'error_uri is null'.
我想捕获这个异常并优雅地处理它。
使用 OpenId,您可以创建一个 OnRemoteFailure 事件来处理这个问题,但我不知道如何使用 Okta.AspNetCore 库来处理。
Okta.AspNetCore 的默认架构是 OpenIdConnectDefaults.AuthenticationScheme
:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
namespace Okta.AspNetCore
{
public static class OktaDefaults
{
public const string MvcAuthenticationScheme = OpenIdConnectDefaults.AuthenticationScheme;
public const string ApiAuthenticationScheme = JwtBearerDefaults.AuthenticationScheme;
public const string CallbackPath = "/authorization-code/callback";
public const string SignOutCallbackPath = "/signout/callback";
public static readonly string[] Scope = new string[] { "openid", "profile" };
}
}
因此您可以使用上面的方案名称配置 OpenIdConnectOptions
,包括访问 OpenIdConnectEvents
:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OktaDefaults.MvcAuthenticationScheme;
})
.AddCookie()
.AddOktaMvc(new OktaMvcOptions
{
// Replace these values with your Okta configuration
OktaDomain = Configuration.GetValue<string>("Okta:OktaDomain"),
ClientId = Configuration.GetValue<string>("Okta:ClientId"),
ClientSecret = Configuration.GetValue<string>("Okta:ClientSecret"),
});
services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.Events = new OpenIdConnectEvents
{
OnRedirectToIdentityProvider = async ctxt =>
{
// Invoked before redirecting to the identity provider to authenticate. This can be used to set ProtocolMessage.State
// that will be persisted through the authentication process. The ProtocolMessage can also be used to add or customize
// parameters sent to the identity provider.
await Task.Yield();
},
OnMessageReceived = async ctxt =>
{
// Invoked when a protocol message is first received.
await Task.Yield();
},
OnTicketReceived = async ctxt =>
{
// Invoked after the remote ticket has been received.
// Can be used to modify the Principal before it is passed to the Cookie scheme for sign-in.
// This example removes all 'groups' claims from the Principal (assuming the AAD app has been configured
// with "groupMembershipClaims": "SecurityGroup"). Group memberships can be checked here and turned into
// roles, to be persisted in the cookie.
await Task.Yield();
},
OnRemoteFailure = context =>
{
..........
context.HandleResponse();
context.Response.Redirect("AccessDenied?error=" + context.Failure.Message);
return Task.FromResult(0);
},
};
});
我已经通过以下教程将 OKTA 集成到我的 ASP.Net 核心应用程序中: https://developer.okta.com/quickstart/#/okta-sign-in-page/dotnet/aspnetcore
如果用户被分配到我的 OKTA 应用程序,它工作正常,但如果没有,我在授权回调中得到一个未处理的异常:
OpenIdConnectProtocolException: Message contains error: 'access_denied', error_description: 'User is not assigned to the client application.', error_uri: 'error_uri is null'.
我想捕获这个异常并优雅地处理它。
使用 OpenId,您可以创建一个 OnRemoteFailure 事件来处理这个问题,但我不知道如何使用 Okta.AspNetCore 库来处理。
Okta.AspNetCore 的默认架构是 OpenIdConnectDefaults.AuthenticationScheme
:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
namespace Okta.AspNetCore
{
public static class OktaDefaults
{
public const string MvcAuthenticationScheme = OpenIdConnectDefaults.AuthenticationScheme;
public const string ApiAuthenticationScheme = JwtBearerDefaults.AuthenticationScheme;
public const string CallbackPath = "/authorization-code/callback";
public const string SignOutCallbackPath = "/signout/callback";
public static readonly string[] Scope = new string[] { "openid", "profile" };
}
}
因此您可以使用上面的方案名称配置 OpenIdConnectOptions
,包括访问 OpenIdConnectEvents
:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OktaDefaults.MvcAuthenticationScheme;
})
.AddCookie()
.AddOktaMvc(new OktaMvcOptions
{
// Replace these values with your Okta configuration
OktaDomain = Configuration.GetValue<string>("Okta:OktaDomain"),
ClientId = Configuration.GetValue<string>("Okta:ClientId"),
ClientSecret = Configuration.GetValue<string>("Okta:ClientSecret"),
});
services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.Events = new OpenIdConnectEvents
{
OnRedirectToIdentityProvider = async ctxt =>
{
// Invoked before redirecting to the identity provider to authenticate. This can be used to set ProtocolMessage.State
// that will be persisted through the authentication process. The ProtocolMessage can also be used to add or customize
// parameters sent to the identity provider.
await Task.Yield();
},
OnMessageReceived = async ctxt =>
{
// Invoked when a protocol message is first received.
await Task.Yield();
},
OnTicketReceived = async ctxt =>
{
// Invoked after the remote ticket has been received.
// Can be used to modify the Principal before it is passed to the Cookie scheme for sign-in.
// This example removes all 'groups' claims from the Principal (assuming the AAD app has been configured
// with "groupMembershipClaims": "SecurityGroup"). Group memberships can be checked here and turned into
// roles, to be persisted in the cookie.
await Task.Yield();
},
OnRemoteFailure = context =>
{
..........
context.HandleResponse();
context.Response.Redirect("AccessDenied?error=" + context.Failure.Message);
return Task.FromResult(0);
},
};
});