Modified: websites/production/cxf/content/docs/jax-rs-oidc.html
==============================================================================
--- websites/production/cxf/content/docs/jax-rs-oidc.html (original)
+++ websites/production/cxf/content/docs/jax-rs-oidc.html Wed Sep 13 15:05:52
2017
@@ -117,11 +117,11 @@ Apache CXF -- JAX-RS OIDC
<!-- Content -->
<div class="wiki-content">
<div id="ConfluenceContent"><p> </p><p><style
type="text/css">/*<![CDATA[*/
-div.rbtoc1505311224086 {padding: 0px;}
-div.rbtoc1505311224086 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1505311224086 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1505314973503 {padding: 0px;}
+div.rbtoc1505314973503 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1505314973503 li {margin-left: 0px;padding-left: 0px;}
-/*]]>*/</style></p><div class="toc-macro rbtoc1505311224086">
+/*]]>*/</style></p><div class="toc-macro rbtoc1505314973503">
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSOIDC-Introduction">Introduction</a></li><li><a shape="rect"
href="#JAX-RSOIDC-MavenDependencies">Maven Dependencies</a></li><li><a
shape="rect" href="#JAX-RSOIDC-IdTokenandUserInfo">IdToken and
UserInfo</a></li><li><a shape="rect" href="#JAX-RSOIDC-OIDCIDPsupport">OIDC IDP
support</a>
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSOIDC-OIDCFlowServices">OIDC Flow Services</a>
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSOIDC-AuthorizationCodeFlow">Authorization Code Flow</a></li><li><a
shape="rect" href="#JAX-RSOIDC-ImplicitFlow">Implicit Flow</a></li><li><a
shape="rect" href="#JAX-RSOIDC-HybridFlow">Hybrid Flow</a></li></ul>
@@ -130,7 +130,7 @@ div.rbtoc1505311224086 li {margin-left:
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSOIDC-Demos">Demos</a></li></ul>
</li></ul>
</div><h1 id="JAX-RSOIDC-Introduction">Introduction</h1><p><a shape="rect"
class="external-link" href="http://openid.net/connect/" rel="nofollow">OpenId
Connect</a> (OIDC) is an identity layer built on top of the OAuth2
protocol.</p><p>When the user authentication is required the client application
initiates one of <a shape="rect" class="external-link"
href="http://openid.net/specs/openid-connect-core-1_0.html" rel="nofollow">OIDC
Core</a> flows and redirects this user to OIDC provider. The user gets
redirected back to the client after the authentication, with the client
application receiving <a shape="rect" class="external-link"
href="http://openid.net/specs/openid-connect-core-1_0.html#IDToken"
rel="nofollow">IdToken</a>. If <a shape="rect" class="external-link"
href="http://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth"
rel="nofollow">Authorization Code Flow</a> is used then IdToken is returned as
part of the follow up <a shape="rect" class="external-link" href="http
://openid.net/specs/openid-connect-core-1_0.html#TokenResponse"
rel="nofollow">code to access token exchange</a>, and if <a shape="rect"
class="external-link"
href="http://openid.net/specs/openid-connect-core-1_0.html#ImplicitFlowAuth"
rel="nofollow">Implicit Flow</a> is used then IdToken is returned <a
shape="rect" class="external-link"
href="http://openid.net/specs/openid-connect-core-1_0.html#ImplicitAuthResponse"
rel="nofollow">immediately</a>.  It is very much like OAuth2 except that
an extra IdToken parameter is returned.</p><p>CXF ships OIDC Provider (IDP) and
Relying Party (RP) utility code to make it easy for developers to create their
own custom OIDC providers or have JAX-RS applications integrated with
well-known 3rd party OIDC IDPs.</p><p>This code relies heavily on <a
shape="rect" href="http://cxf.apache.org/docs/jax-rs-oauth2.html">CXF
OAuth2</a> and <a shape="rect"
href="http://cxf.apache.org/docs/jax-rs-jose.html">CXF JOSE</a> modules.</p><h1
id="JAX-RSOIDC-Mave
nDependencies">Maven Dependencies</h1><div class="code panel pdl"
style="border-width: 1px;"><div class="codeHeader panelHeader pdl"
style="border-bottom-width: 1px;"><b>CXF OIDC module</b></div><div
class="codeContent panelContent pdl">
-<pre class="brush: xml; gutter: false; theme: Confluence"
style="font-size:12px;"><dependency>
+<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"><dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-security-sso-oidc</artifactId>
<version>3.1.7</version>
Modified: websites/production/cxf/content/docs/jax-rs-redirection.html
==============================================================================
--- websites/production/cxf/content/docs/jax-rs-redirection.html (original)
+++ websites/production/cxf/content/docs/jax-rs-redirection.html Wed Sep 13
15:05:52 2017
@@ -32,8 +32,8 @@
<link type="text/css" rel="stylesheet"
href="/resources/highlighter/styles/shThemeCXF.css">
<script src='/resources/highlighter/scripts/shCore.js'></script>
-<script src='/resources/highlighter/scripts/shBrushJava.js'></script>
<script src='/resources/highlighter/scripts/shBrushXml.js'></script>
+<script src='/resources/highlighter/scripts/shBrushJava.js'></script>
<script>
SyntaxHighlighter.defaults['toolbar'] = false;
SyntaxHighlighter.all();
@@ -121,16 +121,16 @@ Apache CXF -- JAX-RS Redirection
 </p><p> </p><p> </p><p> </p><p> </p><p><style
type="text/css">/*<![CDATA[*/
-div.rbtoc1505311254872 {padding: 0px;}
-div.rbtoc1505311254872 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1505311254872 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1505314897034 {padding: 0px;}
+div.rbtoc1505314897034 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1505314897034 li {margin-left: 0px;padding-left: 0px;}
-/*]]>*/</style></p><div class="toc-macro rbtoc1505311254872">
+/*]]>*/</style></p><div class="toc-macro rbtoc1505314897034">
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSRedirection-WithRequestDispatcherProvider">With
RequestDispatcherProvider</a>
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSRedirection-Loggingredirects">Logging redirects</a></li></ul>
</li><li><a shape="rect" href="#JAX-RSRedirection-WithCXFServlet">With
CXFServlet</a></li><li><a shape="rect"
href="#JAX-RSRedirection-CustomRedirection">Custom Redirection</a></li></ul>
</div><h1 id="JAX-RSRedirection-WithRequestDispatcherProvider">With
RequestDispatcherProvider</h1><p><a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/RequestDispatcherProvider.java">RequestDispatcherProvider</a>
is a JAXRS MessageBodyWriter which can redirect to JSP pages, named or default
servlets. It can be used to serve all the responses from a given resource class
or restricted to serving a limited set of classes only using a classResources
map property.</p><p>Starting from CXF 2.5.0 and 2.4.4 it is also possible to
specify that only responses to requests with matching URIs that will be
processed.</p><p>At the moment, this provider is statically configured to
support text/html content types, but it can be easily configured to support
other content types if needed.</p><p>In addition to 'resourcePath' and
'dispatcherName' properties, one can set a 'scope' property which has two possi
ble values, 'request' and 'session' with 'request' being the default value. It
affects the way the JSP code can retrieve parameters passed to it by the
RequestDispatcherProvider. If it is a 'request' scope then all the parameters
are set as the attributes on the current HTTP request. If session scope then
they're set as the attributes on the current HTTP
session.</p><p><code>RequestDispatcherProvider</code> sets the following
parameters :</p><ul class="alternate"><li>JAXRS method response object. The
name of this parameter is either a simple class name of this object (lower
case) or a value retrieved from a beanNames map property using the fully
qualified class name of this object.</li><li>All the path, query and matrix
parameters which have been initialized during the method
execution</li><li>"absolute.path", "base.path" and "relative.path" obtained
from the current UriInfo</li></ul><p>Here are some examples. Lets assume we
have a book.war web application deployed.</p><div class="c
ode panel pdl" style="border-width: 1px;"><div class="codeContent panelContent
pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><jaxrs:server id="bookservice1"
address="/bookstore1">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><jaxrs:server id="bookservice1"
address="/bookstore1">
<jaxrs:serviceBeans>
<bean class="org.apache.cxf.systest.jaxrs.BookStoreDispatch"/>
</jaxrs:serviceBeans>
@@ -145,13 +145,13 @@ div.rbtoc1505311254872 li {margin-left:
</pre>
</div></div><p>The above redirects the response to a default book.html page
which is available directly in the /webapps/book folder. Typically one would do
it to return some static confirmation to the client. For example, consider a
POST form request that has been processed by a given JAX-RS method and the only
thing that needs to be done now is to return the HTML confirmation view. Note
that JAX-RS MessageBodyWriters are not invoked if the resource method returns
no custom object - which is not needed in the case of the static confirmation,
so for RequestDispatcherProvider be able to redirect to book.html one should
simply introduce say an EmptyConfirmation bean with no properties and return it
from the resource method.</p><p>Here is another example (omitting jaxrs:server
declaration for brewity):</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><bean id="dispatchProvider"
class="org.apache.cxf.jaxrs.provider.RequestDispatcherProvider">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><bean id="dispatchProvider"
class="org.apache.cxf.jaxrs.provider.RequestDispatcherProvider">
<property name="resourcePath" value="/book.jsp"/>
</bean>
</pre>
</div></div><p>The only difference from the previous example is that
"/book.jsp" will be delegated to with the task of creating a view. This is a
more interesting example and we presume that the resource method returns say an
instance of the "org.bar.Book" bean:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">@Path("/books")
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">@Path("/books")
public Resource {
@GET
@Produces({"text/html", "application/xml"})
@@ -162,7 +162,7 @@ public Resource {
}
</pre>
</div></div><p>Note how non-intrusive RequestDispatcherProvider is as far as
writing the JAX-RS resource code is concerned, you simply list supported media
types in @Produces as usual.</p><p>RequestDispatcherProvider will make an
instance of Book available as an HttpServletRequest attribute named
"org.bar.Book" by default. this can be customized. If a "beanName" property is
set, for example to "book", then book.jsp will access a Book instance as a
"book" attribute. If you have say 2 resource methods returning instances of
different bean classes, possibly for different view handlers then a beanNames
map property can be used, for example:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><bean id="dispatchProvider"
class="org.apache.cxf.jaxrs.provider.RequestDispatcherProvider">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><bean id="dispatchProvider"
class="org.apache.cxf.jaxrs.provider.RequestDispatcherProvider">
<property name="classResources">
<map>
<entry key="org.bar.Book" value="/book.jsp"/>
@@ -179,7 +179,7 @@ public Resource {
</pre>
</div></div><p>The above configuration says that a "book.jsp" resource will
handle an instance of Book by accessing it as a "book" attribute and a
"customer.jsp" - an instance of Customer by retrieving it as a "customer"
attribute. Note you don't need to use the "beanNames" property in such cases, a
simpler "beanName" property can do unless you have a single (jsp) resource
dealing with both Book and Customer.</p><p>Apart from making an instance of
response class available as HttpServletRequest attribute,
RequestDispatcherProvider will also make all the Path, Query and Matrix
parameters available as HttpServletRequest parameters (as opposed to
attributes) by default. For example, given the above code fragment, an
HttpServletRequest parameter named "id" representing a @PathParam("id")
available to the view handler, as well as all other query and matrix
parameters.<br clear="none"> Note that RequestDispatcherProvider can be
configured to save all these request parameters as HttpServlet
Request attributes by setting a boolean saveParametersAsAttributes property to
true.</p><p>Now, imagine a scenario like this: we have two resource methods
returning a ReservationStatus bean. The first method returns a successful
confirmation or uses Response.seeOther(...) to redirect to a method handling
the failed reservation. So both methods return the same ReservationStatus bean
but we will have two different views handling successful and failed
reservations respectively. Here is one way to manage it:</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><bean id="reserveRegistrationViews"
class="org.apache.cxf.jaxrs.provider.RequestDispatcherProvider">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><bean id="reserveRegistrationViews"
class="org.apache.cxf.jaxrs.provider.RequestDispatcherProvider">
<property name="resourcePaths">
<map>
<entry key="/reservations/reserve/complete"
value="/forms/reservationConfirm.jsp"/>
@@ -190,7 +190,7 @@ public Resource {
</bean>
</pre>
</div></div><p>Given that the same ReservationStatus bean is returned in both
cases, it is actually the original request URI fragments which are used to
match which view handler will deal with a given ReservationStatus, example, a
response to request URI "http://localhost:8080/reservations/reserve/complete"
will be handled by "/forms/reservationConfirm.jsp".</p><p>Note that
RequestDispatcherProvider has a 'dispatcherName' property - that can be handy
when redirecting to named servlets (example, MyServlet) including<br
clear="none"> such ones as "jsp" or "default", especially when CXFServlet
handling a given invocation has a uri pattern (typically, wildcard) that may
also capture the redirection request, see the next section for more
information.</p><p>Next, imagine a scenario like this: we have a single
resource method accepting some data and the response view will need to be
different depending on the status of the request processing. Using enumerations
is the most effective option
in this case:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">package resource;
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">package resource;
public class Status {
UPDATE_SUCCESS,
@@ -212,13 +212,13 @@ public class Resource {
}
</pre>
</div></div><p>Next, you may have a single JSP handler which will check
whether it is Status.UPDATE_SUCCESS or Status.UPDATE_FAILURE and format the
response accordingly. In this case a basic RequestDispatcherProvider
configuration will do:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><bean id="dispatchProvider"
class="org.apache.cxf.jaxrs.provider.RequestDispatcherProvider">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><bean id="dispatchProvider"
class="org.apache.cxf.jaxrs.provider.RequestDispatcherProvider">
<property name="resourcePath" value="/updateStatus.jsp"/>
</bean>
</pre>
</div></div><p>Alternatively you may have a dedicated view handler dealing
with the specific status, in this case either:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><bean id="reserveRegistrationViews"
class="org.apache.cxf.jaxrs.provider.RequestDispatcherProvider">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><bean id="reserveRegistrationViews"
class="org.apache.cxf.jaxrs.provider.RequestDispatcherProvider">
<property name="classResources">
<map>
<entry key="resource.Status.UPDATE_SUCCESS"
value="/forms/updateSuccess.jsp"/>
@@ -228,7 +228,7 @@ public class Resource {
</bean>
</pre>
</div></div><p>or, starting from CXF 2.7.1,</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><beans
xmlns="http://www.springframework.org/schema/beans"
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
@@ -256,30 +256,30 @@ http://www.springframework.org/schema/ut
</beans>
</pre>
</div></div><p>will help.</p><p>Starting from CXF 2.6.1 it is possible to
configure the provider to check if the current class has an associated view
handler or not, for example:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><bean id="viewHandler"
class="org.apache.cxf.jaxrs.provider.RequestDispatcherProvider">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><bean id="viewHandler"
class="org.apache.cxf.jaxrs.provider.RequestDispatcherProvider">
<property name="dispatcherName" value=jsp""/>
<property name="useClassNames" value="true"/>
</bean>
</pre>
</div></div><p>For example, given a simple class name such as "BookInfo",
RequestDispatcherProvider will check if a "/WEB-INF/bookInfo.jsp" handler is
available or not. The provider will likely be extended to check few more
locations as needed.</p><p>RequestDispatcherProvider also checks a
"redirect.resource.path" property on the outbound message. If this property is
set then it will try to find a RequestDispatcher available on a given
path.</p><p>A new property, "includeResource" is available starting from CXF
3.0.4: RequestDispatcher.include() instead of RequestDispatcher.forward() will
be used if this property is set to true.</p><p>Finally, a 'servletContextPath'
property can be used to have some other ServletContext (as opposed to the
current one) be used for RequestDispatcher look-ups. If set then the current
ServletContext.getContext(servletContextPath) will be used to get the needed
ServletContext.</p><h2 id="JAX-RSRedirection-Loggingredirects">Logging
redirects</h2><p>To get
RequestDispatcherProvider log the information about redirects, please set a
'logRedirects' property:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><bean id="reserveRegistrationViews"
class="org.apache.cxf.jaxrs.provider.RequestDispatcherProvider">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><bean id="reserveRegistrationViews"
class="org.apache.cxf.jaxrs.provider.RequestDispatcherProvider">
<property name="logRedirects" value="true"/>
<!-- other properties as needed -->
</bean>
</pre>
</div></div><p>You will see the logging entry like this one:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">23-Jul-2012 11:26:13
org.apache.cxf.jaxrs.provider.RequestDispatcherProvider logRedirection
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">23-Jul-2012 11:26:13
org.apache.cxf.jaxrs.provider.RequestDispatcherProvider logRedirection
INFO: Setting an instance of "oauth2.common.ConsumerRegistration" as
HttpServletRequest attribute "newClient" and redirecting the response to
"/forms/registerAppConfirm.jsp"
</pre>
</div></div><h1 id="JAX-RSRedirection-WithCXFServlet">With
CXFServlet</h1><p>Please see the "Redirection" section on the <a shape="rect"
href="servlet-transport.html">Servlet Transport</a> page.</p><p>Note that both
CXFServlet and JAXRS RequestDispatcherProvider can work together effectively on
executing the redirection requests as described at that page.</p><p>If
CXFServlet URI pattern does not match the resource URIs
RequestDispatcherProvider is redirecting to then there's nothing to worry
about.</p><p>If you have CXFServlet listening on "/" (thus effectively catching
all the requests) and also would like to use RequestDispatcherProvider, then
make sure that a 'dispatcherName' property is also set, for example:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><bean id="dispatchProvider"
class="org.apache.cxf.jaxrs.provider.RequestDispatcherProvider">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><bean id="dispatchProvider"
class="org.apache.cxf.jaxrs.provider.RequestDispatcherProvider">
<property name="dispatcherName" value="jsp"/>
<property name="resourcePath" value="/WEB-INF/jsp/test.jsp"/>
</bean>
</pre>
</div></div><p>If resources which are redirected to can be made public (i.e,
moved out of /WEB-INF) then alternative option (instead of adding a
'dispatcherName' property to RequestDispatcherProvider and still have
CXFServlet listening on '/') is to configure both RequestDispatcherProvider and
CXFServlet to redirect to resources such as "/jsp/test.jsp".</p><p>Also if you
have many public view handlers then rather than having a "dispatcherName"
property set on every dispatcher bean, you can get it set only once on
CXFServlet:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><servlet>
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><servlet>
<servlet-name>RESTServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<init-param>
Modified: websites/production/cxf/content/docs/jax-rs-rxjava.html
==============================================================================
--- websites/production/cxf/content/docs/jax-rs-rxjava.html (original)
+++ websites/production/cxf/content/docs/jax-rs-rxjava.html Wed Sep 13 15:05:52
2017
@@ -117,11 +117,11 @@ Apache CXF -- JAX-RS RxJava
<!-- Content -->
<div class="wiki-content">
<div id="ConfluenceContent"><p><style type="text/css">/*<![CDATA[*/
-div.rbtoc1505311219391 {padding: 0px;}
-div.rbtoc1505311219391 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1505311219391 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1505314852953 {padding: 0px;}
+div.rbtoc1505314852953 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1505314852953 li {margin-left: 0px;padding-left: 0px;}
-/*]]>*/</style></p><div class="toc-macro rbtoc1505311219391">
+/*]]>*/</style></p><div class="toc-macro rbtoc1505314852953">
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSRxJava-RxJava2FlowableandObservablesupport">RxJava2 Flowable and
Observable support</a>
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSRxJava-Introduction">Introduction</a></li><li><a shape="rect"
href="#JAX-RSRxJava-Client">Client</a></li><li><a shape="rect"
href="#JAX-RSRxJava-Server">Server</a>
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSRxJava-Asamethodreturnvalue">As a method return
value</a></li><li><a shape="rect"
href="#JAX-RSRxJava-CombiningFlowablewithAsyncResponse">Combining Flowable with
AsyncResponse</a></li></ul>
@@ -132,9 +132,9 @@ div.rbtoc1505311219391 li {margin-left:
</li></ul>
</li></ul>
</div><h1 id="JAX-RSRxJava-RxJava2FlowableandObservablesupport">RxJava2
Flowable and Observable support</h1><h2
id="JAX-RSRxJava-Introduction">Introduction</h2><p>RxJava 2 Flowable and
Observable are supported on the client and the server side starting from CXF
3.2.0.</p><p>org.apache.cxf/cxf-rt-rs-extension-rx/3.2.0 and
io.reactivex.rxjava2/rxjava/2.1.3 dependencies are required.</p><h2
id="JAX-RSRxJava-Client">Client</h2><p>The following simple example uses
FlowableRxInvoker. org.apache.cxf.jaxrs.rx2.client.ObservableRxInvoker can be
used if needed instead.</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Confluence"
style="font-size:12px;"> </pre>
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"> </pre>
</div></div><h2 id="JAX-RSRxJava-Server">Server</h2><h3
id="JAX-RSRxJava-Asamethodreturnvalue">As a method return value</h3><p>One
simply returns io.reactivex.Flowable from the method and the runtime will make
sure the response is finalized once the Flowable flow is complete.</p><p>The
only requirement is that one has to register a custom JAX-RS invoker,
org.apache.cxf.jaxrs.rx2.server.FlowableInvoker. It does all the default
JAXRSInvoker does and only checks if Flowable is returned - if yes then it
links it internally with the JAX-RS AsyncResponse.</p><p>If needed,
io.reactivex.Observable can be returned instead (with
org.apache.cxf.jaxrs.rx2.server.ObservableInvoker registered)</p><h3
id="JAX-RSRxJava-CombiningFlowablewithAsyncResponse">Combining Flowable with
AsyncResponse</h3><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Confluence"
style="font-size:12px;">JAXRSServerFactoryBean sf = new
JAXRSServerFactoryBean();
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">JAXRSServerFactoryBean sf = new
JAXRSServerFactoryBean();
sf.setInvoker(new FlowableInvoker());
sf.setProvider(new JacksonJsonProvider());
StreamingResponseProvider<HelloWorldBean> streamProvider = new
StreamingResponseProvider<HelloWorldBean>();
@@ -146,7 +146,7 @@ sf.setResourceProvider(RxJava2FlowableSe
sf.setAddress("http://localhost:" + PORT + "/");
server = sf.create();</pre>
</div></div><p> </p><p> </p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Confluence"
style="font-size:12px;">import
org.apache.cxf.jaxrs.rx2.server.JsonStreamingAsyncSubscriber;
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">import
org.apache.cxf.jaxrs.rx2.server.JsonStreamingAsyncSubscriber;
import io.reactive.Flowable;
import io.reactivex.schedulers.Schedulers;
@@ -161,7 +161,7 @@ import io.reactivex.schedulers.Scheduler
.subscribe(new
JsonStreamingAsyncSubscriber<HelloWorldBean>(ar));
}</pre>
</div></div><p> </p><h1
id="JAX-RSRxJava-RxJava1rx.Observablesupport">RxJava1 rx.Observable
support</h1><h2 id="JAX-RSRxJava-Introduction.1">Introduction</h2><p>RxJava 1
rx.Observable is supported on the client and the server side starting from CXF
3.2.0.</p><p>org.apache.cxf/cxf-rt-rs-extension-rx/3.2.0 and
io.reactivex/rxjava/1.3.0 dependencies are required.</p><h2
id="JAX-RSRxJava-Client.1">Client</h2><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Confluence"
style="font-size:12px;">import
org.apache.cxf.jaxrs.rx.client.ObservableRxInvoker;
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">import
org.apache.cxf.jaxrs.rx.client.ObservableRxInvoker;
import org.apache.cxf.jaxrs.rx.client.ObservableRxInvokerProvider;
import rx.Observable;
 
Modified: websites/production/cxf/content/docs/jax-rs-saml.html
==============================================================================
--- websites/production/cxf/content/docs/jax-rs-saml.html (original)
+++ websites/production/cxf/content/docs/jax-rs-saml.html Wed Sep 13 15:05:52
2017
@@ -32,8 +32,8 @@
<link type="text/css" rel="stylesheet"
href="/resources/highlighter/styles/shThemeCXF.css">
<script src='/resources/highlighter/scripts/shCore.js'></script>
-<script src='/resources/highlighter/scripts/shBrushJava.js'></script>
<script src='/resources/highlighter/scripts/shBrushXml.js'></script>
+<script src='/resources/highlighter/scripts/shBrushJava.js'></script>
<script>
SyntaxHighlighter.defaults['toolbar'] = false;
SyntaxHighlighter.all();
@@ -121,23 +121,23 @@ Apache CXF -- JAX-RS SAML
 </p><p> </p><p> </p><p> </p><p><style
type="text/css">/*<![CDATA[*/
-div.rbtoc1505311239079 {padding: 0px;}
-div.rbtoc1505311239079 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1505311239079 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1505314865487 {padding: 0px;}
+div.rbtoc1505314865487 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1505314865487 li {margin-left: 0px;padding-left: 0px;}
-/*]]>*/</style></p><div class="toc-macro rbtoc1505311239079">
+/*]]>*/</style></p><div class="toc-macro rbtoc1505314865487">
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSSAML-Introduction">Introduction</a></li><li><a shape="rect"
href="#JAX-RSSAML-Backwardscompatibilityconfigurationnote">Backwards
compatibility configuration note</a></li><li><a shape="rect"
href="#JAX-RSSAML-Mavendependencies">Maven dependencies</a></li><li><a
shape="rect" href="#JAX-RSSAML-EnvelopedSAMLassertions">Enveloped SAML
assertions</a></li><li><a shape="rect"
href="#JAX-RSSAML-SAMLassertionsinAuthorizationheader">SAML assertions in
Authorization header</a></li><li><a shape="rect"
href="#JAX-RSSAML-SAMLassertionsasFormvalues">SAML assertions as Form
values</a></li><li><a shape="rect"
href="#JAX-RSSAML-CreatingSAMLAssertions">Creating SAML
Assertions</a></li><li><a shape="rect"
href="#JAX-RSSAML-SAMLAssertionValidation">SAML Assertion
Validation</a></li><li><a shape="rect"
href="#JAX-RSSAML-SAMLAuthorization">SAML Authorization</a>
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSSAML-ClaimsBasedAccessControl">Claims Based Access
Control</a></li><li><a shape="rect"
href="#JAX-RSSAML-RoleBasedAccessControl">Role Based Access
Control</a></li></ul>
</li><li><a shape="rect" href="#JAX-RSSAML-SAMLWebSSOProfile">SAML Web SSO
Profile</a></li></ul>
</div><h1 id="JAX-RSSAML-Introduction">Introduction</h1><p>CXF 2.5.0
introduces an initial support for working with <a shape="rect"
class="external-link" href="http://en.wikipedia.org/wiki/SAML_2.0"
rel="nofollow">SAML2</a> assertions. So far the main focus has been put on
making sure SAML assertions can be included in HTTP requests targeted at
application endpoints: embedded inside XML payloads or passed as encoded HTTP
header or form values.</p><p>See also <a shape="rect"
href="jax-rs-xml-security.html">JAX-RS XML Security</a>.</p><h1
id="JAX-RSSAML-Backwardscompatibilityconfigurationnote">Backwards compatibility
configuration note</h1><p>From Apache CXF 3.1.0, the WS-Security based
configuration tags used to configure XML Signature or Encryption
("ws-security-*") have been changed to just start with "security-". Apart from
this they are exactly the same. Older "ws-security-" values continue to be
accepted in CXF 3.1.0. To use any of the configuration examples in this page
with an
older version of CXF, simply add a "ws-" prefix to the configuration
tag.</p><h1 id="JAX-RSSAML-Mavendependencies">Maven dependencies</h1><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><dependency>
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-security-xml</artifactId>
<version>2.5.0</version>
</dependency>
</pre>
</div></div><p>This module depends on Apache WSS4J, as it contains a lot of
useful utility code based around OpenSAML.</p><h1
id="JAX-RSSAML-EnvelopedSAMLassertions">Enveloped SAML
assertions</h1><p>Payload:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><env:Envelope
xmlns:env="http://org.apache.cxf/rs/env">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><env:Envelope
xmlns:env="http://org.apache.cxf/rs/env">
<Book ID="67ca6441-0c4e-4430-af0e-9463ce9226aa">
<id>125</id>
@@ -204,7 +204,7 @@ div.rbtoc1505311239079 li {margin-left:
</env:Envelope>
</pre>
</div></div><p>Note that Book and SAML assertion are individually signed but
the envelope wrapper itself is not.</p><p>Here is another payload showing the
whole enveloped signed including Book and SAML Assertion, this time only a
single signature will be available:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><env:Envelope
xmlns:env="http://org.apache.cxf/rs/env"
ID="e795cdd1-c19d-4a5c-8d86-e8a781af4787">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><env:Envelope
xmlns:env="http://org.apache.cxf/rs/env"
ID="e795cdd1-c19d-4a5c-8d86-e8a781af4787">
<saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
ID="_C76E3D5BBEE4C4D87913203281641141" IssueInstant="2011-11-03T13:49:24.114Z"
Version="2.0" xsi:type="saml2:AssertionType">
<saml2:Issuer>https://idp.example.org/SAML2</saml2:Issuer>
@@ -240,7 +240,7 @@ div.rbtoc1505311239079 li {margin-left:
<ds:Signature
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod
Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/><ds:SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><ds:Reference
URI="#e795cdd1-c19d-4a5c-8d86-e8a781af4787"><ds:Transforms><ds:Transform
Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>GR1pHd2JpxYiCzl6ouCmTZjq/AA=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>C2qUDOFwart2GHFjX6kB3E3z73AMXtRR/6Qjgyp6XP/vTn/Fr2epDNub3q+gNdT0KgjLE2rSynM3QTcpHov9C8l9a8VQquItaalr0XA7BJcxdFMxB7KEATKR9XtrmIEkiw9efM8M83iVux/ufCOWrt0Te2RLz+nRwzyEY49VQOQ=</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certi
ficate><!-- Omitted for brewity
--></ds:X509Certificate></ds:X509Data><ds:KeyValue><ds:RSAKeyValue><ds:Modulus>vu747/VShQ85f16DGSc4Ixh9PVpGguyEqrCsK8q9XHOYX9l9/g5wEC6ZcR2FwfNsoaHcKNPjd5sSTzVtBWmQjfBEfIqwTR7vuihOxyNTwEzVwIJzvo7p8/aYxk+VdBtQxq4UweIcf/iFkUbM1cZ1oiXRQzciRBi+C1BQCQE0qzs=</ds:Modulus><ds:Exponent>AQAB</ds:Exponent></ds:RSAKeyValue></ds:KeyValue></ds:KeyInfo></ds:Signature></env:Envelope>
</pre>
</div></div><p>Server configuration fragment:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"> <bean id="serviceBean"
class="org.apache.cxf.systest.jaxrs.security.BookStore"/>
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"> <bean id="serviceBean"
class="org.apache.cxf.systest.jaxrs.security.BookStore"/>
<bean id="samlHandler"
class="org.apache.cxf.rs.security.saml.SamlEnvelopedInHandler"/>
<!-- only needed if the detached signature signing the application data
is expected -->
@@ -265,7 +265,7 @@ div.rbtoc1505311239079 li {margin-left:
</jaxrs:server>
</pre>
</div></div><p>Client code:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">private WebClient createWebClient(String address) {
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">private WebClient createWebClient(String address) {
JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
bean.setAddress(address);
@@ -288,7 +288,7 @@ div.rbtoc1505311239079 li {margin-left:
}
</pre>
</div></div><p>When we also need to sign the application payload such as Book
we need to make sure that a detached XML signature for Book is created. When
the whole envelope is signed then SamlEnvelopedOutInterceptor needs to be
placed before XmlSigOutInterceptor hence the "new
SamlEnvelopedOutInterceptor(!selfSigned)" constructor is invoked.</p><h1
id="JAX-RSSAML-SAMLassertionsinAuthorizationheader">SAML assertions in
Authorization header</h1><p>Logging output:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">Address:
https://localhost:9000/samlheader/bookstore/books/123
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">Address:
https://localhost:9000/samlheader/bookstore/books/123
Http-Method: GET
Headers: {Accept=[application/xml], Authorization=[SAML
eJydV1mTokgQfu9fYTCPrs2htGKMHVEcKq2gKOLxsoFQAsqhFAjNr99CW1ud7t2ZjdAwMisr68s7/YnMwGfaACEYJ14UVmSxQ/z9wjUlBrRYiWZZiWVYlqPrDFVnmhTbwL80UZERSqEcosQMkw7BUDRdwx+qrtP1dp1qs41nLLciKgaMEVaLRZ4popIHfojapyc7RBqH7chEHmqHZgBRO7HaU6AM21iybV7wXO7kqEO4SbJvk2SWZc9Z/Tm
KHZKhKJpcKMOp5cLA/JT1/lu45p3AWxDfQl47ed/DDvHgDB0zidefZ+7J4vi11IuwYs/eP8PcDPY+PGkvoTM/yTvZnzZqTz0nNJM0hh/g7O8MoUiKI7GMjTznB3G9C2053EQnUjDDKPQs0/cKs4SnwMSN7
@@ -305,13 +305,13 @@ X/fUqygjWBow7h2jFK8VaBTX//SeKzb9krFqKJGC
fCmvq9/El7/AXoseyE=], ...}
</pre>
</div></div><p>Note that the Authorization header has an encoded SAML
Assertion as its value. The original SAML assertion has been optionally
compressed using a deflated encoding and then base64-encoded. This encoded
value can be signed itself - but it is not currently possible.</p><p>Server
configuration is similar to the one from the Enveloped SAML Assertions section,
the only difference is that a SAML handler needs to be replaced:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"> <bean id="serviceBean"
class="org.apache.cxf.systest.jaxrs.security.BookStore"/>
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"> <bean id="serviceBean"
class="org.apache.cxf.systest.jaxrs.security.BookStore"/>
<bean id="samlHandler"
class="org.apache.cxf.rs.security.saml.SamlHeaderInHandler"/>
<!-- same as in the Enveloped SAML Assertions section -->
</pre>
</div></div><p>Client code:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">private WebClient createWebClient(String address) {
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">private WebClient createWebClient(String address) {
JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
bean.setAddress(address);
@@ -332,7 +332,7 @@ fCmvq9/El7/AXoseyE=], ...}
}
</pre>
</div></div><h1 id="JAX-RSSAML-SAMLassertionsasFormvalues">SAML assertions as
Form values</h1><p>Logging output:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">Address: https://localhost:9000/samlform/bookstore/books
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">Address: https://localhost:9000/samlform/bookstore/books
Encoding: ISO-8859-1
Http-Method: POST
Content-Type: application/x-www-form-urlencoded
@@ -352,16 +352,16 @@ JaWX39qd4UFqe2Wb1kn7jj1YHnS/dJlc8OfgQiJy
z46ZePlQcbHwRI/kVeYtLPt8WXOcPk4N2jy8WwC7yUHGvqWF2D6E+FcEv8Lh/qF8fE1u5pqczJyk6XQIcVBJttLRG7sX35R/xqJG28/vLBIXEs+0DqN61/486XlR3H/Efstueksiu3f9+Be8+s1E1KFSLpLmYCfmXvWdKgyKUkNBh7pbeiqvi9/El7+Adcbfqw=
</pre>
</div></div><p>Note that only form 'name' and 'id' fields will remain after
the SAML handler processes a SAML assertion encoded in the SAMLToken form
field. The original SAML assertion has been optionally compressed using a
deflated encoding and then base64-encoded. This encoded value can be signed -
but it is not currently possible.</p><p>Server configuration is similar to the
one from the Enveloped SAML Assertions section, the only difference is that a
SAML handler needs to be replaced:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"> <bean id="serviceBean"
class="org.apache.cxf.systest.jaxrs.security.BookStore"/>
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"> <bean id="serviceBean"
class="org.apache.cxf.systest.jaxrs.security.BookStore"/>
<bean id="samlHandler"
class="org.apache.cxf.rs.security.saml.SamlFormInHandler"/>
<!-- same as in the Enveloped SAML Assertions section -->
</pre>
</div></div><p>The client code is the same as in the SAML assertions in
Authorization header section except than an instance of SamlFormOutInterceptor
has to be registered:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">bean.getOutInterceptors().add(new
SamlFormOutInterceptor());
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">bean.getOutInterceptors().add(new
SamlFormOutInterceptor());
</pre>
</div></div><h1 id="JAX-RSSAML-CreatingSAMLAssertions">Creating SAML
Assertions</h1><p>If you use CXF JAX-RS client API to experiment with SAML then
all you need to do is to register an appropriate out interceptor as shown in
the above code fragments. The interceptor will ensure that a SAML assertion is
created and added inside the XML envelope, as a form or HTTP header value.<br
clear="none"> All of the SAML output interceptors depend on a
"security.saml-callback-handler" property linking to a custom
javax.security.auth.callback.Callback implementation which in its
handle(Callbacks) method provides the information which is needed to create a
SAML assertion to a org.apache.ws.security.saml.ext.SAMLCallback Callback
instance, for example, see this <a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/SamlCallbackHandler.java">custom
implementation</a>.</p><p>More involved cas
es with SAML assertions being created by identity providers will be supported,
with the help of CXF (WS) STSClient when needed.</p><h1
id="JAX-RSSAML-SAMLAssertionValidation">SAML Assertion Validation</h1><p>When
SAML assertions are received on the server side, they are validated to make
sure that the enveloped signatures are correct. SubjectConfirmation methods
(sender-vouches, holder-of-key, bearer) are also checked. <br clear="none"> The
validation can be delegated to STS if needed. By default, server side SAML
handlers have a "samlValidator" property set to an instance of
org.apache.ws.security.validate.SamlAssertionValidator which does a thorough
validation of the assertion. If needed
org.apache.cxf.ws.security.trust.STSTokenValidator can be set instead which
will use STS to validate the assertion.<br clear="none"> Custom validators
extending WSS4J SamlAssertionValidator and doing the additional
application-specific validation can be registered if needed.</p><p>Note the
fact th
at the default validation relies a lot on the code heavily utilized by the
WS-Security implementation should be of no concern - it is an example of the
integration on its own in order to get the validation done. For example, WS-*
STS are heavily used in the enterprise today and it simply makes a complete
sense to rely on it to validate a SAML assertion if it is
possible.</p><p>SubjectConfirmation sender-vouches and holder-of-key methods
can be easily validated with enveloped SAML assertions given that the embedded
SAML signatures and key info can be checked against the signature used to sign
the envelope or a custom payload like Book.</p><p>At the moment these methods
can not be properly validated when the assertion is provided in a header or in
the form, the additional signature signing the encoded SAML token will be
needed - this will be supported in due time. Use "bearer" in those
cases.</p><h1 id="JAX-RSSAML-SAMLAuthorization">SAML Authorization</h1><p>SAML
assertions may contai
n so-called claims which are represented by a sequence of SAML
AttributeStatements containing one or more Attributes, for example:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><saml2:Assertion>
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><saml2:Assertion>
<!-- ... -->
<saml2:AttributeStatement>
<saml2:Attribute
NameFormat="http://schemas.xmlsoap.org/ws/2005/05/identity/claims"
@@ -378,7 +378,7 @@ z46ZePlQcbHwRI/kVeYtLPt8WXOcPk4N2jy8WwC7
</saml2:Assertion>
</pre>
</div></div><p>An individual claim is scoped by NameFormat and Name attribute.
NameFormat is similar to a namespace, while Name identifies what the value of
this claim represents, for example, in the above fragment two claims are
provided, one has a value "user" which represents a role of the assertion's
Subject, another one has a value of "password" which identifies the way Subject
authenticated itself, i.e, Subject provided its password (presumably to
IDP).</p><p>Now, what is interesting is to see if it is possible to use these
claims with Role-Based Access-Control (for example, with endpoints relying on
@RolesAllowed annotations) as well as with the more complex authorization logic
(for example, let this resource be invoked only if Subject used a password to
get authenticated at IDP).</p><h2
id="JAX-RSSAML-ClaimsBasedAccessControl">Claims Based Access Control</h2><p>CXF
JAX-RS offers an extension letting users to enforce a new fine-grained Claims
Based Access Control (CBAC) based
on <a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/api/src/main/java/org/apache/cxf/security/claims/authorization/Claim.java">Claim</a>
and <a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/api/src/main/java/org/apache/cxf/security/claims/authorization/Claims.java">Claims</a>
annotations as well as <a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/api/src/main/java/org/apache/cxf/security/claims/authorization/ClaimMode.java">ClaimMode</a>
enum class.</p><p><strong>Note</strong> a package for Claim, Claims and
ClaimMode annotations has changed from
"org.apache.cxf.rs.security.saml.authorization" to
"org.apache.cxf.security.claims.authorization". Starting from CXF 2.7.1, the
default name format for claims is
"urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified" instead of
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims".</p><p>Here is a simple
code fragment:</p><di
v class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">import
org.apache.cxf.rs.security.saml.authorization.Claim;
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">import
org.apache.cxf.rs.security.saml.authorization.Claim;
import org.apache.cxf.rs.security.saml.authorization.Claims;
@Path("/bookstore")
@@ -401,7 +401,7 @@ public class SecureClaimBookStore {
}
</pre>
</div></div><p>SecureClaimBookStore.addBook(Book) can only be invoked if
Subject meets the following requirement: it needs to have a Claim with a value
"admin" and another Claim confirming that it got authenticated using either a
'fingertip' or 'smartcard' method. Note that @Claim({"admin"}) has no name and
format classifiers set - it relies on default name and format values, namely
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role" and
"urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"
("http://schemas.xmlsoap.org/ws/2005/05/identity/claims" before CXF 2.7.1)
respectively. These default values may change in the future depending on which
claims are found to be used most often - but as you can see you can always
provide name and format values which will scope a given claim value.</p><p>Note
that in the above example, a Claim with the name
"http://claims/authentication-format" has two values, 'fingertip' and
'smartcard'. By default, in order to meet this Claim, Subjec
t needs to have a Claim which has either a 'fingertip' or 'smartcard' value.
If it is expected that Subject needs to have a Claim which has both 'fingertip'
and 'smartcard' values, then the following change needs to be done:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">import
org.apache.cxf.security.claims.authorization.Claim;
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">import
org.apache.cxf.security.claims.authorization.Claim;
import org.apache.cxf.security.claims.authorization.Claims;
@Path("/bookstore")
@@ -425,7 +425,7 @@ public class SecureClaimBookStore {
}
</pre>
</div></div><p>Claims can be specified using individual @Claim annotation,
they can be set at the class level and overridden at the method level and
finally a lax mode of check can be specified:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">import
org.apache.cxf.security.claims.authorization.Claim;
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">import
org.apache.cxf.security.claims.authorization.Claim;
import org.apache.cxf.security.claims.authorization.Claims;
@Path("/bookstore")
@@ -465,10 +465,10 @@ public class SecureClaimBookStore {
}
</pre>
</div></div><p>In the above example, getBookList() can be invoked if Subject
has a Claim with the value "user"; addBook() has it overridden - "admin" is
expected and the authentication format Claim too; getBook() can be invoked if
Subject has a Claim with the value "user" and it also must have the
authentication format Claim with the value "password" - or no such Claim at
all.</p><p>org.apache.cxf.rs.security.saml.authorization.ClaimsAuthorizingInterceptor
enforces the CBAC rules. This filter can be overridden and configured with the
rules directly which can be useful if no Claim-related annotations are expected
in the code. Map nameAliases and formatAliases properties are supported to make
@Claim annotations look a bit simpler, for example:</p><div class="code panel
pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">@Claim(name = "auth-format", format = "authentication",
value = {"password" })
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">@Claim(name = "auth-format", format = "authentication",
value = {"password" })
</pre>
</div></div><p>where "auth-format" and "authentication" are aliases for
"http://claims/authentication-format" and "http://claims/authentication"
respectively.</p><p>Given the above example, the question is how to extract the
information available in a SAML Assertion for the current request to succeed in
passing through the security filter enforcing the CBAC rules.</p><p>The first
and most important thing which needs to be done is to verify that an assertion
Subject can be mapped to a recognized identity instance.</p><p>There is a
number of ways a Subject can be validated.</p><p>If STS is asked to validate
the assertion then a successful response from IDP will likely be good enough
for CXF to trust the identity of the provider.<br clear="none"> If the
assertion signature is verified locally using the public key of IDP then it
could a good enough confirmation too.</p><p>Alternatively, a custom validator,
extending either org.apache.ws.security.validate.SamlAssertionValidator or CXF
SA
ML <a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/authorization/SecurityContextProvider.java">SecurityContextProvider</a>
<a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/authorization/SecurityContextProviderImpl.java">implementation</a>
can be registered with the server side SAML handler.</p><p>The latter option
is preferred because not only one can validate Subject - but also ensure that a
resulting SecurityContext will return a user Principal with a proper name -
given that the actual Subject name available in the assertion may need to be
translated to a name recognized by the local security stores or application. A
combination of the assertion's Subject and AttributeStatement elements may need
to be checked to establish a real name.</p><p>In cases like this you may want
to reg
ister a custom SecurityContextProvider even if you have STS validating the
assertion. Yet another reason is to retrieve the information about roles for a
given Subject or map the assertion claims to roles for working with the RBAC to
succeed, see the next section for more information.</p><p>Have a look please at
this server configuration example:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><bean id="serviceBeanClaims"
class="org.apache.cxf.systest.jaxrs.security.saml.SecureClaimBookStore"/>
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><bean id="serviceBeanClaims"
class="org.apache.cxf.systest.jaxrs.security.saml.SecureClaimBookStore"/>
<bean id="samlEnvHandler"
class="org.apache.cxf.rs.security.saml.SamlEnvelopedInHandler">
<property name="securityContextProvider">
<bean
class="org.apache.cxf.systest.jaxrs.security.saml.CustomSecurityContextProvider"/>
@@ -491,7 +491,7 @@ public class SecureClaimBookStore {
</jaxrs:server>
</pre>
</div></div><p>An instance of
org.apache.cxf.rs.security.saml.authorization.ClaimsAuthorizingFilter is used
to enforce CBAC. It's a simple JAX-RS filter wrapper around
ClaimsAuthorizingInterceptor. SamlEnvelopedInHandler processes and validates
SAML assertions and it also relies on a simple <a shape="rect"
class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/CustomSecurityContextProvider.java">CustomSecurityContextProvider</a>
to help it to figure out what the actual Subject name is. A more involved
implementation can do some additional validation as well as override few more
super class methods, more on it next. The claims themselves have already been
parsed and will be made available to a resulting SecurityContext which
ClaimsAuthorizingFilter will rely upon.</p><h2
id="JAX-RSSAML-RoleBasedAccessControl">Role Based Access Control</h2><p>If you
have an existing RBAC system (based on javax
.annotation.security.RolesAllowed or even
org.springframework.security.annotation.Secured annotations) in place and have
SAML assertions with claims that are known to represent roles, then making
those claims work with the RBAC system can be achieved easily.</p><p>For
example, given this code:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">import org.springframework.security.annotation.Secured;
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">import org.springframework.security.annotation.Secured;
@Path("/bookstore")
@Claim({"user"})
@@ -505,7 +505,7 @@ public class SecureBookStore {
}
</pre>
</div></div><p>where @Secured can be replaced with @RoledAllowed if needed,
the following configuration will do it:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><bean id="serviceBeanRoles"
class="org.apache.cxf.systest.jaxrs.security.saml.SecureBookStore"/>
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><bean id="serviceBeanRoles"
class="org.apache.cxf.systest.jaxrs.security.saml.SecureBookStore"/>
<bean id="samlEnvHandler"
class="org.apache.cxf.rs.security.saml.SamlEnvelopedInHandler">
<property name="securityContextProvider">
<bean
class="org.apache.cxf.systest.jaxrs.security.saml.CustomSecurityContextProvider"/>