To give some context, I'm building a PWA (Progressive Web App) for myself and some friends as a test project. I'm using basic authentication.
As it is a PWA I want it to behave like other apps do, which includes not having to log in every few days keeping the user logged in. Disabling the timeout may not be the best way as it gives security risks but for now it should do just fine.
I already tried to increase the timeout setting to a high number and use the -1 value like below.
server.servlet.session.timeout=9999999999
spring.session.timeout=9999999999
and
server.servlet.session.timeout=-1
spring.session.timeout=-1
But both do not work.
This is how I configured my security:
protected void configure(final HttpSecurity http) throws Exception {
http
.headers().cacheControl().disable().and()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/api/user").permitAll()
.antMatchers("/api/*").authenticated()
.anyRequest().permitAll()
.and()
.cors()
.and()
.csrf()
.ignoringAntMatchers("/logout")
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.httpBasic()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.clearAuthentication(true);
}
As mentioned, after a few days the application will still timeout and give me an 401 error (even though the cookies still exists) which means the user has to log in again.
Does anyone know how I can make the session really long or indefinitely. And if this is not possible which other solution could I use to solve this problem?
Related
So since i'm working on spring security i've setted the headers.frameOptions to DENY, when i try this by putting my backend endpoint in an iframe which is localhost:8080 here , everything is working perfectly fine, the thing is, when i put the frontend localhost:3000 in iframe, nothing happens and the application is displayed in the iframe.
i'm thinking that the headers configuration i'm doing are applying only on APIs and not at the start of the application
at the start of the application as you can see there is no configuration : X-Frame-Options: DENY
Here after i send an API
here is the function
#Override
protected void configure(HttpSecurity http) throws Exception {
http.headers()
.httpStrictTransportSecurity()
.maxAgeInSeconds(31536000)
.includeSubDomains(true);
http.headers()
.contentTypeOptions();
http.cors().and()
.headers()
.xssProtection()
.and()
.contentSecurityPolicy("script-src 'self'")
.and()
.httpStrictTransportSecurity().includeSubDomains(true).maxAgeInSeconds(31536000)
.and()
.contentSecurityPolicy("frame-ancestors 'none'")
.and()
.frameOptions()
.deny()
.and()
.csrf()
.disable()
.formLogin().defaultSuccessUrl("/swagger-ui.html", true).and()
.authorizeRequests().antMatchers(AUTH_LIST).authenticated()
.antMatchers("/actuator/**").access("hasAnyRole('ADMIN') and hasIpAddress('127.0.0.1')")
.anyRequest().permitAll()
.and().httpBasic();
}
I finally resolved this issue by configuring the frontend web.xml file by following this
if u're using nginx as a server you can add :
Header always set X-Frame-Options "SAMEORIGIN"
if you're using any other server u can check mdn,
to conclude, if you're working on a full stack application you have to configure the server configuration file otherwise spring security won't prevent you from clickjacking.
I'm using Spring security for my project, and this is my configuration.
protected void configure(HttpSecurity http) throws Exception {
http.
authorizeRequests()
.antMatchers("/home").hasRole("USER")
.antMatchers("/edit-information/**").hasRole("USER")
.antMatchers("/admin/**").hasAnyRole("ADMIN_STAFF","ADMIN_MANAGER")
.antMatchers("/admin/employee").hasRole("ADMIN_MANAGER")
.and()
.formLogin()
.loginPage("/home/login")
.loginProcessingUrl("/j_spring_security_check")
.usernameParameter("email")
.passwordParameter("password")
.defaultSuccessUrl("/",true)
.failureUrl("/home/login-fail")
.and()
.exceptionHandling()
.accessDeniedPage("/403");
}
So it is my idea.
I want all ADMIN can log in to /admin/** but in /admin/** I have /admin/employee. I just want role ADMIN_MANAGER can log in here only.
But .antMatchers("/admin/**").hasAnyRole("ADMIN_STAFF","ADMIN_MANAGER") is already let ADMIN_STAFF log in to /admin/employee. I tried to add .antMatchers("/admin/employee").hasRole("ADMIN_MANAGER") but it did not work!
I do believe the problem is in the ordering for that antMatchers. The order of the rules matters and the more specific should come first, so instead of this:
.antMatchers("/admin/**").hasAnyRole("ADMIN_STAFF","ADMIN_MANAGER")
.antMatchers("/admin/employee").hasRole("ADMIN_MANAGER")
You can try this:
.antMatchers("/admin/employee").hasRole("ADMIN_MANAGER")
.antMatchers("/admin/**").hasAnyRole("ADMIN_STAFF","ADMIN_MANAGER")
I am using Spring Security in my Spring 4 MVC Rest API application.
I have implemented successfully the authentication process using java configurations. I have also managed to log in properly, and I have used JdbcTemplate to interface with my mysql database.
Tmy SecurityConfig.java
#Override
public void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.failureUrl("/login?error")
.loginPage("/login")
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login")
.invalidateHttpSession(true)
.and().httpBasic().and().csrf().disable();
}
I'm really struggling to understand how I should modify the above configuration to use it in a REST Api application. I need to manage the session for the android app these apis are to be used with, so that, for every request, I do not have to pass the user_id.
If anyone could possibly mention the preferred (standard) way of achieving this (with just enough details), I'll be really really glad :)
I'm using Spring Boot and Thymeleaf. I have a custom 404 template page defined in src/main/resources/templates/error/404.html
This works properly when users are logged in.
However, when they are logged out, they do not get any type of 404 page, they just get redirected back to /login.
I'm thinking my security configuration needs to change but not sure what.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/","/register*","/resetPassword","/forgotPassword","/login","/404").permitAll()
.antMatchers("/admin/**").hasAuthority("ADMIN").anyRequest()
.authenticated().and().formLogin().loginPage("/login").failureUrl("/login?error")
.defaultSuccessUrl("/dashboard").successHandler(successHandler)
.usernameParameter("email").passwordParameter("password")
.and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login?logout").and()
.exceptionHandling().accessDeniedPage("/access-denied");
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/error**","/resources/**", "/static/**", "/css/**", "/js/**", "/img/**");
}
First of all I encourage you to use indentation when using java config to configure your security for your spring application. It helps with readability.
Note all top level methods on the first indentation (authRequest,formLogin,logout) all configure/update the HTTP object it self. All these elements are from the org.springframework.security.config.annotation.web.builders.HttpSecurity class.
The children of these classes further refine the HTTP security configuration.
http
.authorizeRequests()
.antMatchers("/","/register*","/resetPassword","/forgotPassword","/login","/404")
.permitAll()
.antMatchers("/admin/**").hasAuthority("ADMIN")
.anyRequest().authenticated() // <--------
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error")
.defaultSuccessUrl("/dashboard")
.usernameParameter("email").passwordParameter("password")
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login?logout")
.and()
.exceptionHandling()
.accessDeniedPage("/access-denied");
Note .anyRequest().authenticated() is specifically stating that any request must be authenticated. So when you attempt to goto any missing url on your domain it will ask you to login rather than goto the 404 page.
So if you remove that statement it and then try an goto a missing url page it will redirect you to a 404 page.
If you remove .anyRequest().Authenticated() then you can log in without authenticated.
Therefore, do not try to delete. For example, if you go to the address "http://localhost:8080/user", then you will be taken to the authorization page. And if you try to enter the page "http://localhost:8080/user/" then you will be taken to the user page. Please note that links differ only by the forward slash at the end. Of course if you remove ".anyRequest().Authenticated()" in this case you need to add more parameters to antMatchers like "/user" and "/user/"
Therefore, be careful and attentive.
I know there are some question on stackoverflow, but nothing helped...
http
.addFilterBefore(RestConfiguration.getCorsFilter(), ChannelProcessingFilter.class)
.authorizeRequests() //Authorize Request Configuration
.antMatchers("/api/**").hasRole("API")
.antMatchers("/api/confirm/**").permitAll()
.antMatchers("/api/version").permitAll()
.anyRequest().authenticated()
.and() //HTTP basic Authentication only for API
.antMatcher("/api/**").httpBasic()
.and() // angularjs requires csrf
.addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class)
.csrf().disable();
I've a api path with some sub paths. But I want to access two of them without basic auth (confirm/** and version).
How can I do that? I always get the login dialog.
You should use antMatchers("/api/**").hasRole("API") rule after /api/confirm/** and /api/version. Current ordering is not quite right:
.antMatchers("/api/confirm/**").permitAll()
.antMatchers("/api/version").permitAll()
.antMatchers("/api/**").hasRole("API")
To sum up, if you want to only secure /api/* and let public access on /api/confirm/**, /api/version and all other paths without api prefix, you should have a HttpSecurity config like this:
http
// Same as before
.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/api/confirm/**").permitAll()
.antMatchers("/api/version").permitAll()
.antMatchers("/api/**").hasRole("API")
.anyRequest().permitAll();
// Same as before