[SWS-890] Can the WSSecurityEngine used in Wss4jSecurityInterceptor be externalized to introduce custom behaviour? Created: 02/Feb/15  Updated: 09/Feb/16  Resolved: 09/Feb/16

Status: Closed
Project: Spring Web Services
Component/s: None
Affects Version/s: None
Fix Version/s: 2.3.0

Type: New Feature Priority: Major
Reporter: saiprasad krishnamurthy Assignee: Greg Turnquist
Resolution: Complete Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Pull Request URL: https://github.com/spring-projects/spring-ws/pull/58

 Description   

Hello Guys,
I'm currently investigating to use spring-ws along with spring-ws-security-2.13.RELEASE for my security use case.

I'm using Wss4jSecurityInterceptor based approach.

These are what I'm after:

  • I want to perform Encryption/Decryption using PKI for confidentiality.
  • I want to perform Signature verification.
  • I want to perform authentication using the UsernameToken scheme.

These are the caveats:

  • My user store is LDAP (where the password is already hashed and stored). I don't have access to the "clear text" password on the server side to be passed in the call back (AbstractWsPasswordCallbackHandler).

Here is one approach:

  • I would encrypt the UsernameToken (using the same PKI) and decrypt on the server side - This enables me to send the password as a "clear text" at the same time achieving message confidentiality.
  • However, this doesn't solve the problem of authenticating the user with LDAP because I don't have the "clear text" password in the server side.

Observations:
I was looking into Wss4jSecurityInterceptor.java and it appears to be that the securityEngine is defined as private final.I completely understand the reasons of being this the way it is as the clients shouldn't be able to alter the sensitive functionality and break the framework.

However, in my case, if this securityEngine was externalizable (injectable), I can provide my implementation of the engine which can then suppress the UsernameToken (password validation).

This helps me to then to get the Username and Password in my interceptor in the overridden checkResults method which can be used for LDAP Authentication. I will have the full access to the username and password here.

Here is my custom WSSecurityEngine:

 @Override
    public List<WSSecurityEngineResult> processSecurityHeader(Element arg0, RequestData arg1) throws WSSecurityException {
        WSSConfig config = arg1.getWssConfig();
        config.setValidator(WSSecurityEngine.USERNAME_TOKEN, SuppressedUsernameTokenValidator.class);
        return super.processSecurityHeader(arg0, arg1);
    }

Back in my SecurityInterceptor (that extends Wss4jSecurityInterceptor):

 @Override
    protected void checkResults(List<WSSecurityEngineResult> results, List<Integer> validationActions) {
        for (WSSecurityEngineResult res : results) {
			if (res.get("username-token") != null) {
                UsernameToken usernameToken = (UsernameToken) res.get("username-token");
                String username = usernameToken.getName();
                String password = usernameToken.getPassword();
				
				// Perform LDAP Authentication using the username and password.
			  } 
			}
		}

Can the WSSecurityEngine be made injectable in Wss4jSecurityInterceptor or is there any other standard way to implement what I'm after? Thanks for your time.



 Comments   
Comment by Greg Turnquist [ 27/Jan/16 ]

Evaluate if this fits the scope of Spring WS 2.3.

Generated at Tue Dec 12 16:06:28 UTC 2017 using JIRA 6.4.14#64029-sha1:ae256fe0fbb912241490ff1cecfb323ea0905ca5.