This is a list of requirements for this application:
- Web Application must be SSO enabled using WS-Federation
- Role Based Access Control (RBAC) required for Web Application
- users are managed in an LDAP directory
- security solution integrated without programming
- industry standards should be used (WS-SecurityPolicy, Servlet- and JAX-WS Security API)
- Web Services are secured with SAML 2.0 to authenticate the browser user
- Web Services trust a WS-Trust Security Token Service (STS)
- SAML token for authentication only (SupportingToken, WS-SecurityPolicy)
- RBAC might be required for Web services in a future release
- Confidentiality and Integrity on transport level (HTTPS)
- prevent man-in-the-middle attack
You might think this are a bunch of very sophisticated requirements and will cost a lot of money to implement. The answer is no. In this blog I'll introduce the architecture and design and in the next blog how to realize that with Apache CXF and Tomcat.
The following diagram illustrate the overall architecture:
The key components are the WS-Trust Security Token Service (STS) and the Identity Provider (IDP) which is part of the WS-Federation Passive Requestor Profile. If you are familiar with my previous blogs about Web SSO...
The sequence of steps can be splitted into two parts the Web login and the security for the Web Services.
The Web login starts when the user access the Web Application the first time. The Web Application redirects the browser to the IDP for authentication. The IDP transforms and delegates the request to the STS. The STS validates the user against the LDAP directory and issues a signed SAML token. The browser posts the SAML token to the Web Application which validates the token and creates the security context. This part is described in more details in the above mentioned blogs.
Role information can be accessed using standard security constraints in web.xml or using the Java Servlet API without worrying about the underlying SAML security token or accessing the LDAP directory explicitly.
The second part is the security for Web Services when the user does a step in the application which requires a call to a Web Services. The Web Services stack processes the WS-SecurityPolicy of the service provider where it is described to send a token issued by the STS. The Web Services stack sends an Issue request to the STS on behalf of the browser user. The STS validates the incoming credentials and issues the requested signed SAML token for the target Web Service. The Web Services stack caches the token and attachs it to the outgoing Web Services call. The service provider trusts the STS and can therefore validate the signed SAML token on its own.
I'd like to describe the second request to the STS in more details where the Web Services stack requests a token on behalf of the browser user. You must be in the possession of the credentials (ex. password) to request a token for the browser user - otherwise, anybody could request a token for someone else without knowing the passwort using a took like SOAPUI. The Web Application itself doesn't know the password because the authentication is externalized to the IDP. Even if the authentication had been done by the Web Application the password wouldn't have been cached by the application server for security reasons. OK, you don't possess the password but you got the signed SAML token which you can only get if you provided the credentials to the STS initially. This token must be protected on the wire when exchanged between browser and IDP, the browser and the Web Application and the Web Application and the STS. The option with the best performance is SSL/TLS.
For further confidentiality protection you could encrypt the token with the certificate of the application thus only the application is able to process the token. This is a supported feature of the CXF STS.
The SAML token is cached by the application server and is provided to the Web Services stack to request a new token when required. This use case is covered by the WS-Trust specification with the OnBehalfOf element (or ActAs) in the request to the STS. The STS validates the SAML token in the OnBehalfOf element and issues a new token based on the requirements of the Web Services which are described in its WS-SecurityPolicy document and send to the STS in the SecondaryParameters element.
There are some service calls before a request is sent to the service provider. The request to the STS is the most expensive as it might require to access some ID stores to read user attributes, roles (so called claims) to add it to the SAML token. Usually, a security token has some sort of lifetime either described in the security token itself (SAML condition) or some out-of-band agreement and known by the STS only. The WS-Trust specifiction defines the Lifetime element in the response to tell the token requestor the lifetime in a security token agnostic way. Thus, the Web Services stack just have to cache the returned security token (XML element) and the LifeTime element to prevent sending an issue request for every outgoing Web Service call.
Going through the requirements above... the solution above covers all of them.
How to implement this solution is described here