-
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
#842 AuthenticationOptions in GlobalConfiguration #1215
#842 AuthenticationOptions in GlobalConfiguration #1215
Conversation
+1 to please add/merge this feature. Question: does your implementation allow for a given route to NOT have authentication? Like an 'allow anonymous' setting. In my project this would be needed for my identity service. |
@rathga, it should be quite easy to add this option. I'll try to update the pull request soon. Thanks for the feedback! |
6e53f98
to
c1afca2
Compare
@jlukawska Hi J! What I've done:
Now we can start code review... |
Hey, Richard! Could you join to code review please? Also, check please, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@RaynaldM @wast
Wow! 2 approvals from you, guys, without issues, really? 😉 👇
I am impressed! 😄
I see 2 major issues now:
- Unit & acceptance tests, and their methods have a lot of copied & pasted code snippets. The fact-methods are long. But they could be shorter.
- Some lines are too long. It is hard to read.
I would appreciate if PR author will fix them.
@@ -42,6 +42,63 @@ When Ocelot runs it will look at this Routes AuthenticationOptions.Authenticatio | |||
|
|||
If a Route is authenticated Ocelot will invoke whatever scheme is associated with it while executing the authentication middleware. If the request fails authentication Ocelot returns a http status code 401. | |||
|
|||
If you want to configure AuthenticationOptions the same for all Routes, do it in GlobalConfiguration the same way as for Route. If there are AuthenticationOptions configured both for GlobalConfiguration and Route (AuthenticationProviderKey is set), the Route section has priority. If you want to exclude route from global AuthenticationOptions, you can do that by setting AllowAnonymousForGlobalAuthenticationOptions to true in the route AuthenticationOptions - then this route will not be authenticated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is better to write a new subsection of the chapter like:
Global Authentication
^^^^^^^^^^^^^^^^^^^^^
before this line.
And this line is too long! Splitting phrases should help.
public AuthenticationOptions Create(FileAuthenticationOptions routeAuthOptions, | ||
FileAuthenticationOptions globalConfAuthOptions) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public AuthenticationOptions Create(FileAuthenticationOptions routeAuthOptions, | |
FileAuthenticationOptions globalConfAuthOptions) | |
public AuthenticationOptions Create( | |
FileAuthenticationOptions routeAuthOptions, | |
FileAuthenticationOptions globalConfAuthOptions) |
Or, Don't make new line at all. Having 2-3 parameters in signature on the same line is totally fine.
public List<string> AllowedScopes { get; set; } | ||
|
||
/// <summary> | ||
/// Allows anonymous authentication globally. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It allows per route actually.
/// <value> | ||
/// <see langword="true"/> if it is allowed; otherwise, <see langword="false"/>. | ||
/// </value> | ||
public bool AllowAnonymousForGlobalAuthenticationOptions { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name could be shorter, like that: AllowAnonymousAuthentication
or even AllowAnonymous
.
|
||
RuleFor(authOptions => authOptions.AuthenticationProviderKey) | ||
.MustAsync(IsSupportedAuthenticationProviders) | ||
.WithMessage("{PropertyName}: {PropertyValue} is unsupported authentication provider"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What placeholders are here?
Are they implicit? Where is definition of these variables?
var route = new FileRoute | ||
{ | ||
AuthenticationOptions = new FileAuthenticationOptions() | ||
{ | ||
AuthenticationProviderKey = "routeKey", | ||
AllowedScopes = new List<string>() { "routeScope1", "routeScope2" }, | ||
}, | ||
}; | ||
var globalConfig = new FileGlobalConfiguration | ||
{ | ||
AuthenticationOptions = new FileAuthenticationOptions() | ||
{ | ||
AuthenticationProviderKey = "globalKey", | ||
AllowedScopes = new List<string>() { "globalScope1", "globalScope2" }, | ||
}, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you define a helper to construct FileRoute
object plz?
The goal is writing less code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe that all new facts could call new defined helpers.
So, too many copy-pasted code snippets!
var provider = new ServiceCollection() | ||
.BuildServiceProvider(); | ||
|
||
// Todo - replace with mocks | ||
_configurationValidator = new FileConfigurationFluentValidator(provider, new RouteFluentValidator(_authProvider.Object, new HostAndPortValidator(), new FileQoSOptionsFluentValidator(provider)), new FileGlobalConfigurationFluentValidator(new FileQoSOptionsFluentValidator(provider))); | ||
_configurationValidator = new FileConfigurationFluentValidator(provider, new RouteFluentValidator(new HostAndPortValidator(), new FileQoSOptionsFluentValidator(provider), _fileAuthenticationOptionsValidator), new FileGlobalConfigurationFluentValidator(new FileQoSOptionsFluentValidator(provider), _fileAuthenticationOptionsValidator)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Too long line!
It is hard to read the code...
Could you apply new line vs indentation approach to make code readability better plz?
@@ -1554,7 +1598,7 @@ private void GivenAServiceDiscoveryHandler() | |||
ServiceDiscoveryFinderDelegate del = (a, b, c) => new FakeServiceDiscoveryProvider(); | |||
collection.AddSingleton<ServiceDiscoveryFinderDelegate>(del); | |||
var provider = collection.BuildServiceProvider(); | |||
_configurationValidator = new FileConfigurationFluentValidator(provider, new RouteFluentValidator(_authProvider.Object, new HostAndPortValidator(), new FileQoSOptionsFluentValidator(provider)), new FileGlobalConfigurationFluentValidator(new FileQoSOptionsFluentValidator(provider))); | |||
_configurationValidator = new FileConfigurationFluentValidator(provider, new RouteFluentValidator(new HostAndPortValidator(), new FileQoSOptionsFluentValidator(provider), _fileAuthenticationOptionsValidator), new FileGlobalConfigurationFluentValidator(new FileQoSOptionsFluentValidator(provider), _fileAuthenticationOptionsValidator)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Too long lines 1592 and 1601 !
private static bool IsAuthenticated(FileRoute fileRoute, FileGlobalConfiguration globalConfiguration) | ||
{ | ||
return (!string.IsNullOrEmpty(globalConfiguration?.AuthenticationOptions?.AuthenticationProviderKey) && | ||
!fileRoute.AuthenticationOptions.AllowAnonymousForGlobalAuthenticationOptions) || | ||
!string.IsNullOrEmpty(fileRoute.AuthenticationOptions?.AuthenticationProviderKey); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because the body consists of one operator only, why not to define via expression body 👇
private static bool IsAuthenticated(FileRoute fileRoute, FileGlobalConfiguration globalConfiguration) | |
{ | |
return (!string.IsNullOrEmpty(globalConfiguration?.AuthenticationOptions?.AuthenticationProviderKey) && | |
!fileRoute.AuthenticationOptions.AllowAnonymousForGlobalAuthenticationOptions) || | |
!string.IsNullOrEmpty(fileRoute.AuthenticationOptions?.AuthenticationProviderKey); | |
} | |
private static bool IsAuthenticated(FileRoute fileRoute, FileGlobalConfiguration globalConfiguration) | |
=> (!string.IsNullOrEmpty(globalConfiguration?.AuthenticationOptions?.AuthenticationProviderKey) | |
&& !fileRoute.AuthenticationOptions.AllowAnonymousForGlobalAuthenticationOptions) | |
|| !string.IsNullOrEmpty(fileRoute.AuthenticationOptions?.AuthenticationProviderKey); |
… characters: {should_*}
19d5e00
to
c99d512
Compare
I need this change,What time releases this PR? |
Sorry for delaying the delivery! We have a lack of dev time! |
Closed due to creation of a new PR: #2114 |
Closes #842
AuthenticationOptions
property in global configuration #842Proposed Changes
It is possible to configure AuthenticationOptions in GlobalConfiguration. Then all routes use these settings. To configure an exception to this rule (e.g. for identity service), AllowAnonymousForGlobalAuthenticationOptions property should be set to true in the route AuthenticationOptions.
If a route has its own AuthenticationOptions with AuthenticationProviderKey configured additionally, it has priority over the global one.
At the moment if a route uses a global AuthenticationProviderKey (when AuthenticationProviderKey is not configured for route explicitly), it uses also global AllowedScopes, even if AllowedScopes is configured for the route additionally.