-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Support Configuring Authorization Server in HttpSecurity.with(authorizationServer(), ...) #1707
Comments
@rwinch Thanks for the extra details. Regarding:
These have been available since Day 1 and is well documented in the reference doc and is also used throughout all the samples and tests. So it's quite familiar and natural to users.
A dedicated For example, looking at the sample configuration in the Getting Started section of the reference, one could combine the @Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http)
throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
http.with(authorizationServerConfigurer, authorizationServer ->
authorizationServer
.oidc(Customizer.withDefaults())) // Enable OpenID Connect 1.0
.authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated()
)
.csrf((csrf) -> csrf
.ignoringRequestMatchers(authorizationServerConfigurer.getEndpointsMatcher())
)
// Accept access tokens for User Info and/or Client Registration
.oauth2ResourceServer((resourceServer) -> resourceServer
.jwt(Customizer.withDefaults())
)
.formLogin(Customizer.withDefaults());
return http.build();
} Given the above configuration and your comment for expected behaviour:
This is already possible as demonstrated in the sample configuration. At this point, I don't see anything that needs to be improved upon. Thoughts? |
Thanks @jgrandja! This appears to be a great start.
The following lines are not used anywhere else within Spring Security:
The feedback we have received is that it is difficult to remember to do this because it is not following the standard conventions of Spring Security for configuring extensions. I agree. Looking at this configuration, it does not feel like Spring Security's configuration model. The standard way to configure a Spring Security extension can be found in the reference and aligns with what is suggested in this issue. What's more is using the way that is suggested in this ticket only requires remembering a single static method. The remaining configuration can be autocompleted from the IDE. The documented way of configuring Authorization Server requires remembering:
Why is it recommended to use a dedicated
How does someone know how to combine them? For example, the documentation uses
However, when using a single Another example is that the documentation uses Why is it necessary to configure csrf and oauth2Resource server? This seems like unnecessary explicit configuration. |
IMO it is a recommended best practice to isolate all the authorization server capabilities in it's own In a production environment, the Identity Provider is a separately managed system and the same goes for an OAuth2/OIDC Authorization Server as it is also a completely separate system. Obviously, the 2 systems need to be integrated to enable the OAuth2 flows, but they should most definitely be completely isolated, especially the Identity Provider as it should never "sit with" another system, for security and privacy reasons. From a general architecture standpoint, a This is the main reason why we have documented this configuration pattern across the reference docs, samples and tests. However, it does appear that we have not formally documented (in words) this as a best practice in our docs. Another reason worth mentioning, although not as important, is by combining the default (Spring Security) |
@rwinch I've opened a Draft PR (gh-1725) to iterate on this. Take a look at the 1st commit showing a simplified configuration with the existing 2x Take a look at the 2nd commit showing a simplified configuration with a single |
Thanks @jgrandja! Let me know when you are ready for feedback. |
@rwinch It's ready for feedback. |
@jgrandja if this enhancement is added, please do not depreciate the current available configuration. I agree with you to not mix authorization server filter chain with business filter chain. I think that this enhancement will add more confusion than clarity. |
Thanks for the feedback @akuma8. Can you provide more details in regards to:
|
I agree with @rwinch that "it would be very nice if adding a default Authorization Server to an existing application could be done with a single invocation of the HttpSecurity DSL". I find the present approach somewhat inconsistent, and more complex than I'd expect from Spring. |
Thanks for the feedback @johnsonr.
I'm assuming you are referring to the following configuration as documented in the Getting Started page: OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
.oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0 To give you more context on why the configuration is like this is because before Looking at Line 59 in 00f3874
you will notice it applies some defaults and then calls If the application needs to further customize the authorization server configuration, then you need to obtain the reference of the To sum up, before
An application can freely choose to configure the defaults themselves if they prefer. One other important thing to mention is that Spring Authorization Server is built on top of Spring Security, so it inherits Spring Security's configuration model and does not have it's own proprietary ways of configuring.
A single invocation of the @Bean
@Order(1)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)
throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
// @formatter:off
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc(Customizer.withDefaults()) // Enable OpenID Connect 1.0
)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.csrf((csrf) ->
csrf.ignoringRequestMatchers(authorizationServerConfigurer.getEndpointsMatcher()))
// Redirect to the login page when not authenticated from the
// authorization endpoint
.exceptionHandling((exceptions) -> exceptions
.defaultAuthenticationEntryPointFor(
new LoginUrlAuthenticationEntryPoint("/login"),
new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
)
)
// Accept access tokens for User Info and/or Client Registration
.oauth2ResourceServer((resourceServer) -> resourceServer
.jwt(Customizer.withDefaults()));
// @formatter:on
return http.build();
} To sum up once again, I am curious, if the reference doc was updated and made use of I hope any of this helps? I'm looking forward to your response and helping move this forward. |
I love this PR and would love to see it merged so that SAS feels more in line with the rest of Spring Security. We could deprecate the old way but not remove it until the next major release, while promoting the vastly cleaner and more consistent new way. |
We will be merging the 1st commit, which shows a simplified configuration with the existing 2x However, we will not be merging the 2nd commit, which shows a single |
Expected Behavior
It would be nice if all of the Authorization Server configuration options could be made/discoverable from a single entry point & on an existing
SecurityFilterChain
.For example, it would be very nice if adding a default Authorization Server to an existing application could be done with a single invocation of the
HttpSecurity
DSL using something like this:If a user wanted to make changes to the defaults, then they would do so using the
Customizer
. For example, if OIDC was not enabled by default, then the user would be able to use:NOTE: I'm not saying that OIDC should or should not be a default, but I'm just using this as an example of how a user would be able to change the defaults.
Using this approach:
Current Behavior
Currently the recommendation is:
The disadvantages of this approach are:
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity
is unfamiliar to usershttp.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
is also unfamiliar to usersSecurityFilterChain
@Order
(and know where to import it from)OAuth2AuthorizationServerConfiguration.applyDefaultSecurity
so it can be importedOAuth2AuthorizationServerConfigurer.class
and how to get it fromHttpSecurity
and know that this is how to configureoidc
(vs another static method import likeapplyDefaultSecurity
or something returned fromapplyDefaultSecurity
, etc).exceptionHandling
and how to configure it.Context
I'd like to only need to remember a single thing (ideally a concept) in order to add Spring Authorization Server to an existing
SecurityFilterChain
.This came up a few times (in various contexts) around trying to simplify (remove) the additional SecurityFilterChain and align more with webauthn in @joshlong and my Goodbye Passwords Hello Security talk.
The text was updated successfully, but these errors were encountered: