Spring - Security - Trouble with authorizeRequests chain - spring

I can't understand, how to correctly make chain of the authorizeRequests chain.
If I write
http
.addFilterBefore(characterEncodingFilter(), CsrfFilter.class)
.addFilterAfter(cacheControllerFilter(), CsrfFilter.class)
.authorizeRequests()
.antMatchers("/**").permitAll()
.and()
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN").anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/admin/login.html")
.defaultSuccessUrl("/admin/")
.permitAll()
.and()
.logout()
.permitAll();
in this case all is permitAll, including /admin/** .
If I have
http
.addFilterBefore(characterEncodingFilter(), CsrfFilter.class)
.addFilterAfter(cacheControllerFilter(), CsrfFilter.class)
.authorizeRequests()
.antMatchers("/**").permitAll()
.and()
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN").anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/admin/login.html")
.defaultSuccessUrl("/admin/")
.permitAll()
.and()
.logout()
.permitAll();
in this case everything, including /admin/** requires authentication of the user.

Found solution
http://docs.spring.io/spring-security/site/docs/3.2.5.RELEASE/reference/htmlsingle/#authorize-requests
In my case solution is
http
.addFilterBefore(characterEncodingFilter(), CsrfFilter.class)
.addFilterAfter(cacheControllerFilter(), CsrfFilter.class)
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().permitAll()
.and()
.formLogin()
.loginPage("/admin/login.html")
.defaultSuccessUrl("/admin/")
.permitAll()
.and()
.logout()
.permitAll();

Related

spring boot permitAll only works with HttpSecurity.authorizeRequests()

I am creating an api using spring boot
but I am getting the error below
permitAll only works with HttpSecurity.authorizeRequests()
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/", "index", "/css/*", "/js/*")
.permitAll()
.antMatchers("/api/**").hasRole(STUDENT.name())
.antMatchers("/admin/api/**").hasRole(ADMIN.name())
.antMatchers("/management/api/**").hasAnyRole(ADMIN.name(), ADMINTRAINEE.name())
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login").permitAll();
How do I fix this?

Spring Boot Security WebFlux functional, cannot created configuration for two authentication methods

I would like to have two ways of authentication in Spring Boot application. App is written with WebFlux and with functional approach. For some of my endpoints I'd like to have authentication with basicHttp and for some endpoints I would like to have JWT authentication using custom HTTP header. However I cannot merge two WebFilterChains or make it work as one. Only one of the methods works at the time, cannot make them both work. Code for JWT is not finished, but I would like to see 401 when I send request with httpBasic auth method. Paths in examples are fake.
My atttemps:
1)
First bean:
http
.securityMatcher(ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, "/api/1/**"))
.csrf().disable()
.formLogin().disable()
.logout().disable()
.httpBasic().and()
.authenticationManager(authenticationManager(userService))
.build();
Second bean:
http
.securityMatcher(ServerWebExchangeMatchers.pathMatchers("/api/2/**"))
.httpBasic().disable()
.csrf().disable()
.formLogin().disable()
.logout().disable()
.authenticationManager(tokenAuthManager)
.authorizeExchange()
.anyExchange().authenticated()
.and()
.build();
2)
http
.securityMatcher(ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, "/api/1/**"))
.csrf().disable()
.formLogin().disable()
.logout().disable()
.httpBasic().and()
.authenticationManager(authenticationManager(userService))
.securityMatcher(ServerWebExchangeMatchers.pathMatchers("/api/2/**"))
.httpBasic().disable()
.csrf().disable()
.formLogin().disable()
.logout().disable()
.authenticationManager(tokenAuthManager)
.authorizeExchange()
.anyExchange().authenticated()
.and()
.build();

swagger ui with spring security

I need specific role to access swagger ui
snippet to access swagger-ui with role 2 ( tried following with no joy)
http
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/api/**").hasAuthority("ROLE_ROLE1")
.antMatchers("/login/**").permitAll()
.antMatchers("/info/**").permitAll()
.antMatchers(
"/configuration/ui",
"/v2/api-docs",
"/swagger-resources",
"/configuration/security",
"/swagger-ui.html",
"/webjars/**").hasAuthority("ROLE_ROLE2")
.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/perform_login")
.defaultSuccessUrl("/swagger-ui.html", true)
.failureUrl("/login.html?error=true")
.and().logout().logoutSuccessUrl("/login.html")
Permit all works - this checks all the resources are granted access
http
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/api/**").hasAuthority("ROLE_ROLE1")
.antMatchers("/login/**").permitAll()
.antMatchers("/info/**").permitAll()
.antMatchers(
"/configuration/ui",
"/v2/api-docs",
"/swagger-resources",
"/configuration/security",
"/swagger-ui.html",
"/webjars/**").permitAll()
.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/perform_login")
.defaultSuccessUrl("/swagger-ui.html", true)
.failureUrl("/login.html?error=true")
.and().logout().logoutSuccessUrl("/login.html")
there is in memory user for role2
auth
.inMemoryAuthentication()
.withUser("user1").password("userpassword").roles("ROLE2");;
but when I login it doesnt bring up the swagger-ui , is there any thing missing ?
permitAll does show the swagger-ui
any help appreciated
I tried
http
.csrf()
.disable()
.requestMatchers().antMatchers(
"/swagger-ui.html",
"/swagger-resources",
"/configuration/ui",
"/configuration/security",
"/v2/api-docs",
"/webjars/**", "/**")
.and()
.authorizeRequests()
.antMatchers("/api/**").hasAuthority("ROLE_ROLE1")
.antMatchers("/login/**").permitAll()
.antMatchers("/info/**").permitAll()
.antMatchers(
"/swagger-ui.html",
"/swagger-resources",
"/configuration/ui",
"/configuration/security",
"/v2/api-docs",
"/webjars/**").hasRole("ROLE2")

How to configure AuthenticationSuccessHandler etc. only for /api/**

We are developing a standard Spring Boot web application with Thymeleaf templating, but have an API at /api/** which is called through AJAX.
We're using Spring Security's standard cookie based form authentication both for the application and the API. Whereas for the application we want Spring Security to behave in the default way, for the API, we want to provide custom AuthenticationSuccessHandler etc. for returning 200 OK etc., instead of redirecting to success or failure urls.
I am unable to figure out how to configure this, using Java configuration. In the configure method, I tried to configure http two times, as below, but it doesn't seem to work:
// For the API
http.antMatcher("/api/**")
.formLogin()
.successHandler(authenticationSuccessHandler)
.failureHandler(authenticationFailureHandler())
.and()
.logout()
.logoutSuccessHandler(logoutSuccessHandler)
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.and()
.exceptionHandling()
.authenticationEntryPoint(new Http403ForbiddenEntryPoint())
.and()
.rememberMe()
.key(properties.getRememberMeKey())
.rememberMeServices(rememberMeServices())
.and()
.csrf()
.csrfTokenRepository(csrfTokenRepository())
.and()
.addFilterAfter(new LemonCsrfFilter(), CsrfFilter.class)
.addFilterAfter(switchUserFilter(), FilterSecurityInterceptor.class)
.authorizeRequests()
.antMatchers("/login/impersonate*").hasRole(GOOD_ADMIN)
.antMatchers("/logout/impersonate*").authenticated()
.antMatchers("/**").permitAll();
// For the application pages
http
.authorizeRequests()
.antMatchers("/login/impersonate*").hasRole(GOOD_ADMIN)
.antMatchers("/logout/impersonate*").authenticated()
.anyRequest().permitAll()
.and()
.formLogin()
.loginPage("/login").permitAll()
.and()
.logout().permitAll()
.and()
.rememberMe()
.key(properties.getRememberMeKey())
.rememberMeServices(rememberMeServices())
.and()
.csrf()
.csrfTokenRepository(csrfTokenRepository())
.and()
.addFilterAfter(new LemonCsrfFilter(), CsrfFilter.class)
.addFilterAfter(switchUserFilter(), FilterSecurityInterceptor.class);

Spring webflow overwrite Spring security request rules?

Project use SWF 2.4.1 and SSec 4. I specified a failUrl on spring security for errors on login and a transition on webflow if evaluate expression fail. In this case SWF redirection is priority to SSec redirection. I wonder if there is some way to omit/change this behavior because I would follow spring security rules automatically without to create rules on spring webflow.
security rules
http
.antMatcher("/spring/**/*.xhtml")
.exceptionHandling().authenticationEntryPoint(new AccessDenyEntryPoint())
.and()
.requestCache().requestCache(requestCache())
.and()
.authorizeRequests()
.antMatchers("/spring/resources/**","/spring/login","/spring/signup",
"/spring/main","/spring/error","/spring/group").permitAll()
.antMatchers("/spring/myprofile").hasRole("USER")
.antMatchers("/spring/profilegroup").hasRole("MEMBER")
.antMatchers("/spring/admin").hasRole("ADMIN")
.antMatchers("/spring/**/*.xhtml").denyAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/spring/login")
.defaultSuccessUrl("/spring/main",true)
.failureUrl("/spring/login?login_error=1")
.and()
.logout()
.logoutSuccessUrl("/spring/home")
.deleteCookies("JSESSIONID")
.and()
.rememberMe().userDetailsService(customDetailsService)
.and()
.exceptionHandling().accessDeniedPage("/spring/error?error_code=1")
.and()
// Disable CSRF (won't work with JSF) but ensure last HTTP POST request is saved
// See https://jira.springsource.org/browse/SEC-2498
.csrf().disable()
.requestCache()
.requestCache(new HttpSessionRequestCache())
.and()
.sessionManagement()
.sessionFixation().changeSessionId()
.invalidSessionUrl("/spring/main")
.sessionAuthenticationErrorUrl("/spring/error?error_code=4")
.maximumSessions(1)
.expiredUrl("/spring/error?error_code=2")
.maxSessionsPreventsLogin(true);
Webflow rules
<view-state id="login" view="login.xhtml">
<transition on="entry" to="connect"/>
<transition on="recoveryPass" to="recovery" />
</view-state>
<action-state id="connect">
<evaluate expression="login.connect()" />
<transition on="yes" to="connected" />
<transition on="no" to="recovery" />
</action-state>
<view-state id="recovery" view="recovery.xhtml">
<transition on="sendPass" to="login" />
<transition on="return" to="login" />
<transition on="error" />
</view-state>
<end-state id="finish" />
validation code
public String connect(){
logger.entry("Login.connect()");
try{
Authentication request=new UsernamePasswordAuthenticationToken(getEmail(), getPassword());
Authentication result=daoProvider.authenticate(request);
SecurityContextHolder.getContext().setAuthentication(result);
}catch (BadCredentialsException e) {
//MessageRedirect.addFlashMesage("usuario.no.registrado","msg");
return "no";
}catch (LockedException e) {
//MessageRedirect.addFlashMesage("usuario.bloqueado","msg");
return "no";
}catch (DisabledException e) {
//MessageRedirect.addFlashMesage("usuario.desactivado","msg");
return "no";
}
return "yes";
}
Real problem was I was setting secured control on spring security configuration and I should set their on flow definition. Create a custom form page/controller wasn't the problem and works properly and it's not necessary to set loginProccess if you are using a bean. So, configuration would be some like this
Security config
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.exceptionHandling().authenticationEntryPoint(new AccessDenyEntryPoint())
.and()
.exceptionHandling().accessDeniedHandler(new AccessDenyHandlerPoint())
.and()
.authorizeRequests()
.antMatchers("/spring/**/*.xhtml").denyAll()
.and()
.formLogin()
.loginPage("/spring/login")
.loginProcessingUrl("/spring/loginProcess")
.defaultSuccessUrl("/spring/main",true)
.failureUrl("/spring/login?login_error=1")
.and()
.logout()
.logoutUrl("/spring/logout")
.logoutSuccessUrl("/spring/main")
.deleteCookies("JSESSIONID")
// Disable CSRF (won't work with JSF) but ensure last HTTP POST request is saved
// See https://jira.springsource.org/browse/SEC-2498
.and()
.csrf().disable()
.sessionManagement()
.sessionFixation().changeSessionId()
.invalidSessionUrl("/spring/error?error_code=1")
.sessionAuthenticationErrorUrl("/spring/error?error_code=2")
.maximumSessions(1)
.expiredUrl("/spring/error?error_code=3")
.maxSessionsPreventsLogin(true);
}
Flow definition
<secured attributes="ROLE_USER" />
<on-start>
<evaluate expression="spaceBO.dao.getAll()" result="flowScope.spaces"/>
</on-start>
<view-state id="inicio" view="main.xhtml">
</view-state>

Resources