Dynamic RBAC Configuration in Spring Security

Viewed 3418

I'm using Spring Security 5.1.2 in Restful Spring MVC project. I have used Custom Filter, Authentication Provider etc. In my Project which works fine, My Security config file is as follows:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthenticationProcessingFilter jwtAuthenticationProcessingFilter;
    @Autowired
    private JwtAuthenticationProvider jwtAuthenticationProvider;
    @Autowired
    private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
    @Autowired
    private JwtAccessDeniedHandler jwtAccessDeniedHandler;
    @Autowired
    private RolePermissionService rolePermissionService;

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(this.jwtAuthenticationProvider);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests().antMatchers(AuthenticationPatternType.SKIP_PATTERN.getPattern()).permitAll();
        try {
            List<PermissionRule> permissionRules = this.rolePermissionService.permissionRules();
            for (PermissionRule p : permissionRules)
                http.authorizeRequests().antMatchers(p.getPermission()).hasAnyRole(p.getRoles().toArray(new String[0]));
        } catch (SystemException ignored) {
        }
        http.authorizeRequests().antMatchers(AuthenticationPatternType.AUTH_PATTERN.getPattern()).authenticated();

        this.jwtAuthenticationProcessingFilter.init(authenticationManagerBean());
        http.addFilterBefore(this.jwtAuthenticationProcessingFilter, UsernamePasswordAuthenticationFilter.class);

        http.exceptionHandling()
                .authenticationEntryPoint(this.jwtAuthenticationEntryPoint)
                .accessDeniedHandler(this.jwtAccessDeniedHandler);

        http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        http.csrf().disable();
    }
}

And my RolePermissionService Class is as follows:

@Service
public class RolePermissionService {

    @Autowired
    private PermissionDao permissionDao;

    public List<PermissionRule> permissionRules() {
        List<PermissionEntity> permissionEntities = this.permissionDao.list();
        return permissionEntities.stream().map(PermissionRule::new)
            .collect(Collectors.toList());
    }
}

public class PermissionRule {
    private String permission;
    private List<String> roles;

    public PermissionRule(PermissionEntity permissionEntity) {
        this.permission = permissionEntity.getUrl();
        this.roles = permissionEntity.getRoles().stream().map(RoleEntity::getName)
                .collect(Collectors.toList());
    }

    // getters and setters
}

In this project, I have role(rid, name), permission(pid, url) and rolePermission(pid, rid) tables which holds my RBAC data. As you can see I'm reading this data from database (RolePermissionService Class) and load this data to HttpSecurity object in above config file.

Now, assume there is a rest Api which I want to edit rolePermission table or assume there is a rest Api which I want to add a role and its permissions in run time.

Q: How can I update security configuration which I can edit RBAC dynamically at run time?

1 Answers

Please refer https://github.com/liubo-tech/spring-security-rbac

@PreAuthorize("hasAuthority(T(com.example.springsecurityrbac.config.PermissionContact).USER_VIEW)")

Used to annotate method for securing. Uses database table mapping to assign permissions. Please refer repo for further information

Related