Good morning.
We are developing an application which needs access to the internet for reaching the OAuth2.0 server. The problem is, that the configuration of the cloud blocks all internet access, which is not handled by a proxy. For authentication with the proxy we are provided with some credentials. Using the newest Spring boot version and the newest version of Spring Security, the whole team (hobby devs, and free / hobby project, nothing commercial) has no idea on how to setup the SpringSecurityOAuthFilterChain to make all OAuth calls using the proxy with credentials.
Here is our current FilterChain
http //
.authorizeHttpRequests() //
.requestMatchers(PAGE_AUTH_SSO_LOGIN, PAGE_AUTH_ERROR, LOGIN_OAUTH2_CALLBACK_URL,
AuthenticationUtils.FAILURE_OAUTH_LOGIN_CALLBACK,
SpringConstants.ACTUATOR_HEALTH_URL).permitAll() //
.anyRequest().authenticated() //
.and() //
.oauth2Login() //
.loginPage(PAGE_AUTH_SSO_LOGIN)//
.successHandler((request, response, authentication) -> //
response.sendRedirect(SUCCESSFUL_OAUTH_LOGIN_CALLBACK)) //
.failureHandler((request, response, authentication) -> //
response.sendRedirect(AuthenticationUtils.FAILURE_OAUTH_LOGIN_CALLBACK)) //
.and() //
.logout() //
.logoutUrl(LOGOUT_URL) //
.logoutSuccessUrl(
"/oauth2/authorization/logout?redirect_uri=http://localhost:8090/page/auth/ssoLogin.xhtml") //
.clearAuthentication(true) //
.invalidateHttpSession(true) //
.deleteCookies(JSESSIONID) //
.and() //
.csrf().disable();
Setting the parameters for the JVM did not work. Can someone give us a hint or a working example on how to solve this problem?
Version of spring boot and spring boot security 3.0.1
Version of spring-boot-starter-oauth2-client: 3.0.1
Related
I have a Spring Boot application, it use OAuth2 authentication from WSO2 Identity Server.
When I run the aplication on Spring Tool Suit, it works, so i can sing in and use my web site.
But when I run my application on Tomcat(9.0), I try access a page, and redirect to login page, and when i try to sign in, I get the error ERR_TOO_MANY_REDIRECTS
Error Example: When my spring boot app is runing on Tomcat, and I try to access the html page: https://domain/chat/example.html
if the user was not authenticated,
redirects to login page WSO2 Identity Server:
https://domain/is/authenticationendpoint/login.do
after login, the page redirects to the urls below, and does not redirect to url(https://domain/chat/example.html)
https://domain/is/oauth2/authorize
https://domain/chat/oauth2/authorization/wso2
https://domain/chat/login/oauth2/code/wso2
https://domain/chat/login
These pages return the error ERR_TOO_MANY_REDIRECTS.
A user can authenticate, but the application redirect and go to a loop that causes the error, the loop is between the urls 1,2,3,4.
Tomcat Log
Spring Boot Configurations:
LoginController.java
#Controller
public class LoginController {
#GetMapping("/oauth-login")
public String getLoginPage(Model model) {
return "redirect:/oauth2/authorization/wso2";
}
}
ConfigSecurity.java
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)//abilitar seguranca nos metodos
public class ConfigSecurity extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/oauth-login")
.permitAll()
.anyRequest()
.authenticated()
.and()
.oauth2Login().loginPage("/oauth-login")
.and()
.logout().logoutUrl("/applogout");
}
}
application.properties
server.port=8443
spring.security.oauth2.client.registration.wso2.client-name=WSO2 Identity Server
spring.security.oauth2.client.registration.wso2.client-id=asdasd
spring.security.oauth2.client.registration.wso2.client-secret=asdasd
spring.security.oauth2.client.registration.wso2.redirect-uri=https://domain/chat/login/oauth2/code/wso2
spring.security.oauth2.client.registration.wso2.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.wso2.scope=openid
#Identity Server Properties
spring.security.oauth2.client.provider.wso2.authorization-uri=https://domain/is/oauth2/authorize
spring.security.oauth2.client.provider.wso2.token-uri=https://domain/is/oauth2/token
spring.security.oauth2.client.provider.wso2.user-info-uri=https://domain/is/oauth2/userinfo
spring.security.oauth2.client.provider.wso2.jwk-set-uri=https://domain/is/oauth2/jwks
This is my git: https://github.com/Mingato/Root2
I followed the tutorial: https://medium.com/#piraveenaparalogarajah/secure-your-spring-boot-application-with-wso2-identity-server-8140af8aa30b
When I run a .jar file it works but when I run a .war file on tomcat it does not work.
After many researchs, i found my mistake. My Configurations is right, but when i run my Spring boot app on Tomcat, i have to configure my application to run on it, but there are another way, I run my app in the easiest way, I generate the .jat and execute with the command bellow
java -jar myapp.jar
So I remove the Tomcat Server to deploy my spring boot applications.
I have a 'legacy' application build with Vaadin 8 that I need to secure with Keycloak.
Unfortunately, the redirect to Keycloak is not even triggered.
As a test, I created a Spring Boot application and tried to secure it with Keycloak without any problems, but it fails to work with Vaadin 8.
My configuration files for the Spring Boot application are;
application.properties
keycloak.realm=myrealm
keycloak.resource=test-app
keycloak.auth-server-url=http://localhost:8080/auth
keycloak.ssl-required=external
keycloak.public-client=true
keycloak.securityConstraints[0].authRoles[0]=Patient
keycloak.securityConstraints[0].authRoles[1]=Admin
keycloak.securityConstraints[0].securityCollections[0].name=boeken
keycloak.securityConstraints[0].securityCollections[0].patterns[0]=/books
keycloak.securityConstraints[1].authRoles[0]=Admin
keycloak.securityConstraints[1].securityCollections[0].name=backend
keycloak.securityConstraints[1].securityCollections[0].patterns[0]=/manager
server.port=8090
KeycloakConfig class
#Configuration
public class KeycloakConfig {
#Bean
public KeycloakSpringBootConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
}
Just by adding this, the Keycoal-redirect is triggered and I can log in. Easy.
What should I change/add when i'm trying to secure the Vaadin 8 application?
It's not a Spring/Spring boot-application (not started by SpringApplication.run()), I don't think it's mandatory to have a Spring/Spring boot app in order to secure it with Keycloak (correct me if i'm wrong).
The problem seems to be that the application.properties file is ignored (although it is on the class path), as I can navigate to the urls that should be secured.
Does anyone see what's missing/wrong?
In case you would consider using Spring boot, I created a working example of integration between Vaadin 8, Spring Boot and Keycloak.
It makes use of vaadin-spring-boot, keycloak-spring-boot-adapter and keycloak-spring-security-adapter plugins to get jump started and your application.properties will get picked up correctly. In essence, this setup tells Vaadin to let Spring Security handle all security, and in turn Keycloak is hooked up as the security handler.
The only configuration needed is to have a custom SecurityConfiguration to define your specific security needs.
But the bulk comes down to:
#Configuration
#EnableWebSecurity
#EnableVaadinSharedSecurity
#EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true, proxyTargetClass = true)
public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
...
#Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().disable();
http.formLogin().disable();
// disable spring security csrf as Vaadin already provides this
// also possible to disable this in Vaadin and leave this enabled
http.csrf().disable();
http
.authorizeRequests()
.antMatchers("/vaadinServlet/UIDL/**").permitAll()
.antMatchers("/vaadinServlet/HEARTBEAT/**").permitAll()
.anyRequest().authenticated();
http
.logout()
.addLogoutHandler(keycloakLogoutHandler())
.logoutUrl("/sso/logout").permitAll()
.logoutSuccessUrl("/");
http
.addFilterBefore(keycloakPreAuthActionsFilter(), LogoutFilter.class)
.addFilterBefore(keycloakAuthenticationProcessingFilter(), BasicAuthenticationFilter.class);
http
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint());
http
.sessionManagement()
.sessionAuthenticationStrategy(sessionAuthenticationStrategy());
}
...
}
I could reload application on edit with RemoteSpringApplication until I added spring security to my app,
with
#EnableWebSecurity
public class WebAuthConfig extends WebSecurityConfigurerAdapter { ..
etc
event though I added:
// TODO: this disable all security checks httpSecurity.httpBasic().disable().authorizeRequests().anyRequest().permitAll();
so all my rest calls still works without any auth,
as soon as I change the code and running RemoteSpringApplication detects the change it fails with:
Exception in thread "File Watcher" java.lang.IllegalStateException: Unexpected 403 response uploading class files
How to prevent it?
Thx
Add:
.authorizeRequests()
.antMatchers("/.~~spring-boot!~/**")
.permitAll()
.and()
to your Spring Security config near the top of your http method chain in the configure(HttpSecurity http) method and it'll disable Spring Security on the Spring Boot DevTools URL.
If you want to change this URL you can override it by changing the spring.devtools.remote.context-path property in your application.properties.
Make sure you're not running devtools in production of course!!
My use case is simple but could not find an example. I want to allow all my endpoints excluding only one path which will require basic authentication who has USER role. How to do it with Spring Security's antmatchers? I tried something like below but I get 401 Unauthorized in all requests.
httpSecurity
.authorizeRequests()
.antMatchers("/api/**").hasRole("USER")
.antMatchers("/**").permitAll();
To get a basic security feature working, I added the following starter package to my pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
And added following two properties to application.properties:
security.user.name=guest
security.user.password=tiger
Now when I hit my homepage, I get the login box and login works as expected.
Now I want to implement the ‘logout’ feature. When the user clicks on a link, he/she gets logged out. I noticed that the login doesn’t add any cookie in my browser. I am assuming Spring Security creates an HttpSession object for the user. Is that true? Do I need to ‘invalidate’ this session and redirect the user to some other page? What’s the best way to implement the ‘logout’ feature in a Spring Boot based application?
Late is better than never. Spring Boot defaults lots of security components for you, including the CSRF protection. One of the things that does is force POST logout, see here: http://docs.spring.io/spring-security/site/docs/3.2.4.RELEASE/reference/htmlsingle/#csrf-logout
As this suggests you can override this, using something along the lines of:
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().fullyAuthenticated()
.and()
.formLogin().loginPage("/login").failureUrl("/login?error").permitAll()
.and()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login");
The last line is the important one.