Dieser Inhalt ist in der von Ihnen ausgewählten Sprache nicht verfügbar.
Chapter 99. Spring Security
Since Camel 2.3
The Camel Spring Security component provides role-based authorization for Camel routes. It leverages the authentication and user services provided by Spring Security (formerly Acegi Security) and adds a declarative, role-based policy system to control whether a route can be executed by a given principal.
If you are not familiar with the Spring Security authentication and authorization system, please review the current reference documentation on the SpringSource web site linked above.
Access to a route is controlled by an instance of a SpringSecurityAuthorizationPolicy object. A policy object contains the name of the Spring Security authority (role) required to run a set of endpoints and references to Spring Security AuthenticationManager and AccessDecisionManager objects used to determine whether the current principal has been assigned that role. Policy objects may be configured as Spring beans or by using an <authorizationPolicy> element in Spring XML.
The <authorizationPolicy> element can contain the following attributes:
Expand
Name
Default Value
Description
id
null
The unique Spring bean identifier which is used to reference the policy in routes (required)
access
null
The Spring Security authority name that is passed to the access decision manager (required)
authenticationManager
authenticationManager
The name of the Spring Security AuthenticationManager object in the context
accessDecisionManager
accessDecisionManager
The name of the Spring Security AccessDecisionManager object in the context
authenticationAdapter
DefaultAuthenticationAdapter
The name of a camel-spring-securityAuthenticationAdapter object in the context that is used to convert a javax.security.auth.Subject into a Spring Security Authentication instance.
useThreadSecurityContext
true
If a javax.security.auth.Subject cannot be found in the In message header under Exchange.AUTHENTICATION, check the Spring Security SecurityContextHolder for an Authentication object.
alwaysReauthenticate
false
If set to true, the SpringSecurityAuthorizationPolicy will always call AuthenticationManager.authenticate() each time the policy is accessed.
A Spring Security AuthenticationManager and AccessDecisionManager are required to use this component. Here is an example of how to configure these objects in Spring XML using the Spring Security namespace:
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Now that the underlying security objects are set up, we can use them to configure an authorization policy and use that policy to control access to a route:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:spring-security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
http://camel.apache.org/schema/spring-security http://camel.apache.org/schema/spring-security/camel-spring-security.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
<!-- import the Spring security configuration -->
<import resource= "classpath:org/apache/camel/component/spring/security/commonSecurity.xml"/>
<authorizationPolicy id="admin" access="ROLE_ADMIN"
authenticationManager="authenticationManager"
accessDecisionManager="accessDecisionManager"
xmlns="http://camel.apache.org/schema/spring-security"/>
<camelContext id="myCamelContext" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="direct:start"/>
<!-- The exchange should be authenticated with the role -->
<!-- of ADMIN before it is send to mock:endpoint -->
<policy ref="admin">
<to uri="mock:end"/>
</policy>
</route>
</camelContext>
</beans>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:spring-security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
http://camel.apache.org/schema/spring-security http://camel.apache.org/schema/spring-security/camel-spring-security.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
<!-- import the Spring security configuration -->
<import resource= "classpath:org/apache/camel/component/spring/security/commonSecurity.xml"/>
<authorizationPolicy id="admin" access="ROLE_ADMIN"
authenticationManager="authenticationManager"
accessDecisionManager="accessDecisionManager"
xmlns="http://camel.apache.org/schema/spring-security"/>
<camelContext id="myCamelContext" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="direct:start"/>
<!-- The exchange should be authenticated with the role -->
<!-- of ADMIN before it is send to mock:endpoint -->
<policy ref="admin">
<to uri="mock:end"/>
</policy>
</route>
</camelContext>
</beans>
Copy to ClipboardCopied!Toggle word wrapToggle overflow
In this example, the endpoint mock:end is only executed if:
The adminSpringSecurityAuthorizationPolicy can locate a Spring Security Authentication object, that:
can be authenticated or is possible to authenticate
The process of obtaining security credentials that are used for authorization is not specified by this component. You can write your own processors or components which get authentication information from the exchange depending on your needs. For example, you can create a processor that gets credentials from an HTTP request header originating in the Jetty component. No matter how the credentials are collected, they need to be placed in the Inmessage or the SecurityContextHolder so the Camel Spring Security component can access them.
import javax.security.auth.Subject;
import org.apache.camel.*;
import org.apache.commons.codec.binary.Base64;
import org.springframework.security.authentication.*;
public class MyAuthService implements Processor {
public void process(Exchange exchange) throws Exception {
// get the username and password from the HTTP header
// http://en.wikipedia.org/wiki/Basic_access_authentication
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);
// you could also do this if useThreadSecurityContext is set to true
// SecurityContextHolder.getContext().setAuthentication(authToken);
}
}
import javax.security.auth.Subject;
import org.apache.camel.*;
import org.apache.commons.codec.binary.Base64;
import org.springframework.security.authentication.*;
public class MyAuthService implements Processor {
public void process(Exchange exchange) throws Exception {
// get the username and password from the HTTP header
// http://en.wikipedia.org/wiki/Basic_access_authentication
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);
// you could also do this if useThreadSecurityContext is set to true
// SecurityContextHolder.getContext().setAuthentication(authToken);
}
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
The SpringSecurityAuthorizationPolicy automatically authenticates the Authentication object if necessary.
Note
Be aware of these two issues when you use the SecurityContextHolder instead of or in addition to the Exchange.AUTHENTICATION header:
The context holder uses a thread-local variable to hold the Authentication object. Any routes that cross thread boundaries, like seda or jms, lose the Authentication object.
The Spring Security system expects that an Authentication object in the context is already authenticated and has roles.
See the Spring Technical Overview, section 5.3.1: "What is authentication in Spring Security?" for more details.
The default behavior of camel-spring-security is to look for a Subject in the Exchange.AUTHENTICATION header. This Subject must contain at least one principal, which must be a subclass of org.springframework.security.core.Authentication.
You can customize the mapping of Subject to Authentication object by providing an implementation of the org.apache.camel.component.spring.security.AuthenticationAdapter to your <authorizationPolicy> bean.
This can be useful if you are working with components that do not use Spring Security but do provide a Subject.
At this time, only the CXF component populates the Exchange.AUTHENTICATION header.
If authentication or authorization fails in the SpringSecurityAuthorizationPolicy, a CamelAuthorizationException is thrown. This can be handled using Camel’s standard exception handling methods, like the Exception Clause. The CamelAuthorizationException has a reference to the ID of the policy which threw the exception so you can handle errors based on the policy as well as the type of exception.
<onException>
<exception>org.springframework.security.authentication.AccessDeniedException</exception>
<choice>
<when>
<simple>${exception.policyId} == 'user'</simple>
<transform>
<constant>You do not have ROLE_USER access!</constant>
</transform>
</when>
<when>
<simple>${exception.policyId} == 'admin'</simple>
<transform>
<constant>You do not have ROLE_ADMIN access!</constant>
</transform>
</when>
</choice>
</onException>
<onException>
<exception>org.springframework.security.authentication.AccessDeniedException</exception>
<choice>
<when>
<simple>${exception.policyId} == 'user'</simple>
<transform>
<constant>You do not have ROLE_USER access!</constant>
</transform>
</when>
<when>
<simple>${exception.policyId} == 'admin'</simple>
<transform>
<constant>You do not have ROLE_ADMIN access!</constant>
</transform>
</when>
</choice>
</onException>
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Wir helfen Red Hat Benutzern, mit unseren Produkten und Diensten innovativ zu sein und ihre Ziele zu erreichen – mit Inhalten, denen sie vertrauen können. Entdecken Sie unsere neuesten Updates.
Mehr Inklusion in Open Source
Red Hat hat sich verpflichtet, problematische Sprache in unserem Code, unserer Dokumentation und unseren Web-Eigenschaften zu ersetzen. Weitere Einzelheiten finden Sie in Red Hat Blog.
Über Red Hat
Wir liefern gehärtete Lösungen, die es Unternehmen leichter machen, plattform- und umgebungsübergreifend zu arbeiten, vom zentralen Rechenzentrum bis zum Netzwerkrand.