Spring security - how come I can only access pages as ROLE_ADMIN and not ROLE_USER? - spring

In my application, I have a SecurityConfiguration class that has the following method:
protected void configure(HttpSecurity http) throws Exception {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
http.addFilterBefore(filter,CsrfFilter.class);
http
.formLogin()
.loginPage("/login")
.usernameParameter("ssoId")
.passwordParameter("password")
.and()
.authorizeRequests()
// I admit that this section needs some work
.antMatchers("/", "/home/**", "/alert/*", "/scheduler/*", "/agent/*", "/ftp/*", "/smtp/*", "/sql/*").access("hasRole('USER')")
.antMatchers("/benefit/transport/*", "/contract/*").access("hasRole('ADMIN')")
.antMatchers("/", "/home/*", "/alert/*", "/scheduler/*", "/agent/*", "/ftp/*", "/smtp/*", "/sql/*").access("hasRole('ADMIN')")
.antMatchers("/benefit/transport/*", "/contract/*").access("hasRole('ADMIN')")
.antMatchers("/admin/**").access("hasRole('ADMIN')")
.antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
.and()
.rememberMe().rememberMeParameter("remember-me").tokenRepository(persistentTokenRepository()).tokenValiditySeconds(86400)
.and()
.csrf()
.and()
.exceptionHandling().accessDeniedPage("/accessDenied");
}
But as stated on the question, I my user has the ROLE_ADMIN privilege, access is normal throughout the application. But if he has only ROLE_USER, no pages are displayed.
What am I not seeing here?

What are you trying to achive with these lines?
.antMatchers("/", "/home/**", "/alert/*", "/scheduler/*", "/agent/*", "/ftp/*", "/smtp/*", "/sql/*").access("hasRole('USER')")
.antMatchers("/", "/home/*", "/alert/*", "/scheduler/*", "/agent/*", "/ftp/*", "/smtp/*", "/sql/*").access("hasRole('ADMIN')")
Seems to me that you are overwriting your configuration here.. So the ADMIN role would overwrite the USER role here.

Related

Users are able to access all endpoints after setting antMachers in Spring Security

I'm developing a spring-boot application and its spring security configuration is as follows:
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.authorizeRequests()
.antMatchers("/actuator/**", "/login*", "/logout*")
.permitAll();
httpSecurity
.cors().and()
.csrf().disable()
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/taas/v1/**").hasRole("admin")
.antMatchers("/taas/v1/teams", "/taas/v1/profiles", "/taas/v1/tests/summary").hasRole("tester")
.antMatchers( "/taas/v1/teams", "/taas/v1/tests/summary").hasRole("user")
.anyRequest().authenticated()
.and()
.exceptionHandling().accessDeniedHandler(customAccessDeniedHandler)
.and()
.httpBasic()
.and()
.formLogin()
.successHandler(customAuthenticationSuccessHandler)
.failureHandler(customAuthenticationFailureHandler)
.and()
.logout()
.logoutSuccessHandler(customLogoutSuccessHandler())
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID");
}
}
Even though i have set the url pattern for each roles. All users are able to access all endpoints as mentioned in antMatchers(). A user with role user is not supposed to access /taas/v1/profiles. But when I try to access that endpoint by logging in as user, I'm getting the response but expected response is 403 forbidden.
I request someone to provide a workaround for me.
I got this issue resolved by doing some minor changes in my antMatchers(). Below is the modified code.
The main issue is that antMatcher() pattern must not contain the context path, see Spring security antMatcher does not work
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.cors()
.and()
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/profiles").hasAnyRole("TESTER")
.antMatchers( "/teams", "/tests/summary").hasAnyRole("USER", "TESTER", "ADMIN")
.anyRequest().authenticated()
.and().csrf().disable()
.exceptionHandling()
.accessDeniedHandler(customAccessDeniedHandler)
.and()
.httpBasic()
.and()
.formLogin()
.successHandler(customAuthenticationSuccessHandler)
.failureHandler(customAuthenticationFailureHandler)
.and()
.sessionManagement()
.invalidSessionUrl("/invalidSession.html")
.maximumSessions(1).sessionRegistry(sessionRegistry()).and()
.sessionFixation().none()
.and()
.logout()
.logoutSuccessHandler(customLogoutSuccessHandler())
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID");
}
}
Please verify the code that you're sharing because as you've mentioned. A user with role user is not supposed to access /ptaas/v1/profiles. But when I try to access that endpoint by logging in as user.
Where your mapping says you've not configured access to user role as given.
.antMatchers( "/taas/v1/teams", "/taas/v1/tests/summary").hasRole("user")
As per your comments it should have been .antMatchers( "/taas/v1/teams", "/taas/v1/tests/summary", "/ptaas/v1/profiles").hasRole("user")

Do not start sessions for anonymous users

How can I disable sessions for anonymous users in spring boot 2.0?
My current configuration:
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/actuator/**").permitAll()
.antMatchers("/password/forgot/**").permitAll()
.antMatchers("/password/reset/**").permitAll()
.antMatchers("/css/**").permitAll()
.antMatchers("/js/**").permitAll()
.antMatchers("/img/**").permitAll()
.antMatchers("/manage/**").permitAll()
.antMatchers( "/favicon.ico").permitAll()
.anyRequest().authenticated();
http
.formLogin()
.loginPage("/login")
.permitAll()
.successHandler(authSuccessHandler)
.and()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login")
.invalidateHttpSession(true)
.permitAll();
}
}
When I open the login page, there is still a session created:
Perhaps the session is being automatically created by Spring Security. That behavior can be disabled by setting create-session to never. This means Spring Security will not attempt to automatically create a session.
<http create-session="never">
[...]
</http>
Some more details here: https://www.baeldung.com/spring-security-session
try adding "anonymous.disable()" after http in FormLoginWebSecurityConfigurerAdapter class.
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.anonymous.disable()
.authorizeRequests()
.antMatchers("/actuator/**").permitAll()
.antMatchers("/password/forgot/**").permitAll()
.antMatchers("/password/reset/**").permitAll()
.antMatchers("/css/**").permitAll()
.antMatchers("/js/**").permitAll()
.antMatchers("/img/**").permitAll()
.antMatchers("/manage/**").permitAll()
.antMatchers( "/favicon.ico").permitAll()
.anyRequest().authenticated();
http
.formLogin()
.loginPage("/login")
.permitAll()
.successHandler(authSuccessHandler)
.and()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login")
.invalidateHttpSession(true)
.permitAll();
}
Enjoyy!
In my case I had to do 3 things:
Add http.anonymous.disable() to my WebSecurityConfigurerAdapter.
Also add http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER). I don't know why, but this DOES create sessions for my authenticated users, even though the docs say that it will never create sessions for you.
Deleted all my cookies before testing. I discovered that if you made a request with an old session cookie, the server would use said cookie to create a new session, ignoring completely the SessionCreationPolicy we just set.

Spring OAuth2 server : WebSecurityConfigurerAdapter how to allow another request than the login page

I' d like to allow another page than the login one in my configuration, a registration page. I use the authorization_code grant to connect the users from another service, the client, so they are redirected to the oauth2 server to login then they are redirected back to the client.
I created a registration form accessible from the login page, but I 'm not able to reach it I' m automaticly redirected to the login page.
Here is my configuration
#Override
protected void configure(HttpSecurity http) throws Exception { // #formatter:off
http.requestMatchers()
.antMatchers("/login**", "/oauth/**")
.and()
.authorizeRequests()//autorise les requetes
.anyRequest()//pour n'importe quel path
.authenticated()//aux utilisateur authentifié
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login.do")
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.userDetailsService(userDetailsServiceBean());
}
I'd like to allow a /registration path but I don't know how to do that.
Here is the solution
#Override
protected void configure(HttpSecurity http) throws Exception { // #formatter:off
http.requestMatchers()
.antMatchers("/login**", "/registration"/*, "/logout.do"*/, "/oauth/**")
.and()
.authorizeRequests()
.antMatchers("/registration")
.permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login.do")
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.userDetailsService(userDetailsServiceBean());
}

Spring Security HTTP FormLogin

I have a problem with my Spring Security
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UsuarioService usuarioService;
#Autowired
private PasswordEncoder passwordEncoder;
#Override
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
http
.authorizeRequests()
.antMatchers(
"/",
"/index/**",
"/register",
"/doregister",
"/login",
"/dologin",
"/logout-success",
"/confirmregister",
"/invaliduser",
"/expiredtoken",
"/userstatuslog",
"/verifyemail")
.permitAll()
.anyRequest()
.authenticated()
.and()
.authorizeRequests()
.antMatchers(
"/login",
"logout")
.permitAll()
.and()
.authorizeRequests()
.antMatchers(
"/static/css/**",
"/css/custom.css",
"/js/**",
"/images/**"
)
.permitAll()
.and()
.authorizeRequests()
.antMatchers(
"/forbidden",
"/edit-profile-about",
"/doeditprofileabout",
"/profile"
)
.hasRole("USER")
.and()
.authorizeRequests()
.antMatchers(
"/controlpanel",
"/forbidden",
"/edit-profile-about",
"/doeditprofileabout",
"/profile"
)
.hasRole("ADMIN")
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/")
.permitAll()
.and()
.logout()
.deleteCookies("remove")
.invalidateHttpSession(true)
.logoutUrl("/logout")
.logoutSuccessUrl("/logout-success")
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"));
// #formatter:on
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(usuarioService).passwordEncoder(passwordEncoder);
}
Everytime, I do login it sends me to the bootstrap file...
localhost:8080/css/bootstrap-3.3.7-dist/css/bootstrap.min.css
or...
localhost:8080/css/custom.css
or...
localhost:8080/js/jquery-2.1.4.min.js
but not to the same one (it seems random! :-)
Then sometimes the CSS works and sometimes not. In the login form it has no styles, but only sometimes, because when I run the app, it has the styles. And when I do login too, but not when I logout or try to login again. So when the user is correctly logged in, it has styles again.
And when I tried to access "/controlpanel" with a user (with ROLE_USER) it allows access (and it should not), but when I do it with a user (Role_ADMIN) it works fine.
It happens when your static resources are filtered by Spring Security.
Try to ignore these resources at all:
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/path/**");
}
define patterns to meet all your locations.
The problem is that your css files is not accessible by guest. So after logging in, you will be redirected back to it. Sometime css in login page works because of browser caching.
Try to change your configuration to
http
.authorizeRequests()
.antMatchers(
"/",
"/index/**",
"/register",
...).permitAll()
.antMatchers(
"/login",
"logout").permitAll()
.antMatchers( // You need to add all css file here
"/static/css/**",
"/css/custom.css",
"/css/bootstrap-3.3.7-dist/css/bootstrap.min.cs‌​‌​‌​s",
"/js/**",
"/images/**").permitAll()
.antMatchers(
"/forbidden",
"/edit-profile-about",
"/doeditprofileabout",
"/profile").hasRole("USER")
.antMatchers(
"/controlpanel",
"/forbidden",
"/edit-profile-about",
"/doeditprofileabout",
"/profile").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
...

Spring security not blocking all requests

I'm using Spring security 3.2 and have this configuration:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers()
.addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN))
.and()
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.rememberMe()
.rememberMeServices(rememberMeServices())
.key(env.getProperty("security.rememberme.key"))
.and()
.formLogin()
.loginProcessingUrl("/app/authentication")
.successHandler(ajaxAuthenticationSuccessHandler)
.failureHandler(ajaxAuthenticationFailureHandler)
.usernameParameter("j_username")
.passwordParameter("j_password")
.permitAll()
.and()
.logout()
.logoutUrl("/app/logout")
.logoutSuccessHandler(ajaxLogoutSuccessHandler)
.deleteCookies("JSESSIONID")
.permitAll()
.and()
.addFilter(basicAuthenticationFilter(basicAuthenticationEntryPoint(), authenticationManager()))
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/login/**").permitAll()
.antMatchers("/logout/**").permitAll()
.antMatchers("/super_admin/**").hasRole("ADMIN")
.antMatchers("/administration/**").hasRole("ADMIN")
.antMatchers("/*").permitAll()
.antMatchers("/app/**").authenticated();
When I'm logged as user with role ADMIN and I'm accessing http://mydomain:8080/super_admin and http://mydomain:8080/#/administration this is not being blocked. (Works fine)
But when I log in as user without role ADMIN this is being blocked http://mydomain:8080/super_admin, but I can still access http://mydomain:8080/#/administration.
Is there a problem with #?
How I can block http://mydomain:8080/#/administration
Thank you for any feedback.
Values after the # are not send to the server. You have to use some JavaScript to check if it's ok for the user to access the page.
Evgeni is correct, the values after the # is called the fragment or anchor part of the URL, and is used by web browsers not the server.
Example of a fragment URL http://en.wikipedia.org/wiki/Hurricane_Ginger#Impact. This link will take you to Hurricane_Ginger heading Impact

Resources