My use case is simple but could not find an example. I want to allow all my endpoints excluding only one path which will require basic authentication who has USER role. How to do it with Spring Security's antmatchers? I tried something like below but I get 401 Unauthorized in all requests.
httpSecurity
.authorizeRequests()
.antMatchers("/api/**").hasRole("USER")
.antMatchers("/**").permitAll();
Related
I have rest API where I need to secure some (UI facing) endpoints with OKTA authentication, and others (backend-facing) with Azure Active Directory. I managed to do it separately (either I can secure the endpoints with OKTA or AAD), but they don't want to work together. As soon as I add okta-spring-boot-starter to POM (or okta-spring-security-oauth2) - AAD security stops working and endpoints are either open or secured with OKTA only. I am trying to do it using WebSecurityConfigurerAdapter implementations for okta and aad:
#Configuration
#EnableWebSecurity
public class WebSecurityConfig {
#Configuration
#Order(1)
public static class OktaAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/v1/endpoint1").authenticated()
.antMatchers("/v1/endpoint2/**").authenticated();
}
}
#Configuration
#Order(2)
public static class ActiveDirectoryAdapter extends WebSecurityConfigurerAdapter {
#Autowired
private AADAppRoleStatelessAuthenticationFilter filter;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/v1/endpoint3/**").authenticated()
.antMatchers("/v1/endpoint4/**").authenticated()
.and()
.addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class);
}
}
}
This configuration however works only for endpoint1 and endpoint2 (secured with okta), other rest points are open (as if 2nd implementation of WebSecurityConfigurerAdapter was ignored). If I remove okta package from pom, AAD configuration starts working. If I switch orders of above configurations then nothing is secured. I suspect okta package does some autoconfiguration, but can't find any information about it. What am I missing?
The Okta Spring Boot Starter is mostly just a light wrapper to help configure the existing Spring Security OAuth autoconfig with a few Okta specific bits.
My first suggestion (if possible) is to try to use Spring Security OAuth for both IdPs, as it doesn't look like the AAD starter works Spring Security's built-in OAuth support (I could be wrong, I only took a quick look). Assuming AAD is just OAuth/OIDC it will just work with a little bit of configuration.
You will still need a solution to protect your given routes 1 & 2 -> Okta 3 & 4 AAD. There are a few ways to do this. You could use scopes (assuming they are different) or some other type of "authority":
http.authorizeRequests()
.antMatchers("/your/route").hasAuthority("SCOPE_custom");
The Okta Spring Boot Starter should work with other IdPs configured with Spring Security OAuth properties: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2login-boot-property-mappings
I cannot speak 100% to what the ADD starter adds, but I'm guessing it's similar to Okta. Which is:
A common set of properties (inline with other vendor offerings)
Vendor-specific JWT validation (Spring Security only does basic JWT validation, and each vendor has its own recommendations, assuming you are using JWT access tokens)
A little sugar (for example the Okta starter adds a mapping of Okta groups to Spring Authorities)
As far as JWT validation goes Okta recommends validating JWTs like this:
https://scotch.io/tutorials/jwt-vs-opaque-access-tokens-use-both-with-spring-boot#toc-better-jwt-validation
A similar technique could be used (if needed).
Keep us posted!
In a Spring Secuity / Boot application I have multiple #Configuration annotated Configurations that extend WebSecurityConfigurerAdapter.
In one of these specific configurations, I want to protect a specific URL with basic auth. I do that by overriding configure(final HttpSecurity) and using antMatcher("myURL") onto the HttpSecurity object, followed by the usual authorization-chain and httpBasic().
But configuring basic auth in spring also requires your configuration to override configure(final AuthenticationManagerBuilder auth), where you configure an authentication-mechanism, as I understand. In my case, that is a simple inMemoryAuthentication(), with user and password of my choice.
Now, I know that some of the other configurations in the project configure the rest of the urls with a way more complex authentication-mechanism, which implement's SSO. I am not entirely sure if my configuration, which messes with the AuthenticationManagerBuilder, interferes with these other mechanisms in any way?
My expectation is that, because in configure(final HttpSecurity) I use antMatcher("myURL"), this configuration will create a SecurityFilterChain that has my specific inMemoryAuthentication() logic (somewhere deep in a spring filter that handles basic auth) and that this chain will only be used for the requests matching "myURL" pattern. I expect other filters-chains that are created by other other existing configurations and their more complex authentication mechanisms to be unaffected by my new configuration. My new inMemoryAuthentication should never play a role there. Is that correct?
I could reload application on edit with RemoteSpringApplication until I added spring security to my app,
with
#EnableWebSecurity
public class WebAuthConfig extends WebSecurityConfigurerAdapter { ..
etc
event though I added:
// TODO: this disable all security checks httpSecurity.httpBasic().disable().authorizeRequests().anyRequest().permitAll();
so all my rest calls still works without any auth,
as soon as I change the code and running RemoteSpringApplication detects the change it fails with:
Exception in thread "File Watcher" java.lang.IllegalStateException: Unexpected 403 response uploading class files
How to prevent it?
Thx
Add:
.authorizeRequests()
.antMatchers("/.~~spring-boot!~/**")
.permitAll()
.and()
to your Spring Security config near the top of your http method chain in the configure(HttpSecurity http) method and it'll disable Spring Security on the Spring Boot DevTools URL.
If you want to change this URL you can override it by changing the spring.devtools.remote.context-path property in your application.properties.
Make sure you're not running devtools in production of course!!
I am using Spring Social along with Spring Boot and Spring Security. I use Spring Social to provide authentication into our web service. This is done using the SocialAuthenticationFilter approach.
I am trying to support the ability to have a single user (ie. org.springframework.security.core.userdetails.UserDetails) have multiple Spring Social connections. This way a user could sign in with either his Google credentials or Facebook credentials.
If I go directly into my database I can make this configuration. Then I can sign into the same Spring Security account for different Spring Social connections. The problem is the point at which a user adds the new connection. I'll give a sample of what I'm doing with the assumption that I'm signed in via a Google account and want to add Facebook.
I log in via Google. Then if I load either my Spring Security formLogin().loginPage() or go straight to auth/facebook (the standard Spring Social Facebook login URL), I can perform Facebook authentication. But, the result is that my current Authentication object (from SecurityContextHolder.getContext().getAuthentication()) is an anonymous authentication user. This does make sense because I just logged in using Facebook. But at the same time I'd like to know that I'm logged in so that I could ask the user about connecting the accounts and setup the database.
How can I provide the ability to let an authenticated user add a new social account to his user account? Also, I'm not tied to a particular workflow for adding new connections; the above was just my first set of experiments.
Spring Social 1.1.4
Spring Boot 1.3.8
Spring Security & MVC - as
specified by Spring Boot 1.3.8
Update
From Jerome's suggestion I extracted the security filter chain from Spring Security debugging:
Security filter chain: [
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
CsrfFilter
LogoutFilter
SocialAuthenticationFilter
UsernamePasswordAuthenticationFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
]
This is probably not an issue with Spring Social, but rather with Spring Security. If you get an anonymous user logged in, then it means that AnonymousAuthenticationFilter is kicking in before yours, or SocialAuthenticationFilter.
Switch spring security to debug:
#EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
public void configure(WebSecurity web) throws Exception {
web.debug(true);
}
}
And check which filters are involved. I'm pretty sure you have the anonymous filter which kicks in for undesired paths.
I have been trying to get a grip on spring security and always get confused with the initial configuration. Where in few tutorial I find CSRF disabled and in few I found it enabled.
At some forum it's written as it's good to disable it and in some tutorials few people mention it's not a good practice to disable csrf.
My point is why do we need CSRF? what's the reason behind using CSRF? what if we disable it and why if we shouldn't disable it?
http.csrf()
.csrfTokenRepository(csrfTokenRepository()).and()
.addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)
and
http.csrf().disable()
.exceptionHandling().and()
.anonymous().and()
.servletApi().and()
.headers().cacheControl().and()
.authorizeRequests()
What's the best configuration if I am using Spring Security with REST? Because in second configuration it's showing me a popup window to login. And in first configuration it's giving me
(Expected CSRF token not found. Has your session expired?)
If CSFR is enabled or not depends on The Spring Security version and type of configuration used.
Before Spring Security 4, when using XML configuration CSFR would be disabled and when using Java based configuration it would be enabled. As of Spring Security 4 CSFR is enabled for both XML and Java based configuration by default.
Do you need CSFR, well if you have a public facing site or API I would say yes. Every security layer you disable makes your application more vulnerable.
What CSFR is is explained on this page