...
From the 3.3.0 release, the Claims access control annotations/interceptors now work with JWT tokens (as well as SAML tokens). This resulted in the following package changes:
- ClaimsAuthorizingInterceptor has moved from the cxf-rt-security-saml module to the cxf-rt-security module. The package name of the ClaimsAuthorizingInterceptor has changed: from org.apache.cxf.rt.security.saml.interceptor.ClaimsAuthorizingInterceptor to org.apache.cxf.rt.security.claims.interceptor.ClaimsAuthorizingInterceptor.
- ClaimsAuthorizingFilter has moved from the cxf-rt-rs-security-xml module to the cxf-rt-frontend-jaxrs module. The package name of the ClaimsAuthorizingFilter has changed: from org.apache.cxf.rs.security.saml.authorization.ClaimsAuthorizingFilter to orgto org.apache.cxf.rsjaxrs.security.claims.ClaimsAuthorizingFilter
Maven dependencies
Code Block | ||||
---|---|---|---|---|
| ||||
<dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-rs-security-xml</security</artifactId> <version>3.3.0</version> </dependency> |
In addition, cxf-rt-rs-security-xml is required if you are working with SAML tokens, and cxf-rt-rs-security-jose-jaxrs is required if you are working with JWT tokens.
Claims based access control
...
where "auth-format" and "authentication" are aliases for "http://claims/authentication-format" and "http://claims/authentication" respectively.
Enforcing Claims authorization
Simply adding Claims annotations are per the examples above is not sufficient to enforce claims based authorization.
...
To enforce claims authorization, a ClaimsAuthorizingInterceptor must be set as an "inInterceptor", passing it a reference to the secured object. There is also a JAX-RS filter wrapper around ClaimsAuthorizingInterceptor available, which is called ClaimsAuthorizingFilter.
An instance of org.apache.cxf.rs.security.saml.authorization.ClaimsAuthorizingFilter (note org.apache.cxf.rs.security.claims.ClaimsAuthorizingFilter from CXF 3.3.0) is used to enforce CBAC. It's a simple JAX-RS filter wrapper around ClaimsAuthorizingInterceptor.
...
Role based access control
If we have a SAML Assertion or JWT token with claims that are known to represent roles, then making those claims work with an RBAC system can be achieved easily.
SimpleAuthorizingInterceptor
One option is to enforce that only users in a given role can access a method in the service bean is to use CXF's SimpleAuthorizingInterceptor. It has a "methodRolesMap" property can maps method names to roles. This interceptor must then be added to the inInterceptor chain of the service endpoint. For example:
Code Block | ||||
---|---|---|---|---|
| ||||
<bean id="serviceBean" class="org.apache.cxf.systest.jaxrs.security.jose.jwt.BookStoreAuthn"/>
<bean id="jwtAuthzFilter" class="org.apache.cxf.rs.security.jose.jaxrs.JwtAuthenticationFilter">
<property name="roleClaim" value="role"/>
</bean>
<bean id="authorizationInterceptor"
class="org.apache.cxf.interceptor.security.SimpleAuthorizingInterceptor">
<property name="methodRolesMap">
<map>
<entry key="echoBook" value="boss"/>
<entry key="echoBook2" value="boss"/>
</map>
</property>
</bean>
<jaxrs:server address="https://localhost:${testutil.ports.jaxrs-jwt-authn-authz}/signedjwtauthz">
<jaxrs:serviceBeans>
<ref bean="serviceBean"/>
</jaxrs:serviceBeans>
<jaxrs:providers>
<ref bean="jwtAuthzFilter"/>
</jaxrs:providers>
<jaxrs:inInterceptors>
<ref bean="authorizationInterceptor"/>
</jaxrs:inInterceptors>
<jaxrs:properties>
<entry key="rs.security.signature.in.properties"
value="org/apache/cxf/systest/jaxrs/security/bob.jwk.properties"/>
</jaxrs:properties>
</jaxrs:server> |
Using annotations
Instead of mapping method names to roles using the SimpleAuthorizingInterceptor, we can instead annotate them in the service bean with javax.annotation.security.RolesAllowed or org.springframework.security.annotation.Secured annotations. For example:
|
where @Secured can be replaced with @RoledAllowed if needed, the following configuration will do it:
|
That is all what is needed. Note that in order to help the default SAML SecurityContextProvider figure out which claims are roles, one can set the two properties as shown above - this not needed if it's known that claims identifying roles have NameFormat and Name values with the default values, which are "http://schemas.xmlsoap.org/ws/2005/05/identity/claims" and "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role" respectively at the moment.
Note that you can have RBAC and CBAC combined for a more sophisticated access control rules be enforced while still keeping the existing code relying on @RolesAllowed or @Secured intact. Override ClaimsAuthorizingFilter and configure it with the Claims rules directly and register it alongside SimpleAuthorizingFilter and here you go.
Also note how SecureAnnotationsInterceptor can handle different types of role annotations, with @RolesAllowed being supported by default.