Spring Boot and OAuth2, WebSecurityConfigurerAdapter vs ResourceServerConfigurerAdapter - spring

What is the difference between WebSecurityConfigurerAdapter and ResourceServerConfigurerAdapter and which should have higher precedence?
I don't really see difference if I am both resource owner and the client. I can configureHttpSecurity in both classes.
EDIT:
Which type of matchers should I add in WebSecurityConfigurerAdapter and which in ResourceServerConfigurerAdapter? I found in some examples that WebSecurityConfigurerAdapter matches pages for login, registration etc. and ResourceServerConfigurerAdapter for the real resource. Is that a correct way of doing it?

ResourceServerConfigurerAdapter for adjust the access rules and paths that are protected by OAuth2 security (Some additional oauth2 filters activated).
WebSecurityConfigurerAdapter for the basic Spring Security customization.

Related

Combining OAuth2 with http basic authentication spring security

I've implemented OAuth2 using spring boot and spring security. Now I've different set of APIs available and I want to use different authentication methods for it. For e.g I want to use OAuth2 for /users/** apis and Http Basic Authentication for /admin/** APIs.
However, OAuth2 shouldn't work for /admin/** and HTTP basic shouldn't work for /users/** APIs.
Any help would be great!
In Spring Security you can have multiple filter chains that handle different requests.
So you can have one that handles requests to the /users/** uri which will have the Basic Authentication filter , and one that handles requests to /admin/** uri which will have the Oauth2 filters. To set this up, you need 2 instances of the WebSecurityConfigurerAdapter
One for Oauth2
#Configuration
#Order(1)
public static class Oauth2ConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http.mvcMatcher("/user/**")
......
And another for Basic:
#Configuration
#Order(2)
public static class BasicConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http.mvcMatcher("/admin/**")
......
This article explains it in more detail: https://www.baeldung.com/spring-security-multiple-entry-points
Also this code does something similar with Digest auth for /admin and Basic for all other. https://github.com/wlesniak/spring-security-authn-authz-course/tree/master/module_2/mod2_crypto_portfolio_digest

SAML and Oauth2 in a single spring boot application

In an attempt to develop a generic identity service for a project I am working on, I need to support Azure ADFS-based SAML security for UI pages and Oauth2 based security for my REST APIs in a single spring-boot application
I have a spring boot application attempting to provide SAML based protection for some of my UI resources and Oauth2 based protection for my REST APIs. The UI pages and the REST APIs are hosted in the same spring boot based application. I have a SecurityConfiguration class that extends WebSecurityConfigurerAdapter and that contains my SAML configuration. I also have a ResourceServerConfig class that extends ResourceServerConfigurerAdapter where I have tried to configure the Oauth2 authentication for my REST APIs.
Here is what my code looks like
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
{
/////// Other methods //////
#Override
protected void configure(HttpSecurity http) throws Exception
{
http.authorizeRequests().anyRequest().authenticated();
http.httpBasic().authenticationEntryPoint(samlEntryPoint());
http.csrf().disable();
http.addFilterBefore(metadataGeneratorFilter(), ChannelProcessingFilter.class).addFilterAfter(samlFilter(), BasicAuthenticationFilter.class);
http.authorizeRequests().antMatchers("/oauth/token").permitAll().anyRequest().authenticated();
}
The ResourceServerConfig class looks something like the following
#Configuration
#EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter
{
#Override
public void configure(HttpSecurity http) throws Exception
{
http
.csrf().disable()
.anonymous().and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS).permitAll()
.antMatchers("/api/**").authenticated();
}
My problem is, with the above configuration in place, I can either get SAML protection on my UI pages OR Oauth2 protection on my APIs but not both. If I remove #EnableResourceServer from the ResourceServerConfig class and try to access one of my UI pages, I am reliably redirected to the microsoft Azure login page which redirects me back to my UI page after successful authentication. But with this, any attempt to access my apis (with valid bearer tokens) results in a redirection to the microsoft Azure login page. If I re-enable #EnableResourceServer my APIs get protected and behave as expected but SAML protection for all UI pages gets completely disabled with spring allowing unhindered access to all UI resources.
I can't figure out how to tell spring boot to use which authentication framework for the two kinds of URL patterns I have. Is such a thing even possible?
Any help with this would be appreciated.
Regards,
Dipak Jha
I think I have found an answer to my own question. This reply here provides a workable solution. A properly configured OAuthRequestedMatcher seems to do the trick. Please let me know if someone thinks this can be done in a better way.
Regards
Dipak Jha

How to handle security.enable-csrf in Spring Boot 2?

I'm migrating an application from Spring Boot 1.5 to 2.0.5.
I have a property set as security.enable-csrf=true in 1.5 version which is not available in 2.0 version of Spring Boot.
I read the documents and it is said that in Spring Boot 2.0:
CSRF protection is enabled by default in the Java configuration.
So by default it is enabled ok fine, but there is also one class created which extends WebSecurityConfigurerAdapter this means Spring Boot default security configuration has been turned off. Is this also means security.enable-csrf is disabled now?
If yes how do I enable it like I had it in the application for 1.5 version.
I didn't get any document which gives a clear confirmation on how to handle security.enable-csrf property in Spring Boot 2.0 and while declaring the WebSecurityConfigurerAdapter.
Does anyone know about it? Also any document link which I have missed to read about this would be great help.
In order to have backward compatibility with the property already been set in you application, security.enable-csrf=true, you can use the following code:
#EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
#Value("${security.enable-csrf}")
private boolean csrfEnabled;
#Override
protected void configure(HttpSecurity http) throws Exception {
if (!csrfEnabled) {
http.csrf().disable();
}
}
}
As you might guess the magic comes from http.csrf().disable(); that
in the above code you can control enabling/disabling it by the
property you have set in you application.properties file.
More Info:
For more details you can also refer to the spring documents:
https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#csrf
WebSecurityConfigurerAdapter is an abstract class, when you create a class which extends WebSecurityConfigurerAdapter, you will override void configure(HttpSecurity http) method.
You can disable csrf in this method, like that;
http.csrf().disable();
You can read this comment on top of the csrf() method (in HttpSecurity class).
Adds CSRF support. This is activated by default when using
WebSecurityConfigurerAdapter's default constructor. You can disable it ...."
This comment says that, when you extends this class, default constructor of WebSecurityConfigurerAdapter works and csrf is activated.

Unable to use ResourceServerConfigurerAdapter and WebSecurityConfigurerAdapter in the same project

I have a project that serves web pages that use form login. Now I would like the project to also expose an api that uses oauth. The idea is to have the ResourceServerConfigurerAdapter and WebSecurityConfigurerAdapter setup with requestMatchers to use different paths that don't overlap. However, I get either a OAuth2AuthenticationProcessingFilter or a UsernamePasswordAuthenticationFilter, but not both.
ResourceServerConfigurerAdapter:
#Override
public void configure(HttpSecurity http) throws Exception {
http
.requestMatchers()
.mvcMatchers("/api/**")
...
}
If my WebSecurityConfigurerAdapter does not use any requestMatchers, I get a UsernamePasswordAuthenticationFilter but no OAuth2AuthenticationProcessingFilter.
http
.authorizeRequests()
...
If on the other hand I use any request matcher at all in the WebSecurityConfigurerAdapter, no matter how specific, I get a OAuth2AuthenticationProcessingFilter but no UsernamePasswordAuthenticationFilter.
http
.requestMatchers()
.mvcMatchers("/anything")
.authorizeRequests()
...
Solutions?
Or should I just go about this a different way? For instance, create a new project for the api? (even though that will mean duplicating some code, such as domain objects)
Consider Annotating ResourceServerConfigurerAdapter with #Order(40) and implement configure(HttpSecurity http) as the following:
http.antMatcher("/api/**").authorizeRequests().anyRequest().authenticated();
annotate WebSecurityConfigurerAdapter with #Order(50). Tested on spring boot 1.5.7.
try to secure all possible paths in the security configuration with the highest order.
Spring creates one security filter chain for security configuration in ResourceServerConfigurerAdapter and another for security configuration in WebSecurityConfigurerAdapter

ResourceServerConfigurerAdapter vs WebSecurityConfigurerAdapter

I'm currently working on a Oauth2 implementation with Spring Security, and I found many documentations that use ResourceServerConfigurerAdapter along with the WebSecurityConfigurerAdapter.
I hope someone can tell me the differences between the two configurations because I really get confused in which configure(HttpSecurity http) method to use since both classes offer one.
I've found some similar questions here in stackoverflow but there are not clearly answered.
From reading the JavaDocs I think the only purpose it's to separate the concerns for OAuth2 Resources authentication from the WebSecurityConfigurerAdapters which contains all sorts of security filters.
Additionally it seems like you should add #EnableResourceServer annotation and provide a #Bean of type ResourceServerConfigurer via ResourceServerConfigurerAdapter. The annotation will basically create another WebSecurityConfigurerAdapters with an hard-coded order of 3.
So to summarise you will have 2 or more WebSecurityConfigurerAdapters but one is specific to OAuth2 authentications.

Resources