I was wondering if there is a way for authorizing incrementally with Spring Security (as mentioned here)
By default spring security provides basic profile access when using Google sign OAuth verification. That flow is correct. I would however want to request for additional scopes (Gmail Read, Calendar read etc) on certain URL endpoints.
I have already tried using the @PreAuthorize property on the endpoint along with enabling @EnableGlobalMethodSecurity(prePostEnabled = true)
as in the code.
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
}
Security Configuration Class:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/error", "/privacy", "/css/**", "/images/**", "/js/**", "/fonts/**")
.permitAll().anyRequest().authenticated().and().oauth2Login().and().logout().logoutSuccessUrl("/");
http.csrf().disable();
http.headers().frameOptions().disable();
}
}
I have found a workaround. I have implemented a custom AccessDeniedHandler. Check for the exception and the URL from which it is coming from. If the URL is one where a higher scope is required I redirect the request to google authentication with extra scopes added.
This is a workaround, the real solution is still open.
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
@Value("${spring.security.oauth2.client.registration.google.client-id}")
private String clientId;
@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException, ServletException {
if (accessDeniedException.getMessage().equalsIgnoreCase("Insufficient scope for this resource")) {
response.sendRedirect("https://accounts.google.com/o/oauth2/v2/auth?client_id=" + clientId
+ "&response_type=code&scope=https://www.googleapis.com/auth/gmail.readonly&redirect_uri="
+ request.getServerName() + "/xyz");
}
}
}