Spring WebSecurity how to use 2 loginForm - spring

I created two login forms in Spring Web Security. (User, Admin) However, if login fails on the user login page, it returns to the user login page, but if the login fails on the admin login page, it will return to the user login page instead of the admin login page. Is there anything I am doing wrong?
httpSecurity
.csrf()
.disable()
.authorizeRequests()
.requestMatchers(PathRequest.toStaticResources().atCommonLocations())
.permitAll()
.antMatchers("/registerUser", "/saveUser", "/admin")
.permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/admin")
.loginProcessingUrl("/login-process")
.defaultSuccessUrl("/center", true)
.failureUrl("/Admin/admin?error=ture")
.failureHandler(failureHandler())
.permitAll();
httpSecurity.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login-process")
.defaultSuccessUrl("/center", true)
//.failureUrl("/login")
.failureUrl("/login.html?error=true")
.permitAll()
.and()
.rememberMe()
.rememberMeParameter("remember-me")
.key(REMEMBER_ME_TOKEN)
.tokenValiditySeconds(Math.toIntExact(Duration.ofDays(30).getSeconds()))
.userDetailsService(userService);

Related

Spring Security 6 form login while restricting every other request

I am migrating an application from Spring 5 to Spring 6, including the security configuration.
My original setup involved calling .permitAll() for the loginPage url and the loginProcessingUrl and then calling .anyRequest().authenticated() which ensured every other request was redirected to the login page.
I have migrated the configuration and come up with
#Bean
public SecurityFilterChain defaultSecurityConfigurationFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests()
.requestMatchers("/LoginPage/").permitAll()
.requestMatchers("/ValidateLogin/").permitAll()
.and()
// setup login redirection and logic
.formLogin()
.loginPage("/LoginPage")
.loginProcessingUrl("/ValidateLogin")
.usernameParameter("loginName")
.passwordParameter("password")
.failureHandler(customAuthenticationFailureHandler())
.successHandler(customAuthenticationSuccessHandler())
.and()
// setup logout
.logout()
.logoutUrl("/Logout")
.logoutSuccessUrl("/LoginPage")
.invalidateHttpSession(true)
.permitAll()
.and()
.sessionManagement()
.invalidSessionUrl("/LoginPage")
.sessionFixation()
.migrateSession()
.and()
.csrf()
.and()
// add security headers
.headers()
.frameOptions()
.sameOrigin()
.contentSecurityPolicy(CONTENT_SECURITY_POLICY)
.and()
.and()
.authorizeHttpRequests()
.anyRequest()
.authenticated();
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
filter.setForceEncoding(true);
http.addFilterBefore(filter, CsrfFilter.class);
MultipartFilter multipartFilter = new MultipartFilter();
multipartFilter.setServletContext(SpringContext.getBean(ServletContext.class));
http.addFilterBefore(multipartFilter, CsrfFilter.class);
http.addFilterAfter(new SessionCookieFilter(), CsrfFilter.class);
return http.build();
}
However it seems that the anyRequest().authenticated() rule is used no matter which url I try to access resulting in an infinite redirect loop where I am served a 302 to /LoginPage.
Is there any way of creating the functionality in Spring 5 where anyRequest() would catch any requests that weren't already permitted?

Excluding a specific page from Spring Security that is redirected from login page

I am having trouble while I am redirecting an authentication link from my login page. I added the link in to my login page in JSF like this:
<div>
Login via Testinium Cloud
</div>
My spring security configuration is like this:
and()
.authorizeRequests()
.antMatchers(DEFAULT_URL).permitAll()
.antMatchers("/javax.faces.resource/**").permitAll()
.antMatchers("/jsfPages/*").permitAll()
.antMatchers("/errorPages/*").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.accessDeniedHandler(jsfAccessDeniedHandler())
.authenticationEntryPoint(jsfAuthenticationEntryPoint())
.and()
.formLogin()
.loginPage(LOGIN_PAGE).permitAll()
.failureUrl(LOGIN_PAGE).permitAll()
.defaultSuccessUrl(DEFAULT_URL)
.successHandler(authSuccessHandler)
.and()
.logout()
.logoutUrl(LOGOUT_URL).permitAll()
.invalidateHttpSession(true)
.logoutSuccessHandler(logoutSuccessHandler)
.and()
.exceptionHandling().accessDeniedPage("/error/403.xhtml");
How could I redirect my link from login page without gettin an authentication error. I tried
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/api/v1/signup");
}
But it didn't work out for me. Thanks!
If you want to exclude a page from your spring security configuration without overriding web security, you can add 'not' method that is connected to 'antMatchers' method in your code with authenticated() method following like this:
.authorizeRequests()
.antMatchers(DEFAULT_URL).permitAll()
.antMatchers("/javax.faces.resource/**").permitAll()
.antMatchers("/jsfPages/*").permitAll()
.antMatchers("/errorPages/*").permitAll()
.antMatchers(LOGIN_TESTINIUM).not().authenticated()
.anyRequest().authenticated()
.and()

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 - how come I can only access pages as ROLE_ADMIN and not ROLE_USER?

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.

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