-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow a Route to specify more than one authentication scheme #740
Comments
@philproctor can you already do this when you provide the authentication scheme to .NET? E.g. you provide a scheme with a key that works with JWT + Client Certificates? If not I would say this is more something the .NET authentication world should support? Not something we should look to add to Ocelot? All Ocelot does it defer to .NET here. I am reluctant to do anything else. |
@TomPallister we use 3 authentications: services.AddMvc(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme,
JwtBearerDefaults.AuthenticationScheme, OpenIdConnectDefaults.AuthenticationScheme)
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
}); If I try to register all of them with the same scheme name in |
Hi Everyone. We are using several authentication schemes too. Could you please tell if you have any info how to specify all of them for one Route. Thank you a lot. |
Hi @raman-m I think this is supported by .NET. We can specify multiple authentication schemes for a route: [Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme + "," + JwtBearerDefaults.AuthenticationScheme)]
public class MyController: Controller
{
} I think the same should be supported in Ocelot. |
The method that I use in ASP.NET to accept multiple authentication schemes is to add them all to the same authorization policy. The ASP.NET Authorize attribute names the authorization policy, not the authentication scheme. If Ocelot let me specify the name of an authorization policy instead of an authentication scheme, then I could achieve this result. Is that something that can be reasonably added? |
@TomPallister Tom, @philproctor Hi Phil! |
Hi Michael ! Could you share an example code with authorization policy approach please which you like to use? P.S.One of these days we are going to close this issue as implemented... The linked PR is ready on 95%. |
The same cannot be supported by Ocelot, because Ocelot has no controllers at all except very system ones. And Yes, a controller can support multiple auth schemes but based on those schemes which were described for the ASP.NET pipeline. Otherwise it doesn't work. So you need to specify schemes and inject their services to DI in app start logic, and then they will be available in all controllers. |
@feugen24 commented on Jul 22, 2019:
Not auth types, but auth artifacts: URL query string parameters, request headers, and form properties. Ocelot routes query params and headers for sure. Unfortunately Ocelot doesn't forward |
Here's an example configuration that configures JWT and cookie-based authentication, and then defines an authorization policy that accepts either. // Add authentication using JWT bearer tokens
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = context.Configuration["Jwt:Issuer"],
ValidAudience = context.Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(context.Configuration["Jwt:Key"]))
};
});
// Add another using cookies
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.Cookie.Name = "MyCookie";
options.Cookie.SameSite = SameSiteMode.Strict;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
options.Cookie.MaxAge = TimeSpan.FromMinutes(30);
options.LoginPath = "/Login";
options.LogoutPath = "/Logout";
options.AccessDeniedPath = "/AccessDenied";
options.ReturnUrlParameter = "returnUrl";
options.SlidingExpiration = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
});
// Define an authorization policy named "Either" that accepts either JWT or cookie authentication
builder.Services.AddAuthorization(options =>
{
var policy = new AuthorizationPolicyBuilder(new []
{
JwtBearerDefaults.AuthenticationScheme,
CookieAuthenticationDefaults.AuthenticationScheme
})
.RequireAuthenticatedUser()
.Build();
options.AddPolicy("Either", policy);
}); After setting up this policy, I might configure my route like this: {
"Routes": [
{
"DownstreamPathTemplate": "/api/service1",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5001
}
],
"UpstreamPathTemplate": "/service1",
"UpstreamHttpMethod": [ "Get" ],
"AuthorizationPolicy": "Either"
}
],
"GlobalConfiguration": {
"BaseUrl": "https://localhost:5000"
}
} That would be equivalent to placing an attribute on my controller action |
@michaellperry Thank you for the sample!
Hmm... I'm very sorry, but Ocelot has no the |
I must have misunderstood your request for example code. My intent was to show you what code I would like to be able to write using the authorization policy approach. This would be one way to add a feature to support multiple authentication schemes. It would also have the benefit of providing additional flexibility by taking advantage of a feature already built into the ASP.NET authorization pipeline. Thanks for pointing me to the feature. That would certainly resolve this issue. If I were to work on a PR for that, would you be able to bump the priority? |
@michaellperry Michael,
So, Ocelot is able to route anonymous HTTP traffic down to the target service and downstream services can sign a cookie.
Yes, we would! We welcome any contributions. @ggnaegi FYI |
That would be #1159, Add a list of AuthorizationPolicies to ReRoutes. It looks like that stalled after the initial suggestion. And it looks like it would resolve this issue. I'll take a deeper look and send you a proposal. |
* #1580. Added an opportunity to use several authentication provider keys. * Update src/Ocelot/Configuration/Builder/AuthenticationOptionsBuilder.cs Co-authored-by: Raynald Messié <[email protected]> * #1580. Replaced AuthenticationProviderKeys type from the list to the array. * #1580. Added a doc how to use AuthenticationProviderKeys in a Route. * #1580. Amended the description how to use AuthenticationProviderKeys in a Route. * #1580. Added an opportunity to use several authentication provider keys. * Update src/Ocelot/Configuration/Builder/AuthenticationOptionsBuilder.cs Co-authored-by: Raynald Messié <[email protected]> * #1580. Replaced AuthenticationProviderKeys type from the list to the array. * #1580. Added a doc how to use AuthenticationProviderKeys in a Route. * #1580. Amended the description how to use AuthenticationProviderKeys in a Route. * Quick review * #1580. Implemented review points. * #1580. Initialized result with AuthenticateResult.NoResult(). * #1580. Added @ggnaegi suggestions. * #1580. Brought back the idea not to allocate AuthenticateResult instance. * quick review * Return Auth result of the last key in the collection * review unit tests * Enable parallelization of unit tests * Fix messages * Disable parallelization for PollyQoSProviderTests * Switch off unstable test * Re-enable parallelization & Isolate unstable test * Reflection issue in middleware base: remove getting Type object * Switch off unstable test * Clean code * Make MiddlewareName as public property * Code review by @RaynaldM * AuthenticationMiddleware: Line & Branch coverage -> 100% * AuthenticationOptionsCreator: coverage -> 100% * Remove private helpers with one reference * RouteOptionsCreator: coverage -> 100% * FileAuthenticationOptions: Refactor ToString method * FileConfigurationFluentValidator: coverage -> 100% * RouteFluentValidator: Branch coverage -> 100% * TODO and Skip unstable test * Move acceptance tests to the separate folder * Review and refactor acceptance tests * Add AuthenticationSteps class. Choose inheritance over composition: less code * Add 'GivenIHaveATokenWithScope' to 'AuthenticationSteps' * Temporarily disable 'Should_timeout_per_default_after_90_seconds' test * Add CreateIdentityServer method * Add draft test * Update route validator to support multiple auth schemes * Acceptance tests * Revert "TODO and Skip unstable test" This reverts commit 1ec8564. * Revert "Make MiddlewareName as public property" This reverts commit 6f50c76. * Revert "Reflection issue in middleware base: remove getting Type object" * Clean up * Isolate unstable test * Mark old property as `Obsolete` * a tiny little bit of cleanup * Handling cases when principal or identity are null * Update Authentication feature docs * Convert back to block scoped namespace --------- Co-authored-by: Igor Polishchuk <[email protected]> Co-authored-by: Raman Maksimchuk <[email protected]> Co-authored-by: Raynald Messié <[email protected]> Co-authored-by: Igor Polishchuk <[email protected]> Co-authored-by: Guillaume Gnaegi <[email protected]>
New Feature
Allow a reroute to specify more than one authentication scheme for a reroute. Specification could either be JSON array or comma separated.
Motivation for New Feature
Sometimes more than one authentication scheme may be allowed for an API (e.g. JWT + Client Certificates). This feature would allow more than one scheme to be use on a single reroute eithout requiring a custom override of the authentication pipeline..
The text was updated successfully, but these errors were encountered: