I have a RestrictedAttribute to protect my controllers that implments the OnAuthorization(AuthorizationFilterContext context)
from the IAuthorizationFilter.
Then I need to check if the user is authenticated using following code:
public void OnAuthorization(AuthorizationFilterContext context)
{
IPrincipal user = context.HttpContext.User;
// If the user is not authenticated...
if (!user.Identity.IsAuthenticated)
{
TraceFailure("Unauthorized. User (principal identity) is not authenticated.", null);
// Add to response HttpStatusCode.Unauthorized
}
}
All my controllers are inherited by our custom ApiBaseController
that has the [Restricted]
attribute like:
/// <summary>
/// Defines the base class for all API controllers.
/// </summary>
[Restricted]
[DynamicClaims]
[CultureAware]
public abstract class ApiBaseController : ControllerBase
I send a valid token to the request but the user
has all its parameters as null and the IsAuthenticated is always false (because is the default value).
I configured my Authentication and Authorization like following:
public static IServiceCollection AddIdentityClientMiddlewareService(
this IServiceCollection services)
{
try
{
services.AddAuthorization((options) =>
{
options.AddPolicy(
"DefaultScope",
(policy) =>
{
policy.AuthenticationSchemes = new List<string>
{
"Bearer"
};
policy.RequireClaim("scope", Configuration.WebApiScopes);
});
}).AddAuthentication((options) =>
{
options.DefaultAuthenticateScheme = AuthorizationConstants.AuthenticationSchemes.Cookies;
options.DefaultChallengeScheme = AuthorizationConstants.AuthenticationSchemes.Oidc;
}).AddCookie(AuthorizationConstants.AuthenticationSchemes.Cookies, (options) =>
{
options.Cookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.SameAsRequest;
options.CookieManager = new SameSiteCookieManager(new ChunkingCookieManager());
}).AddOpenIdConnect(AuthorizationConstants.AuthenticationSchemes.Cookies, (options) =>
{
// Set the identity server endpoint
options.Authority = Configuration.AuthorityEndpoint;
// Set the authentication type
// Set the grant used (hybrid)
options.ResponseType = "code id_token token";
// Set client id and client secret
options.ClientId = Configuration.ClientId;
options.ClientSecret = Configuration.ClientSecret;
// Set the scopes requested
options.Scope.Add(Configuration.WebUserInterfaceScopes);
// Setup notifications from the middleware
options.Events = new Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectEvents()
{
// Notified when the authentication fails
OnAuthenticationFailed = OnAuthenticationFailedAsync,
// Notified when the security token is received
OnTokenResponseReceived = OnTokenResponseReceivedAsync,
// Notified when the security token has been validated
OnTokenValidated = OnSecurityTokenValidatedAsync,
// Notified when an authorization code is received
OnAuthorizationCodeReceived = OnAuthorizationCodeReceivedAsync,
// Notified when a redirect to an identity provider is requested
OnRedirectToIdentityProvider = OnRedirectToIdentityProviderAsync,
// Notified when a protocol message is received
OnMessageReceived = OnMessageReceivedAsync,
};
}).AddJwtBearer((options) =>
{
// Setup the bearer token authentication middleware
// This middleware is for the Web API
// Set the identity server endpoint
options.Authority = Configuration.AuthorityEndpoint;
options.SaveToken = true;
options.RequireHttpsMetadata = false;
options.IncludeErrorDetails = true;
options.RefreshOnIssuerKeyNotFound = true;
// Token validation options
// Disable audience validation
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateAudience = false,
NameClaimType = "name",
RoleClaimType = "role"
};
});
}
catch (Exception ex)
{
throw new InvalidOperationException("Unable to configure the Identity Server.", ex);
}
return services;
}
Why is my context.HttpContext.User
is not populated with the metadata? I am missing something?
CodePudding user response:
Well... After quite a few time came back to the maze... finnaly i spot something out.
The AddAuthentication
config determine AuthorizationConstants.AuthenticationSchemes.Cookies
as its default authentication scheme(and I guess we forget to change the scheme on AddOpenIdConnect
, as it currently Cookie name). DefaultChallengeScheme
was specified to AuthorizationConstants.AuthenticationSchemes.Oidc
, but if the request was not redirect, that prove it use cookie authentication to verify and passed down.
a valid token
now has no use since we doesn't specify out what specific Authentication scheme on the endpoint. Therefore, it use the default cookie thing.
This was base on assumption that we're not drop app.UseAuthentication(); app.UseAuthorization();
.
I would bet change defaultAuthentication to the right one would solve the prob
.AddAuthentication((options) =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = AuthorizationConstants.AuthenticationSchemes.Oidc;
})