It looks like you need to pass the SecurityContext across the JMS endpoint. when you using the camel-jms component, it will transfer the exchange which hold the SecurityContext for you if you set the "transferExchange" option to be true.
-- Willem Jiang Red Hat, Inc. FuseSource is now part of Red Hat Web: http://www.fusesource.com | http://www.redhat.com Blog: http://willemjiang.blogspot.com (http://willemjiang.blogspot.com/) (English) http://jnn.javaeye.com (http://jnn.javaeye.com/) (Chinese) Twitter: willemjiang Weibo: willemjiang On Wednesday, November 14, 2012 at 6:55 AM, [email protected] wrote: > I have an existing Spring MVC application which has @PreAuthorize annotations > on the business services. I would like to add the ability for a > client/system to send JMS Messages which, in-turn, calls methods on those > secured spring beans. /FYI, without the @PreAuthorize annotation the > call's work seamlessly./ > > Reading the Camel Wiki on Spring-Security > (http://camel.apache.org/spring-security.html), it looks like I should be > able to put a spring authentication token wrapped as a Subject principal > into the Exchange.AUTHENTICATION Header and send it over the wire. > However, I get the error > "org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: > An Authentication object was not found in the SecurityContext". > > I had implemented an AuthenticationAdapter expecting to see calls to convert > from Subject back to Authentication objects. Obviously, the Authentication > object is not put back into a security context, nor was any additional > authentication logic called off to. > > Since that didn't prove useful, I decided to wrap the "camel:to" with a > "camel:policy" as described in the spring-security section in hopes it would > yield some better results (even though I don't want to apply policies to > routes). I then received an error from the > SpringSecurityAuthorizationPolicy. Digging into it, it shows that there is > not an instance of the Subject class in the headers. > > Given that information, I tried adding custom filter header strategies after > observing that the JMSHeaderFilterStrategy was being used, which doesn't > look like it will include the needed Subject header; still with no luck. > > After a lot of time putting the strategies on combinations of sending and > receiving ends of the queue with no success, I decided I had to look for > help and determine if maybe the concept was flawed or there was even a path > to my solution. > > So, I ask, should this concept work? If so, what's the missing-link that's > needed to make this work? > > Here are the versions from my POM. > <spring.version>3.1.2.RELEASE</spring.version> > <spring-security.version>3.1.2.RELEASE</spring-security.version> > <spring-integration.version>2.1.3.RELEASE</spring-integration.version> > <spring-ws.version>2.1.1.RELEASE-SNAPSHOT</spring-ws.version> > <hibernate.version>4.1.4.Final</hibernate.version> > <aspectj.version>1.7.0</aspectj.version> > <activemq.version>5.6.0</activemq.version> > <camel.version>2.10.2</camel.version> > <xbean-spring.version>3.11.1</xbean-spring.version> > <slf4j.version>1.6.6</slf4j.version> > > And since everyone likes code and configuration... > > *INTERFACE* > import org.springframework.security.access.prepost.PreAuthorize; > > public interface AMathService { > > @PreAuthorize("hasAuthority('ROLE_ADMIN')") > String sayHello(String name); > > } > > *IMPLEMENTATION* > import org.springframework.stereotype.Service; > > @Service("aMathService") > public class AMathServiceImpl implements AMathService { > > @Override > public String sayHello(String name) { > return new String("hello " + name); > } > } > > *ROUTE(no strategy)* > <camel:route id="sayHello"> > <camel:from uri="jms:queue:hello"/> > <camel:policy ref="admin"> > <camel:to uri="bean:aMathService?method=sayHello(String)" /> > </camel:policy> > </camel:route> > > *ROUTE(with strategy)* > <camel:route id="sayHello"> > <camel:from > uri="jms:queue:hello?headerFilterStrategy=#camelToSpringHeaderFilterStrategy"/> > <camel:policy ref="admin"> > <camel:to uri="bean:aMathService?method=sayHello(String)" /> > </camel:policy> > </camel:route> > > > *CLIENT (option a)* > GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); > GrantedAuthority a = new SimpleGrantedAuthority("ROLE_ADMIN"); > authorities.add(a); > Authentication auth = new > org.springframework.security.authentication.UsernamePasswordAuthenticationToken("abcdefg", > "1234", authorities); > > Subject subject = new javax.security.auth.Subject(); > subject.getPrincipals().add(auth); > > Endpoint endpoint = camel.getEndpoint("jms:queue:hello"); > System.out.println(camelTemplate.requestBodyAndHeader(endpoint, "john" , > Exchange.AUTHENTICATION, subject)); > > *CLIENT (option b)* > Producer producer = endpoint.createProducer(); > producer.start(); > Exchange exchange = endpoint.createExchange(ExchangePattern.InOut); > exchange.getIn().setBody("john"); > exchange.getIn().getHeaders().put(Exchange.AUTHENTICATION, subject); > producer.process(exchange); > System.out.println(".. the result is " + exchange.getOut().getBody()); > producer.stop(); > > > > > -- > View this message in context: > http://camel.465427.n5.nabble.com/JMS-to-Secured-Spring-Method-with-PreAuthorize-annotation-tp5722696.html > Sent from the Camel - Users mailing list archive at Nabble.com > (http://Nabble.com).
