'Apply dynamic ACL with spring security and JWT

I have implemented authentication using SpringSecurity, JWT and OAuth2.

@Override
public void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
    .antMatchers(HttpMethod.POST,"/v1/register").permitAll()
    .antMatchers(HttpMethod.GET,"/v1/public").permitAll();
    List<String> permisos = roleService.findPermisos();
    for(String name: permisos) {
        String[] data = name.split(",");
        http.authorizeRequests().antMatchers(data[0], data[1]).hasRole(data[2]);
    }
    http.authorizeRequests()
    .anyRequest().authenticated()
    .and().cors().configurationSource(corsConfigurationSource());
}

Currently the configure(HttpSecurity http) method works on the OAuth2 side. In my database I have all the @RestController to which they are allowed or denied access for each Role, the problem is, it is applied only once the app is compiled and I need is for it to be applied when I modify the allowed or denied access without the need to recompile a dynamic acl shown in List<String> permisos = roleService.findPermisos().

Searching I read that I can use Filters with HttpSecurity, I have not been able to find examples, your help please.



Solution 1:[1]

Doing some research I modified my solution as follows:

@Override
public void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
    .antMatchers(HttpMethod.PUT,"/v1/menu").permitAll()
    .anyRequest().authenticated().and()
    .addFilterAfter(new CustomFilter(), AbstractPreAuthenticatedProcessingFilter.class)
    .cors().configurationSource(corsConfigurationSource());
}

I add a Filter addFilterAfter(new CustomFilter(), AbstractPreAuthenticatedProcessingFilter.class) and in CustomFilter() is:

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {
        ServletContext servletContext = request.getServletContext();
        if(usuarioService == null){
            WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
            usuarioService = webApplicationContext.getBean(IUsuarioService.class);
        }
        String[] path = request.getRequestURI().split("/");
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Usuario usuario = usuarioService.findByEmail(authentication.getName());
        if(usuarioService.existsPermission(request.getMethod(), path[2], authentication.getName())) {
            filterChain.doFilter(request, response);
        } else {
            response.sendError(HttpServletResponse.SC_FORBIDDEN);
        }
}

So I changed my solution from a loop to a query through a filter, the problem is that all the Rest must be registered and validated, this would be a problem to allow access to resources that I do not want to be verified.

Please, if you have a better solution, I would really appreciate your help.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Wilmer