'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 |
