| <!DOCTYPE html> |
| <html lang="en"> |
| |
| <head> |
| <meta charset="UTF-8"> |
| <meta http-equiv="X-UA-Compatible" content="IE=edge"> |
| <meta name="viewport" content="width=device-width, initial-scale=1"> |
| <title>Apache TomEE</title> |
| <meta name="description" |
| content="Apache TomEE is a lightweight, yet powerful, JavaEE Application server with feature rich tooling." /> |
| <meta name="keywords" content="tomee,asf,apache,javaee,jee,shade,embedded,test,junit,applicationcomposer,maven,arquillian" /> |
| <meta name="author" content="Luka Cvetinovic for Codrops" /> |
| <link rel="icon" href="../../favicon.ico"> |
| <link rel="icon" type="image/png" href="../../favicon.png"> |
| <meta name="msapplication-TileColor" content="#80287a"> |
| <meta name="theme-color" content="#80287a"> |
| <link rel="stylesheet" type="text/css" href="../../css/normalize.css"> |
| <link rel="stylesheet" type="text/css" href="../../css/bootstrap.css"> |
| <link rel="stylesheet" type="text/css" href="../../css/owl.css"> |
| <link rel="stylesheet" type="text/css" href="../../css/animate.css"> |
| <link rel="stylesheet" type="text/css" href="../../fonts/font-awesome-4.1.0/css/font-awesome.min.css"> |
| <link rel="stylesheet" type="text/css" href="../../fonts/eleganticons/et-icons.css"> |
| <link rel="stylesheet" type="text/css" href="../../css/jqtree.css"> |
| <link rel="stylesheet" type="text/css" href="../../css/idea.css"> |
| <link rel="stylesheet" type="text/css" href="../../css/cardio.css"> |
| |
| <script type="text/javascript"> |
| <!-- Matomo --> |
| var _paq = window._paq = window._paq || []; |
| /* tracker methods like "setCustomDimension" should be called before "trackPageView" */ |
| /* We explicitly disable cookie tracking to avoid privacy issues */ |
| _paq.push(['disableCookies']); |
| _paq.push(['trackPageView']); |
| _paq.push(['enableLinkTracking']); |
| (function () { |
| var u = "//matomo.privacy.apache.org/"; |
| _paq.push(['setTrackerUrl', u + 'matomo.php']); |
| _paq.push(['setSiteId', '5']); |
| var d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0]; |
| g.async = true; |
| g.src = u + 'matomo.js'; |
| s.parentNode.insertBefore(g, s); |
| })(); |
| <!-- End Matomo Code --> |
| </script> |
| </head> |
| |
| <body> |
| <div class="preloader"> |
| <img src="../../img/loader.gif" alt="Preloader image"> |
| </div> |
| <nav class="navbar"> |
| <div class="container"> |
| <div class="row"> <div class="col-md-12"> |
| |
| <!-- Brand and toggle get grouped for better mobile display --> |
| <div class="navbar-header"> |
| <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> |
| <span class="sr-only">Toggle navigation</span> |
| <span class="icon-bar"></span> |
| <span class="icon-bar"></span> |
| <span class="icon-bar"></span> |
| </button> |
| <a class="navbar-brand" href="/" title="Apache TomEE"> |
| <span> |
| |
| |
| <img |
| src="../../img/apache_tomee-logo.svg" |
| onerror="this.src='../../img/apache_tomee-logo.jpg'" |
| height="50" |
| > |
| |
| |
| </span> |
| </a> |
| </div> |
| <!-- Collect the nav links, forms, and other content for toggling --> |
| <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> |
| <ul class="nav navbar-nav navbar-right main-nav"> |
| <li><a href="../../docs.html">Documentation</a></li> |
| <li><a href="../../community/index.html">Community</a></li> |
| <li><a href="../../security/security.html">Security</a></li> |
| <li><a class="btn btn-accent accent-orange no-shadow" href="../../download.html">Downloads</a></li> |
| </ul> |
| </div> |
| <!-- /.navbar-collapse --> |
| </div></div> |
| </div> |
| <!-- /.container-fluid --> |
| </nav> |
| |
| |
| <div id="main-block" class="container main-block"> |
| <div class="row title"> |
| <div class="col-md-12"> |
| <div class='page-header'> |
| |
| <h1>Securing a Web Service</h1> |
| </div> |
| </div> |
| </div> |
| <div class="row"> |
| |
| <div class="col-md-12"> |
| <div id="preamble"> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>Web Services are a very common way to implement a Service Oriented |
| Architecture (SOA).</p> |
| </div> |
| <div class="paragraph"> |
| <p>There are lots of web service standards/specifications (XML, SOAP, WSDL, |
| UUDI, WS-*, …​) coming from organizations like W3C, OASIS, WS-I, …​ |
| And there are java web service standards like JAX-WS 1.x (JSR 181), |
| JAX-WS 2.0 (JSR 224).</p> |
| </div> |
| <div class="paragraph"> |
| <p>OpenEJB provides a standard way to implement web services transport |
| protocol throughout the JAX-WS specification. Java basic standards for |
| web services (JAX-WS) do lack some features that are required in most |
| real world applications, e.g. standard ways for handling security and |
| authentication (there is no java specification for Oasis’s WS-Security |
| specification).</p> |
| </div> |
| <div class="paragraph"> |
| <p>OpenEJB provides two mechanisms to secure webservices - HTTP |
| authentication and WS-Security:</p> |
| </div> |
| <div class="paragraph"> |
| <p>HTTPS : works at the transport level, enables a point-to-point security. |
| It has no impact on developments. It allows you :</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>To secure data over the network with data encrypted during transport</p> |
| </li> |
| <li> |
| <p>To identify the end user with SSLv3 with client certificate required</p> |
| </li> |
| <li> |
| <p>OpenEJB supports BASIC authentication over HTTP(S), using the |
| configured JAAS provider. This will honour any EJB security roles you |
| have setup using</p> |
| </li> |
| <li> |
| <p>See the webservice-security example in the OpenEJB codebase |
| <a href="https://github.com/apache/tomee/tree/master/examples" class="bare">https://github.com/apache/tomee/tree/master/examples</a></p> |
| </li> |
| </ol> |
| </div> |
| <div class="paragraph"> |
| <p><em>Warning: Currently only BASIC is the only HTTP authentication mechanism |
| available when running OpenEJB standalone or in a unit test, but we hope |
| to support DIGEST in the future.</em></p> |
| </div> |
| <div class="paragraph"> |
| <p>WS-Security: works at the message (SOAP) level, enables a higher-level |
| security, Nowadays, SOAP implementations use other protocols than just |
| HTTP so we need to apply security to the message itself and not only at |
| the transport layer. Moreover, HTTPS can only be used for securing |
| point-to-point services which tend to decrease with Enterprise Service |
| Bus for example.</p> |
| </div> |
| <div class="paragraph"> |
| <p>The Oasis organization has defined a standard (part of well-known WS-*) |
| which aims at providing high level features in the context of web |
| services: WS-Security. It provides a standard way to secure your |
| services above and beyond transport level protocols such as HTTPS. |
| WS-Security relies on other standards like XML-Encryption.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Main features are:</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Timestamp a message,</p> |
| </li> |
| <li> |
| <p>Pass credentials (plain text and/or ciphered) between services,</p> |
| </li> |
| <li> |
| <p>Sign messages,</p> |
| </li> |
| <li> |
| <p>Encrypt messages or part of messages.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="paragraph"> |
| <p>Again, JAX-WS doesn’t standardize security for web services. OpenEJB |
| provides a common and highly configurable way to configure WS-Security |
| in association with the JAX-WS usage without vendor dependence. |
| Internally, OpenEJB integrates Apache WSS4J as the WS-Security |
| implementation. To use the integration, you will need to configure WSS4J |
| using the <em>openejb-jar.xml</em>.</p> |
| </div> |
| <div class="paragraph"> |
| <p><em>Warning: the proposed WS-Security integration is only used at server |
| side. Currently, WS-Security client configuration is not managed by |
| OpenEJB. You can use the JAX-WS API to create a stub and then rely on |
| the implementation to set up WS-Security properties.</em></p> |
| </div> |
| <div class="paragraph"> |
| <p>This configuration file lets you set up incoming and outgoing security |
| parameters. Incoming and outgoing configuration is independent so that |
| you can configure either one or the other or both. You can decide to |
| check client credentials for incoming messages and sign outgoing |
| messages (response).</p> |
| </div> |
| </div> |
| </div> |
| <h1 id="_configuration_principles" class="sect0">Configuration principles</h1> |
| <div class="paragraph"> |
| <p>The configuration is made in the |
| <em>openejb-jar.xml</em>. Each endpoint web service can provide a set of |
| properties to customize WS-Security behavior through the element. The |
| content of this element is consistent with the overall structure of |
| <em>openejb.xml</em>. The format for properties is the same as if you would use |
| a common java property file.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlight"><code class="language-xml" data-lang="xml"><properties> |
| wss4j.in.action = UsernameToken |
| wss4j.in.passwordType = PasswordDigest |
| wss4j.in.passwordCallbackClass=org.superbiz.calculator.CustomPasswordHandler |
| </properties></code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>In order to recover WSS4J properties both for input and output, we use |
| naming conventions. Each property is made of .<in|out>.=</p> |
| </div> |
| <div class="paragraph"> |
| <p>For example : <em>wss4j.in.action = UsernameToken</em></p> |
| </div> |
| <h1 id="_username_token_password_digest_example" class="sect0">Username Token (Password digest) example</h1> |
| <div class="paragraph"> |
| <p>Excerpt from <em>openejb-jar.xml</em>.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlight"><code class="language-xml" data-lang="xml"><openejb-jar xmlns="http://tomee.apache.org/xml/ns/openejb-jar-2.2"> |
| <enterprise-beans> |
| ... |
| <session> |
| <ejb-name>CalculatorImpl</ejb-name> |
| <web-service-security> |
| <security-realm-name/> |
| <transport-guarantee>NONE</transport-guarantee> |
| <auth-method>WS-SECURITY</auth-method> |
| <properties> |
| wss4j.in.action = UsernameToken |
| wss4j.in.passwordType = PasswordDigest |
| wss4j.in.passwordCallbackClass=org.superbiz.calculator.CustomPasswordHandler |
| </properties> |
| </web-service-security> |
| </session> |
| ... |
| </enterprise-beans> |
| </openejb-jar></code></pre> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="_request_sent_by_the_client">Request sent by the client.</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>This request contains SOAP headers to |
| manage security. You can see <em>UsernameToken</em> tag from the WS-Security |
| specification.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlight"><code class="language-properties" data-lang="properties">POST /CalculatorImplUsernameTokenHashedPassword HTTP/1.1 |
| Content-Type: text/xml; charset=UTF-8 |
| SOAPAction: "" |
| Accept: * |
| Cache-Control: no-cache |
| Pragma: no-cache |
| User-Agent: Java/1.5.0_05 |
| Host: 127.0.0.1:8204 |
| Connection: keep-alive |
| Transfer-Encoding: chunked |
| |
| 524 |
| <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> |
| <soap:Header> |
| <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soap:mustUnderstand="1"> |
| <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" |
| wsu:Id="UsernameToken-22402238" |
| xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> |
| <wsse:Username xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">jane</wsse:Username> |
| <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest" |
| xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">tf7k3a4GREIt1xec/KXVmBdRNIg=</wsse:Password> |
| <wsse:Nonce xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">cKhUhmjQ1hGYPsdOLez5kA==</wsse:Nonce> |
| <wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2009-04-14T20:16:26.203Z</wsu:Created> |
| </wsse:UsernameToken> |
| </wsse:Security> |
| </soap:Header> |
| <soap:Body> |
| <ns1:sum xmlns:ns1="http://superbiz.org/wsdl"> |
| <arg0>4</arg0> |
| <arg1>6</arg1> |
| </ns1:sum> |
| </soap:Body> |
| </soap:Envelope></code></pre> |
| </div> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="_the_response_returned_from_the_server">The response returned from the server.</h2> |
| <div class="sectionbody"> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlight"><code class="language-properties" data-lang="properties">HTTP/1.1 200 OK |
| Content-Length: 200 |
| Connection: close |
| Content-Type: text/xml; charset=UTF-8 |
| Server: OpenEJB/??? (unknown os) |
| |
| <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> |
| <soap:Body> |
| <ns1:sumResponse xmlns:ns1="http://superbiz.org/wsdl"> |
| <return>10</return> |
| </ns1:sumResponse> |
| </soap:Body> |
| </soap:Envelope></code></pre> |
| </div> |
| </div> |
| </div> |
| </div> |
| <h1 id="_jaas_with_ws_security" class="sect0">JAAS with WS-Security</h1> |
| <div class="paragraph"> |
| <p>1 doesn’t work straight off with WS-Security, but you can add calls to |
| the OpenEJB SecurityService to login to a JAAS provider to a |
| CallbackHandler. Once you have done this, any permissions configured |
| with 1 should be honoured.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Here is a snippet from the webservice-ws-security example demonstrating |
| this:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlight"><code class="language-java" data-lang="java">public class CustomPasswordHandler implements CallbackHandler { |
| |
| public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { |
| WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; |
| |
| if (pc.getUsage() == WSPasswordCallback.USERNAME_TOKEN) { |
| // TODO get the password from the users.properties if possible |
| pc.setPassword("waterfall"); |
| |
| } else if (pc.getUsage() == WSPasswordCallback.DECRYPT) { |
| |
| pc.setPassword("serverPassword"); |
| |
| } else if (pc.getUsage() == WSPasswordCallback.SIGNATURE) { |
| |
| pc.setPassword("serverPassword"); |
| |
| } |
| |
| if ((pc.getUsage() == WSPasswordCallback.USERNAME_TOKEN) || (pc.getUsage() == WSPasswordCallback.USERNAME_TOKEN_UNKNOWN)) { |
| |
| SecurityService securityService = SystemInstance.get().getComponent(SecurityService.class); |
| Object token = null; |
| try { |
| securityService.disassociate(); |
| |
| token = securityService.login(pc.getIdentifer(), pc.getPassword()); |
| securityService.associate(token); |
| |
| } catch (LoginException e) { |
| e.printStackTrace(); |
| throw new SecurityException("wrong password"); |
| } |
| } |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <h1 id="_examples" class="sect0">Examples</h1> |
| <div class="paragraph"> |
| <p>A full example (webservice-ws-security) is available with <a href="https://github.com/apache/tomee/tree/master/examples/webservice-ws-security">OpenEJB Examples</a>.</p> |
| </div> |
| </div> |
| |
| </div> |
| </div> |
| <div style="margin-bottom: 30px;"></div> |
| <footer> |
| <div class="container"> |
| <div class="row"> |
| <div class="col-sm-6 text-center-mobile"> |
| <h3 class="white">Be simple. Be certified. Be Tomcat.</h3> |
| <h5 class="light regular light-white">"A good application in a good server"</h5> |
| <ul class="social-footer"> |
| <li><a href="https://www.facebook.com/ApacheTomEE/"><i class="fa fa-facebook"></i></a></li> |
| <li><a href="https://twitter.com/apachetomee"><i class="fa fa-twitter"></i></a></li> |
| </ul> |
| <h5 class="light regular light-white"> |
| <a href="../../privacy-policy.html" class="white">Privacy Policy</a> |
| </h5> |
| </div> |
| <div class="col-sm-6 text-center-mobile"> |
| <div class="row opening-hours"> |
| <div class="col-sm-3 text-center-mobile"> |
| <h5><a href="../../latest/docs/" class="white">Documentation</a></h5> |
| <ul class="list-unstyled"> |
| <li><a href="../../latest/docs/admin/configuration/index.html" class="regular light-white">How to configure</a></li> |
| <li><a href="../../latest/docs/admin/file-layout.html" class="regular light-white">Dir. Structure</a></li> |
| <li><a href="../../latest/docs/developer/testing/index.html" class="regular light-white">Testing</a></li> |
| <li><a href="../../latest/docs/admin/cluster/index.html" class="regular light-white">Clustering</a></li> |
| </ul> |
| </div> |
| <div class="col-sm-3 text-center-mobile"> |
| <h5><a href="../../latest/examples/" class="white">Examples</a></h5> |
| <ul class="list-unstyled"> |
| <li><a href="../../latest/examples/simple-cdi-interceptor.html" class="regular light-white">CDI Interceptor</a></li> |
| <li><a href="../../latest/examples/rest-cdi.html" class="regular light-white">REST with CDI</a></li> |
| <li><a href="../../latest/examples/ejb-examples.html" class="regular light-white">EJB</a></li> |
| <li><a href="../../latest/examples/jsf-managedBean-and-ejb.html" class="regular light-white">JSF</a></li> |
| </ul> |
| </div> |
| <div class="col-sm-3 text-center-mobile"> |
| <h5><a href="../../community/index.html" class="white">Community</a></h5> |
| <ul class="list-unstyled"> |
| <li><a href="../../community/contributors.html" class="regular light-white">Contributors</a></li> |
| <li><a href="../../community/social.html" class="regular light-white">Social</a></li> |
| <li><a href="../../community/sources.html" class="regular light-white">Sources</a></li> |
| </ul> |
| </div> |
| <div class="col-sm-3 text-center-mobile"> |
| <h5><a href="../../security/index.html" class="white">Security</a></h5> |
| <ul class="list-unstyled"> |
| <li><a href="https://apache.org/security" target="_blank" class="regular light-white">Apache Security</a></li> |
| <li><a href="https://apache.org/security/projects.html" target="_blank" class="regular light-white">Security Projects</a></li> |
| <li><a href="https://cve.mitre.org" target="_blank" class="regular light-white">CVE</a></li> |
| </ul> |
| </div> |
| </div> |
| </div> |
| </div> |
| <div class="row bottom-footer text-center-mobile"> |
| <div class="col-sm-12 light-white"> |
| <p>Copyright © 1999-2022 The Apache Software Foundation, Licensed under the Apache License, Version 2.0. Apache TomEE, TomEE, Apache, the Apache feather logo, and the Apache TomEE project logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners.</p> |
| </div> |
| </div> |
| </div> |
| </footer> |
| <!-- Holder for mobile navigation --> |
| <div class="mobile-nav"> |
| <ul> |
| <li><a hef="../../latest/docs/admin/index.html">Administrators</a> |
| <li><a hef="../../latest/docs/developer/index.html">Developers</a> |
| <li><a hef="../../latest/docs/advanced/index.html">Advanced</a> |
| <li><a hef="../../community/index.html">Community</a> |
| </ul> |
| <a href="#" class="close-link"><i class="arrow_up"></i></a> |
| </div> |
| <!-- Scripts --> |
| <script src="../../js/jquery-1.11.1.min.js"></script> |
| <script src="../../js/owl.carousel.min.js"></script> |
| <script src="../../js/bootstrap.min.js"></script> |
| <script src="../../js/wow.min.js"></script> |
| <script src="../../js/typewriter.js"></script> |
| <script src="../../js/jquery.onepagenav.js"></script> |
| <script src="../../js/tree.jquery.js"></script> |
| <script src="../../js/highlight.pack.js"></script> |
| <script src="../../js/main.js"></script> |
| </body> |
| |
| </html> |
| |