My friend and I are making a Java spring boot application for University practice. Its front is on Firebase, and the API is on Heroku
The problem is the following, I configured Spring Security as follows:
#Override
protected void configure(final HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.authorizeRequests()
.antMatchers("/admin/**", "/bid/getBids", "/bid/{id}", "/purchase/create",
"/purchase/{id}", "/purchase/question/{questionId}/answer").hasAuthority("ROLE_ADMIN")
.antMatchers("/registration/**", "/registration").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.formLogin()
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/").deleteCookies("JSESSIONID")
.invalidateHttpSession(true);
}
While I'm testing the API on Heroku via swagger/postman, everything works fine, including role restrictions.
But when it tries to set up authorization via the /login path, it redirects to the swagger-ui page, because that's how I set it up. I rewrote the redirect to its main page on Firebase, but the session doesn't work that way, apparently because cookies are saved to the address of my application on Heroku.
Please tell me how I can configure Spring Security so that its site saves user sessions during authorization, and the site works normally with my API?
I use a translator for some phrases, sorry about that
Your frontend and backend applications are served on different domains and HTTP cookie information is stored for only the specific domain. So I think you can easily serve your static page (or single page application resources) by putting under src/resources/static of your spring boot application. By doing this you can also restrict your front-end application and allow for only authorized users. If you want to serve the front-end application on firebase and backend on Heroku you should forward it to the upstream host by configuring rewrite rules in the firebase.json file (https://firebase.google.cn/docs/hosting/full-config?authuser=0#rewrites).
Related
Trying to setup login authentication with Spring Boot starter 2.3.0 and Spring Security 5.3.2
My loginController was working initially a /login POST request
Then I added Spring Security and a UsernamePasswordAuthenticationFilter, and other classes to authenticate that I copied from other apps and it works.
It's going out and authenticating the username and password but it doesn't go through the Controller /login method. It seems to just skip it (sysout logs aren't showing). But if I remove the method then it doesn't work (so it's like it has to be there but doesn't go into it).
#Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.cors()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().authorizeRequests()
.antMatchers(SecurityConstant.PUBLIC_URLS).permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(
// authenticationFilter(),
jwtAuthorizationFilter,
UsernamePasswordAuthenticationFilter.class);
Has anyone experienced anything like this before? Thanks, appreciate any help, trying to learn Spring Security
I'm trying to use create-react-app to start the frontend for my spring-boot project.
I use redis to store sessions.
For some reason I actually need to enable session generation for anonymous users.
The following code is my security config for spring boot:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
//#formatter:off
http
.formLogin()
.loginPage("/login")
.permitAll()
.loginProcessingUrl("/form-login")
.and()
.cors()
.and()
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/restricted/**")
.authenticated()
.antMatchers("/**")
.permitAll()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.ALWAYS);
//#formatter:on
}
}
I've tested this by having a very simple index.html inside the "static" folder under my spring-boot project. Then I go to "http://localhost:8080" and I saw the session cookie.
Then I removed "index.html" file and start the react app with proxy config. By default the new url is "http://localhost:3000". I do see the default reactjs startup page but I no longer get any session cookies.
My proxy setting in "package.json" for my create-react-app is as follows:
"proxy": "http://localhost:8080"
I also tested that I can still get session cookie only if I directly go to "http://localhost:8080" instead of port 3000.
Any help is appreciated. Thanks so much in advance.
Okay people, after waiting for a couple days without any answers I did some research myself and found the answer. I decided to post the answer here in case other people having the same issue.
The issue with create-react-app proxy is that it is a forward proxy. So the session cookie doesn't really work well with forward proxy. Sadly there is no easy solution solving this issue but there is a workaround.
As I mentioned above, I can for sure get the session cookie by directly accessing the backend url. So if I want to get the session cookie by using the proxy, I should put some code in the frontend to access the backend first and then put the session cookie in the header whenever the app starts. Then keep monitoring the frontend and reacquire the session whenever it expires.
For the best practice, the backend should really have a mock service which has no session, no login and no tokens but mocked data. Because the frontend doesn't really care about how session, access token or login works, these are the backend jobs. The frontend just need to get the data and then display the data.
But in reality having a mock server may take time and it is not worth doing that for every thing case.
So if you do not want to write the mock server, you either go with proxy but have a little hack in your frontend to actually acquire the session. Or you build the entire frontend app and put it under the "static" folder in your spring boot app.
For me I would rather separate the frontend and backend rather than putting them all together.
I have spring boot app with OAuth2. I want to open a few endpoints for anonymous access. I can do it using:
http
.authorizeRequests()
.antMatchers("/xyz/**").anonymous()
.and()
.authorizeRequests()
.anyRequest().authenticated();
but is there any way to do it more selectively and open only specific endpoints by putting some annotations there? I tried #PermitAll but it still requires authentication.
You can use antMatchers("/YOUR_ENDOINT/**").permitAll();
I am configuring endpoint access in Spring Security. What I want to accomplish:
Everyone has access to resources
Everyone can login/register
Only authenticated users can access logout and all other mapped endpoints
Here is my configuration, it fulfills firs two requirements and prevents access to /logout for non-logged users.
http.authorizeRequests()
.antMatchers("/register").permitAll()
.antMatchers("/register/*").permitAll()
.antMatchers("/favicon.ico").permitAll()
.antMatchers("**/*.html").permitAll()
.antMatchers("**/*.css").permitAll()
.antMatchers("**/*.js").permitAll()
.and()
.formLogin().loginPage("/login").failureUrl("/login-error").defaultSuccessUrl("/")
.usernameParameter("username").passwordParameter("password")
.and()
.logout().logoutSuccessUrl("/login").deleteCookies("JSESSIONID").logoutUrl("/logout");
to ensure that request to your application requires the user to be authenticated use
.anyRequest().authenticated()
We're currently attempting to add SAML integration to our project and one of the requirements is that an administrator can use the system to add authentication to a part of the website.
For instance, if the app was hosted at "foo.com" then they would be able to specify that all pages that start with "foo.com/secret" should be authenticated using SAML.
I know how this can be done statically on system start up but I'm struggling to find any information on how to alter the Spring Security settings at runtime.
I'm currently trying to test this out on the example saml project which can be found here: https://github.com/vdenotaris/spring-boot-security-saml-sample
The configure method of the WebSecurityConfig class looks like the following:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.authenticationEntryPoint(samlEntryPoint());
http
.csrf()
.disable();
http
.addFilterBefore(metadataGeneratorFilter(), ChannelProcessingFilter.class)
.addFilterAfter(samlFilter(), BasicAuthenticationFilter.class);
http
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/error").permitAll()
.antMatchers("/saml/**").permitAll()
.anyRequest().authenticated();
http
.logout()
.logoutSuccessUrl("/");
}
I want to be able to add an additional antMatcher for a new URL that is authenticated. I've been able to change the http object at runtime but this has no effect on the security.