Camel REST and Spring Security Java Configuration

Viewed 831

I'm trying to set up Camel REST to use basic auth with a simple username/password from my application.properties and can't for the life of me seem to configure Camel Spring Security to do that. I'm trying to follow the Spring Security component documentation which seems to be missing the example of configuring the required beans. I found the missing example here under 'Controlling access to Camel routes' but this only shows the xml configuration.

How do I set up the required SpringSecurityAuthorizationPolicy bean? It needs an AuthenticationManager and an AccessDecisionManager and it also seems to require that I set its SpringSecurityAccessPolicy which I have no idea how to do.

I haven't gotten to test these yet, because I can't get my beans set up, but my rest route looks like:

rest("/ingest")
            .post("/json").consumes("application/json")
            .route()
            .process(authProcessor)
            .policy(authPolicy) // this is the bean I don't know how to configure
            .to("direct:ingest")
            .endRest();

and my AuthProcessor (taken from the camel component doc) looks like:

@Component
public class AuthProcessor implements Processor {

    public void process(Exchange exchange) {
        String userpass = new String(Base64.decodeBase64(exchange.getIn().getHeader("Authorization", String.class)));
        String[] tokens = userpass.split(":");

        // create an Authentication object
        UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(tokens[0], tokens[1]);

        // wrap it in a Subject
        Subject subject = new Subject();
        subject.getPrincipals().add(authToken);

        // place the Subject in the In message
        exchange.getIn().setHeader(Exchange.AUTHENTICATION, subject);
    }
}

and here's my broken bean configuration for what it's worth:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Bean
public SpringSecurityAuthorizationPolicy springSecurityAuthorizationPolicy(
        AuthenticationManager authenticationManager, AccessDecisionManager accessDecisionManager) {
    SpringSecurityAuthorizationPolicy policy = new SpringSecurityAuthorizationPolicy();

    SpringSecurityAccessPolicy springSecurityAccessPolicy = new SpringSecurityAccessPolicy();

    policy.setAuthenticationManager(authenticationManager);
    policy.setAccessDecisionManager(accessDecisionManager);
    policy.setSpringSecurityAccessPolicy(????);

    return policy;
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication().withUser("user").password("pass").roles("USER");
}

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

@Bean
public AccessDecisionManager accessDecisionManager() {
    AffirmativeBased affirmativeBased = new AffirmativeBased(ImmutableList.of(
            new RoleVoter()
    ));

    affirmativeBased.setAllowIfAllAbstainDecisions(true);

    return affirmativeBased;
}
}

I've been banging my head against the wall trying to understand this so an example of how to do this would be amazing. It looks like the xml configuration for what I want to do (in the second link) is simple enough but I can't seem to replicate it in Java configuration.

1 Answers

I know it's an old topic, but I ran into similar questions. I managed to get it working. Not by overriding the accessDecisionManager() method within the WebSecurityConfigurerAdapter class, but by constructing a new instance while building my SpringSecurityAuthorizationPolicy:

@Bean
public Policy adminPolicy(AuthenticationManager authenticationManager) {
    RoleVoter roleVoter = new RoleVoter();
    SpringSecurityAuthorizationPolicy policy = new SpringSecurityAuthorizationPolicy();
    policy.setAuthenticationManager(authenticationManager);
    policy.setAccessDecisionManager(new UnanimousBased(List.of(roleVoter)));
    policy.setSpringSecurityAccessPolicy(new SpringSecurityAccessPolicy(roleVoter.getRolePrefix() + "<ROLE_NAME>");
    return policy;
}
Related