Spring Security disable security for requests made FROM a certain url - java

my application uses spring security. I know you can use antMatchers to permit requests for some URI that are mapped into your application. But I need too allow requests made from an external api to a URI in my application and just for that api. I need something like this:
#Override
protected void configure(WebSecurity web) throws Exception
{
web.ignoring()
.antMatchers("http://externalTestApi.com");
}
Does anybody know if this is possible? I did not find anything on this.

You can do something like this (if you want to combine multiple conditions)
.authorizeRequests()
.antMatchers("/user/list")
.access("authenticated or hasIpAddress('666.666.666.666') or hasIpAddress('127.0.0.1') or hasIpAddress('0:0:0:0:0:0:0:1')")
or
.authorizeRequests()
.antMatchers("/user/list")
.hasIpAddress("0.0.0.0/0");

Related

Adding Spring Boot Keycloak configuration of HTTP requests

Currently in my SecurityConfig.java class file where I define my KeycloakWebSecurityConfigurerAdapter I want to define so that every GET request can be done by two different roles. But only one role can do the other types of HTTP requests (POST, PUT, PATCH etc). How can this be achieved in my code below:
#Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests()
.antMatchers(HttpMethod.GET).hasAnyRole("user", "admin")
.anyRequest().hasRole("admin");
}
What happens is that when trying to do POST request I get access denied 403. GET requests works fine. Any ideas?
You should disable csrf on your configure method :
public void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.csrf().disable().authorizeRequests().anyRequest().authenticated();
}
}
You should not use KeycloakWebSecurityConfigurerAdapter nor anything else from Keycloak libs for Spring, it is deprecated.
Instead, you can follow this tutorial which proposes two solutions based on:
spring-boot-starter-oauth2-resource-server which requires quite some Java conf
spring-addons-webmvc-jwt-resource-server which enables to configure most of security from properties (way simpler than preceding)
All tutorials linked here show how to map Keycloak roles to spring-security authorities (and will keep CSRF protection enabled, even for stateless resource-servers).

Spring security requests authorization

I am new to spring security and was checking how to authorize requests to URLs in my application.
According to the documentation here, we add authorization as follow:
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**", "/signup", "/about").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
.anyRequest().authenticated()
.and()
// ...
.formLogin();
}
As this method worked fine for me, I was wondering if there's another dynamic way to specify this configuration. By using some sort of annotations for our REST controllers for example?
I have a solution in mind that would be really practical, but I wanted to make sure that there's no other way to do this before starting to develop my own code.
Thank you for your help.
Yes there is an annotations as #Secured/#PreAuthorize/#PostAuthorize. this annotations are preferred way for applying method-level security, and supports Spring Expression Language out of the box, and provide expression-based access control.
for e.g
#PreAuthorize("hasRole('ADMIN')")
public String yourControllerMethod() {
return response;
}
for detail check here.
The only other way is to use the #Secured/#PreAuthorize/#PostAuthorize annotations. But you must put them on all webservices you want to secure.
Usually, when I build a webservices application, I like to authorize all requests on the WebSecurityConfigurerAdapter, and then secure requests one by one with these annotations.

Spring Security - doesn't access database

I am using spring boot and very new to spring security, but I wanted basic security to my web application. What I did was add on my pom.xml the needed dependencies and added this java class to my project:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/**","/event/**","/ticket/**")
.hasRole("USER")
.and()
.formLogin();
}
}
After running my web application, I run into the login page, where I put user/password and then it goes to my web application. However, the commands don't work. I am pushing some buttons that should send signals to my MySql database, but nothing happens. It's like the front-end isn't connected to the back-end anymore. I am using AngularJS for front-end and a View Controller that navigates between pages. Rest of the application is REST-based. Any idea why this might happen?
Later Edit: Now I understand, the problem that I have is that after authenticating, I get 403 status codes on my end-points. Any idea how I might fix it?
Later Editv2: Looks like I don't get authorized on my POST requests, my GET ones work fine...here are some of my POST end-points: /event/buy_ticket/{id} , /ticket//cancel_ticket/{id}
angular.min.js:101 POST http://localhost:8080/event/buy_ticket/2 403 ()
I even tried to explicitly say it to permit it, but I still get 403...
http.authorizeRequests()
.antMatchers("/**","/event/**","/ticket/**","/event/buy_ticket/2")
.permitAll()
.and()
.formLogin();
Later later later edit:
Disabling csrf worked
Getting 403 Forbidden error codes means that Spring is receiving your requests but choosing to stop processing them. From the Wiki page on HTTP 403:
Authentication was provided, but the authenticated user is not
permitted to perform the requested operation.
If I had to wager, I would say the problem is that you have not specified what resources and endpoints should be accessible and how. If memory serves me right, Spring Security will, by default, lock down everything super tightly so you need to explicitly tell it what to leave open. Below is a sample from my own security configuration:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests() // require authorization
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll() // for the CORS preflight check
.antMatchers("/login", "/api/open/**", "/resources/**").permitAll() // the open API endpoints and resources
.antMatchers("/logout", "/api/secured/**").authenticated(); // lock down these endpoints
...additional configurations...
}
All endpoints that should be freely available are prefaced with "/api/open/" while all endpoints that should be protected by Spring Security are prefaced with "/api/secured/". The exceptions are the logout and login endpoints, since those tie into Spring Security directly.
Here's a great blog post - and the related repo - that shows off how to implement Spring Security that plays nice with AngularJS, even as a Single Page Application, which are notoriously annoying to secure.
Edit: You might be running up against CSRF protection, which is enabled by default in Spring Security - see this post. CSRF will allow HTTP "safe" methods like GET, HEAD, and OPTION but block "unsafe" methods like PUT, POST, DELETE, etc if those methods do not provide the proper token (since no CSRF was configured, those request don't have a token -> blocked). For testing purposes, you can disable it by adding http.csrf().disable() to the configure() method.

Allow all URLs but one in Spring security

I would like to protect just a single URL, while allowing anonymous access for everything else.
The Java configuration examples i'm seeing in the internet all seem to indicate that you need to explicitly permitAll each and every URL, and appropriate hasRole for URLs that need to be protected. This in my case, creates a really unwieldy java code which I have modify every time I add a new URL to the application. Is there an easier java configuration that I can use.
And note also that in my case, the URL i'm protecting is a sub-resource, say employee/me, I would like employee/list, etc., to be anonymously accessible.
If you're using Java Configuration, you can use something like following in your configure method:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/employee/me").authenticated()
.antMatchers("/**").permitAll();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/employee/me").authenticated()
.antMatchers("/**").permitAll();
}

Spring boot csrf filter

I was trying to enable csrf filter for some specific api calling and for the others no need of csrf filter.What I have done is
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().antMatchers("/public/**").permitAll();
http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint);
http.csrf().disable().addFilterBefore(new StatelessCSRFFilter(), CsrfFilter.class).authorizeRequests().antMatchers("/rest/**").permitAll();
}
The problem is when I was calling localhost:8080/public/hello
An error was showing
"message": "Missing or non-matching CSRF-token"
I am using Spring boot and Spring Security.
Thanks for any help.
http.antMatcher("/public/**").authorizeRequests().anyRequest().permitAll();
http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint);
http.antMatcher("/rest/**").addFilterBefore(new StatelessCSRFFilter(), CsrfFilter.class).csrf().disable();
Or you can do like this.I think both will be working.
http.antMatcher("/public/**").csrf().disable();
http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint);
http.antMatcher("/rest/**").addFilterBefore(new StatelessCSRFFilter(), CsrfFilter.class).csrf().disable();
Try changing http.csrf().disable() to http.antMatcher("/public/**").csrf().disable() and http.antMatcher("/rest/**").csrf().disable(). You will likely have to put those two lines each in their own WebSecurityConfigurerAdapter.
That will tell Spring-Security to create multiple HTTP Security Filter Chains (akin to having multiple <http/> blocks in the XML model).

Categories