Setting session timeout in spring boot application using google App Engine - spring-boot

I have a spring boot application which is being deployed in google app engine.
I have a requirement of setting session time out on condition basis.
I tried attaching a successHandler in spring security configuration as
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
.and()
.successHandler(successHandler())
}
And here is the success handler
private AuthenticationSuccessHandler successHandler() {
return (httpServletRequest, httpServletResponse, authentication) -> {
httpServletRequest.getSession().setMaxInactiveInterval(10);
};
}
I figured out that google app engine uses jetty server (jetty 9 actually) and
it frequently keeps storing the created sessions in memcache and datastore.
some how app engine does not honor the session time out set by calling
httpServletRequest.getSession().setMaxInactiveInterval(10);

Related

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();
}

How to single sign out on Spring mvc application enabled SSO using Spring OAuth2?

I'm developing a spring web app with SSO architect by using Spring OAuth2
2 spring mvc web apps
1 authorization server is responsible for SSO and issue/check tokens
1 resources server serving /api/me
Everything works well when single signing on, but I don't know how to Single Sign Out (1 app logs out, other apps log out as well). Currently, it seems that every apps with mimimum config like code snippet below is using different session storage, and after successful authentication, it saves the authenticated session in its own session storage, and every subsequent requests is intercepted with the session in cookie. So when sso-server logging out it cannot invalidate related sessions on others app session storages. Anyone could suggest me some strategies for Single Sign Out?
Web client application.yml file:
security:
oauth2:
client:
clientId: metlife_monitor
clientSecret: password
accessTokenUri: http://localhost:8668/sso-server/oauth/token
userAuthorizationUri: http://localhost:8668/sso-server/oauth/authorize
tokenName: oauth_token
resource:
userInfoUri: http://localhost:8688/api/me
Web Application class:
#SpringBootApplication
#EnableOAuth2Sso
#EnableJdbcHttpSession
public class Application extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/**")
.authorizeRequests()
.antMatchers("/", "/login**", "/error**", "/webjars/**").permitAll()
.anyRequest().authenticated()
.and().logout()
.logoutUrl("/logout")
.logoutSuccessUrl("http://localhost:8668/sso-server/logout")
.invalidateHttpSession(true)
.deleteCookies("client-session", "JSESSIONID")
.permitAll()
.and().csrf().disable()
;
}
public static void main(String[] args) {
SpringApplication.run(App1Application.class, args);
}
}
There's difference between a Single-Sign-On(SSO) server and a Central-Authentication-Server(CAS). If the your auth server does not manage any sessions, it stops being an SSO server and just becomes a CAS.
In your case you can have your SSO server manage sessions and it can also distribute a session id that Resource Servers would verify with it before servicing the request. It does lead to a chatty system though. If you can live with a little latency post session-expiry, then you can make very short-lived tokens that are attached to the SSO and would not have to verify the token with every request, you'd only refresh a token is there's still a valid session.
If you can, consider using Keycloak. It has adapters for Java and Javascript applications as well

How to reload the Configure method of WebSecurityConfigurerAdapter when the application is up and running

I am using spring boot and in spring security we are using "WebSecurityConfigurerAdapter" and using the method
#Override
protected void configure(HttpSecurity http) throws Exception {
AuthenticationFilter authenticationFilter = new AuthenticationFilter(authenticationManager(), tokenService(), externalServiceAuthenticator());
http.addFilterBefore(authenticationFilter, BasicAuthenticationFilter.class)
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().authorizeRequests().antMatchers(externalServiceCaller.getPrivateEndPoints())
.hasAnyAuthority(externalServiceCaller.getAllAuthorities()).anyRequest().authenticated()
.and().authorizeRequests().anyRequest().anonymous()
.and().exceptionHandling().authenticationEntryPoint(unauthorizedEntryPoint())
.and().exceptionHandling().authenticationEntryPoint(forbiddenEntryPoint());
}
This is working fine for existing role and user but when we are adding more users and role at run time (After the application start) then spring security is not able to recognize new role and new user . Is there any way to call the above method again when the application is up and running.
Reload configure(HttpSecurity http) is impossible in runtime, because it's some kind of builder and it's creates some part of the spring security chain when the application is starting - if you'd like to reload the method you have to replace the spring security chain during runtime - it's not so easy and recommended way.
If you need add some user during runtime - implement custom AuthentificationProvider

Spring Boot, Elastic Beanstalk error, no issue from the IDE

I'm currently using continuous integration in order to automatically set up and configure the servers. Unfortunately I'm running into issues when the Elastic Beanstalk Tomcat 8 initializes. I get the following error only when running from AWS, it runs fine in my ide:
Caused by: java.lang.NullPointerException: null
at org.springframework.security.config.annotation.web.builders.HttpSecurity.addFilterBefore(HttpSecurity.java:1112) ~[spring-security-config-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at uk.co.thinkinnovate.security.WebSecurityConfig.configure(WebSecurityConfig.java:41) ~[WebSecurityConfig.class:na]
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.getHttp(WebSecurityConfigurerAdapter.java:199) ~[spring-security
And the block of code with the issue:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf()
.disable()
.addFilterBefore(tokenProcessingFilter(),
BasicAuthenticationFilter.class)
.addFilterBefore(new SimpleCORSFilter(),
AuthenticationTokenProcessingFilter.class)
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().exceptionHandling();
}
#Bean
public AuthenticationTokenProcessingFilter tokenProcessingFilter() {
System.out.println("Getting token processing filter.");
System.out.println(this.tokenBasedRememberMeService);
return this.tokenBasedRememberMeService;
}
Why is the TomCat version not autowiring the tokenBasedRememberMeService but my Spring Boot application is?
Thanks guys.
Edit:
Just a weird note: "Getting token processing filter" only calls in the AWS app and is null whereas in the IDE and Spring Boot it does not appear.
I feel I'm missing some key concept here.
This issue was so simple!
Make sure your application class extends SpringBootServletInitializer implements InitializingBean

Spring boot actuator secure services does not work fine

I an Trying to secure spring actuator services /manage context path when calling for example:
http://localhost:9091/manage/metrics
with this config in my yalm.properties
management:
port: 9091
address: 127.0.0.1
context-path: /manage
security:
enabled: true
role: ADMIN.
Git branch with security actuator service layer
but access to every service is still free.
Spring security config:
'#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/pizzas","/info","/addPizza").hasAnyRole("USER","ADMIN").and().authorizeRequests().antMatchers("/users","/addUser").hasRole("ADMIN").and().authorizeRequests().antMatchers("/static/**","/logout","/login").permitAll();
http.formLogin().loginPage("/login").failureUrl("/login?error").permitAll();
http.logout().logoutSuccessUrl("/?logout").deleteCookies("remember-me").permitAll();
http.sessionManagement().maximumSessions(1).
expiredUrl("/?expired").maxSessionsPreventsLogin(true).and()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
}
/**
* Configure global security with Bccyptenoncder and custom userDetailService with Spring Security
* #param auth
* #throws Exception
*/
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsServiceImpl).passwordEncoder(passwordEncoder());
}
/**
* Bcrypt password encoding configuration, more info at http://www.baeldung.com/spring-security-registration-password-encoding-bcrypt
* #return
*/
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
'
Spring boot team has resolved me this issue. I share the solution here:
Same Origin Policy
You cannot use the login page from your main Spring Application within actuator security. The reason is that the cookie is going to be associated with the domain + port + context path of the application. This is part of the Same Origin Policy
This means if you sent the user to localhost:9090/pizza/login and authenticated, when you visited localhost:9091/manage/ the JSESSIONID cookie would not be submitted to the management application which means you would not be seen as authenticated.
In order to authenticate across domains (i.e. different ports in this case) you would need some single sign on (OpenID, CAS, SAML, etc) mechanism.
Mapping a Login Page in the Management Application
In order to use this configuration you would need to setup a login page within the management application. To do this you would just need to return an HTML form when /login is requested. However, I'm not really certain how you would do that within the Boot management application. Perhaps #philwebb or #dsyer can elaborate on how one would do that.
Distinct Security Configuration for the Management Application
Alternatively you could create separate security configuration for the management application that allows authenticating with Basic Authentication. To do this you would create another Security Configuration that looks something like this:
#Order(0)
#Configuration
public class ManagementSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.requestMatchers()
.requestMatchers(request -> "/manage".equals(request.getContextPath()))
.and()
.authorizeRequests()
.anyRequest().hasRole("ADMIN")
.and()
.httpBasic();
}
}
This would make sure that if the context root is "/manage" that this security configuration is used. A few points of interest:
#Order(0) makes sure the configuration occurs before your other security configuration since by default any subclass of WebSecurityConfigurerAdapter will be ordered at 100. This is important because only the first WebSecurityConfigurerAdapter is used (similar to the authorizeRequests() matchers).
The request matcher is using a lambda for matching on the contextPath. I had thought there was a better way to distinguish Spring Boot application from the main application, but it does not appear that is the case. Perhaps #dsyer knows how this should be done.
NOTE
You can rewrite your configuration much more concisely as:
http
.authorizeRequests()
.antMatchers("/pizzas","/info","/addPizza").hasAnyRole("USER","ADMIN")
.antMatchers("/users","/addUser").hasRole("ADMIN")
.antMatchers("/static/**","/logout","/login").permitAll()
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/?logout")
.deleteCookies("remember-me")
.permitAll();
You might consider reading Spring Security Java Config Preview: Readability for details on how to format the configuration to better read it too.

Resources