How to configure web security in spring security to allow some url to access? - spring

How to configure WebSecurity in java based to allow some urls to be accessed. i tried as below
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeUrls()
.antMatchers("/rest/**").permitAll().antMatchers("/admin/**").hasRole("ADMIN");
}
Here on above i want to allow "/rest/" **to all (it means this url should not be under security) and "/admin/**" should be secured and have authority of Admin. FYI i am using this with Spring oauth too so "/oauth/token" also should be accessible to all.

Try this to make all urls that you need open by admin scope:
http.authorizeRequests()
.antMatchers("/admin/**").access("hasRole('ADMIN')")
I think you do not need to specify urls that are not have access permission in your configure method because they will be accessed normally.

Related

Spring security is blocking Vue.js pages | receiving 403 error

I have a Spring/Vuejs project that couples the frontend and backend into one warFile and for some reason the Spring Security setup I have blocks the Vue.js pages when I run the warFile.
When I have the Configuration set this way, it blocks the pages -
#Override
public void configure(HttpSecurity security) throws Exception {
security.csrf().disable()
.cors().and()
.authorizeRequests()
.antMatchers("/api/v1/authenticate", "/api/v1/register").permitAll()
.anyRequest().authenticated().and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
security.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
When I have it set up this way, it shows the pages AND the data from my api's (it creates the JWT but still allows the api calls without Authorization) -
#Override
public void configure(HttpSecurity security) throws Exception {
security.csrf().disable()
.cors().and()
.authorizeRequests()
.antMatchers("/api/v1/authenticate", "/api/v1/register", "/**","/css/**","/js/**").permitAll()
.anyRequest().authenticated().and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
security.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
When I have it setup the first way and run the frontend and backend on different ports, it works perfectly. It shows the pages and blocks all API calls that don't have an authorized JWT.
I want the same type of result with backend/frontend in the same warFile
Is there a solution for this???
When I have it setup the first way and run the frontend and backend on different ports, it works perfectly.
I wonder if this is due to the CORS policy being invoked. Otherwise, Spring Security doesn't take the port number into consideration when making authorization decisions.
When I have the Configuration set this way, it blocks the pages -
That's because you have this line:
.anyRequest().authenticated()
It means that any URL, including JS files, will require authentication.
When I have it set up this way, it shows the pages AND the data from my api's
That's because you have this line:
.antMatchers("/**").permitAll()
It means that any URL is permitted.
The DSL processes URLs in the order the paths are declared. I think you want a hybrid of the two. Something like this:
.antMatchers("/api/v1/authenticate", "/api/v1/register", "/css/**","/js/**").permitAll()
.anyRequest().authenticated()
This means that the two /api endpoints all /css endpoints and all /js endpoints won't require authentication, but everything else will.
Consider making the permitAll as narrow as you can -- it's not clear to me whether you really want all your JS files to not require authentication.
#jzheaux your root comment led me to the answer.
This was the change I made and it works just as I need it to now. Thanks for the guidance!
#Override
public void configure(HttpSecurity security) throws Exception {
security.csrf().disable()
.cors().and()
.authorizeRequests()
.antMatchers("/api/v1/authenticate","/api/v1/register","/static/**","/").permitAll()
.anyRequest().authenticated().and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
security.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}

My heroku app is requesting a password that I did not put there

I'm new to the process of sending an application to production and I'm using Heroku free plan to test. Today I went to check my app and the API I made using Spring boot is not working and is requesting a login that I didn't do. My app address is https://erik-financial-api.herokuapp.com and when you go there it redirects you to the address https://erik-financial-api.herokuapp.com/login with the following:
I did not make this page and none of the passwords (from my app or from my Heroku account) work on it. This was supposed to be just a REST API for another front-end app. Does anyone know why is this happening?
The code for this project can be found on my GitHub on https://github.com/esscheffer/financial-api
Edit: this seems to be a default spring security login page. I have searched for solutions, but none worked so far. What I have tried:
Add
override fun configure(security: HttpSecurity) {
security.httpBasic().disable()
.formLogin().disable()
}
to my WebSecurityConfigurerAdapter class.
Add http.httpBasic().disable().formLogin().disable() to the configure of my ResourceServerConfigurerAdapter class.
Add (exclude = [SecurityAutoConfiguration::class]) to the #SpringBootApplication sanitation on my application class.
The first 2 tries didn't remove the login page and the last one broke the app, returning 404 for all pages. Note that this only happens when I deploy my application to Heroku. When running locally I don't have this login page or any other problem.
Add a new configuration class com.scheffer.erik.financial.api.config.SecurityConfig, where in the configure method you can disable the HTTP Basic authentication as well as login form based authentication, like below:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity security) throws Exception {
security
.httpBasic().disable()
.formLogin().disable();
}
}
Do it like this...permit all requests for the home page...I hope it will work for you.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().
authorizeRequests()
.antMatchers("/").permitAll() //OR .antMatchers("/**").permitAll()
.anyRequest().authenticated();
}

Spring Boot Security without Login Form

I want to add security to a Spring Boot application so I thought about using Spring Security. My only problem is the Login Form, Is there some way to authenticate a User by reading the login credentials from a config file instead of letting someone type in the name and password? I want to do that because the application will be running on a Raspberry Pi. What would be the best approach for something like that?
You can use basic authentication and pass username and password in the header.
The configuration could look like this:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/dashboard/**").permitAll()
.anyRequest().authenticated()
.and().httpBasic();
http.csrf().disable();
}
From the client you have to add the header:
Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
The string behind Basic is the Base64 encoded username:password

Protect specific resources id with OAuth2 on Spring Boot

I have a working OAUTH2 implementation on Spring Boot, with AuthorizationServer and ResourceServer on the same implementation, using password grant.
About the server:
The TokenStore is custom and uses a WebService to store the token remotely.
I have a custom AuthenticationProvider.
This works for controlling access to resources based on given authorities, for instance, in the ResourceServer config:
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/api/resource/**")
.hasAnyAuthority("USER", "ADMIN")
.antMatchers("/api/admin/**")
.hasAnyAuthority("ADMIN");
}
Now, I need to control that USER can access to "/api/resource/1" but not "/api/resource/2", this IDs can change and I fetch the list during the authentication.
I've tried to add the ID's list to OAuth2AccessToken additional information and adding a custom filter in the ResourceServer configuration but it always comes empty.
So, How's the proper way for implementing this without using JWT?
After some thinking and research, If someone is trying to achieve something similar, this is what I'll do:
Map the allowed ID's to authorities, e.g. ID_201 and the modules as roles, so I will have a ROLE_ADMIN.
It's possible to refer to path variables in Web Security Expressions, as explained in here. So the idea is to pass the variable (resource id) and check whether it's allowed or not.
public class WebSecurity {
public boolean checkResourceId(Authentication authentication, int id) {
//check if the list of authorities contains ID_{id}.
}
}
And in the Web Security config:
http
.authorizeRequests()
.antMatchers("/resource/{resourceId}/**").access("#webSecurity.checkResourceId(authentication,#resourceId)")
...
If you're working on Spring Boot with spring-security 4.0.4 be sure to upgrade to 4.1.1 as reported in this bug.

how to implement a authentication with spring boot security?

i am using spring boot. i want to post a username and password params to login, and if login success then return a token. after, i will use the token to judge login status. here is my security configure code. but i don't konw where to write the login authentication logic code.
SecurityConfig.java
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest()
.fullyAuthenticated()
.and()
.formLogin()
.loginPage("/user/unlogin")
.permitAll();
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/user/login")
.antMatchers("/user/logout")
.antMatchers("/user/register");
}
}
==========================
thank you !
There's always more than one way to do something with Spring. There is a happy path (probably) with Spring Boot, and you seem to have started on it. Note though, if you want Boot to provide some default behaviour, then don't use #EnableWebSecurity (as advised in the user guide). The web-secure sample has an example you can follow.
If you use formLogin() the default login URL is /login (not /user/login), so you should be able to post the username and password to that endpoint to authenticate. Don't add /login to the unsecured paths using web.ignoring() or Spring Security will never process it. When you post to /login you get back a JSESSIONID cookie. That's your authentication token, and it expires when the session expires in the server (30min by default, but easily configurable). Include it in future requests for secure resources - some HTTP clients will even do that for you (like a browser does).

Resources