KNOX-3340: Add Control for LDAPRolesLookupInterceptor#1258
Conversation
This commit adds a RolesLookupBypassControl for use with the LDAPRolesLookupInterceptor. The LDAPRolesLookupInterceptor will skip role mapping if this control is present and true in the request.
Test Results22 tests 22 ✅ 2s ⏱️ Results for commit 1efba9a. ♻️ This comment has been updated with latest results. |
smolnar82
left a comment
There was a problem hiding this comment.
A BER-encoded Boolean consists of
- Tag: 1 byte (0x01)
- Length: 1 byte (The size of the value)
- Value: 1 byte (0x00 or 0xFF)
- Total: 3 bytes.
The error in the PR is specifically the content of the middle byte (the "Length" field of the TLV).
In BER, the "Length" byte should only represent the size of the Value portion. For a Boolean, the value is only 1 byte long.
- Current PR encoding: 0x01 (Tag) | 0x03 (Length) | Value (1 byte) -> This says "expect 3 more bytes" but only provides 1.
- Correct BER encoding: 0x01 (Tag) | 0x01 (Length) | Value (1 byte).
Setting the length byte to 0x03 while only providing 1 byte of data might cause standard LDAP clients or strict decoders to fail.
Once this change is done, you may also have to change the documentation.
Great work on the implementation and the tests otherwise!
|
@smolnar82 I've updated the PR for your requested change and also to move the OID into configuration until we get an official OID. |
| public void setBypassRolesLookup() { | ||
| rolesLookupBypassControlDecorator.setBypassRolesLookup(true); | ||
| assertEquals("isBypassRolesLookup should match the value from the decorated Impl", rolesLookupBypassControl.isBypassRolesLookup(), rolesLookupBypassControlDecorator.isBypassRolesLookup()); | ||
| rolesLookupBypassControlDecorator.setBypassRolesLookup(false); | ||
| assertEquals("isBypassRolesLookup should match the value from the decorated Impl", rolesLookupBypassControl.isBypassRolesLookup(), rolesLookupBypassControlDecorator.isBypassRolesLookup()); | ||
| } |
There was a problem hiding this comment.
This is exactly the same test as the previous one. You might want to remove this one and rename the above to testBypassLookup?
There was a problem hiding this comment.
minor difference between the tests.
One checks that the decorator.isBypassRolesLookup matches the decorated instance values by setting the values of the decorated instance.
The other checks that the decorator can set the values on the decorated instance.
I'll tweak the tests to make this more obvious.
| rolesLookupBypassControl.setBypassRolesLookup(true); | ||
| byte[] expectedBytes = new byte[]{0x01, 0x01, (byte) 0xff}; | ||
|
|
||
| ByteBuffer byteBuffer = ByteBuffer.allocate(3); | ||
| ByteBuffer encodedBuffer = rolesLookupBypassControlDecorator.encode(byteBuffer); | ||
| // transition from write mode to read mode | ||
| encodedBuffer.flip(); | ||
| byte[] encodedBytes = new byte[encodedBuffer.remaining()]; | ||
| encodedBuffer.get(encodedBytes); | ||
| assertArrayEquals(expectedBytes, encodedBytes); |
There was a problem hiding this comment.
Maybe creating a new private method (testEncode(boolean encodeTrue)) and call that one from here and from encodeFalseValue? The only difference is the content of expectedBytes, but we'd save some lines of duplication.
| String rolesLookupBypassControlOid = gatewayConfig.getLdapRolesLookupBypassControlOid(); | ||
| if (StringUtils.isNotBlank(rolesLookupBypassControlOid)) { | ||
| if (!Oid.isOid(rolesLookupBypassControlOid)) { | ||
| rolesLookupBypassControlOid = null; |
There was a problem hiding this comment.
I see you are throwing throw new ConfigurationException("Roles Lookup Bypass Control OID is not valid"); below in KnoxLDAPServerManager. However, I think that exception belongs here, when the factory wants to create an instance of LDAPRolesLookupInterceptor.
The creation of this interceptor is also happening in KnoxLDAPServerManager.init() by calling createInterceptors, so it'd fail fast in case someone provided an invalid OID.
What do you think?
There was a problem hiding this comment.
I can get rid of this change since we have an OID.
There was a problem hiding this comment.
outdated comment because I removed the oid configuration
| Asn1Buffer asn1Buffer = new Asn1Buffer(); | ||
| RolesLookupBypassControl control = new RolesLookupBypassControlImpl(ROLES_LOOKUP_BYPASS_CONTROL_OID); | ||
| control.setBypassRolesLookup(true); | ||
|
|
||
| rolesLookupBypassControlFactory.encodeValue(asn1Buffer, control); | ||
|
|
||
| // expectedBytes in reverse because Asn1Buffer stores bytes in reverse order | ||
| byte[] expectedBytes = new byte[]{(byte) 0xff, 0x01, 0x01}; | ||
| System.out.println(asn1Buffer.toString()); | ||
| ByteBuffer encodedBuffer = asn1Buffer.getBytes(); | ||
| byte[] encodedBytes = new byte[encodedBuffer.remaining()]; | ||
| encodedBuffer.get(encodedBytes); | ||
| assertArrayEquals(expectedBytes, encodedBytes); |
There was a problem hiding this comment.
I've the same observation here as above wrt. encode/decode testing (one private method would eliminate the majority of duplicated lines here).
|
|
||
| | Property | Default Value | Description | | ||
| | :--- | :--- | :--- | | ||
| | `gateway.ldap.roles.lookup.bypass.control.oid` | N/A | The OID to use for the bypass control. The control will not be registered if this value is not provided. The Knox LDAP Service will fail to initialize if the value provided is on an OID. | |
There was a problem hiding this comment.
typo: if the value provided is on an OID. -> if the value provided is not an OID.
There was a problem hiding this comment.
removed since OID will not be configurable
|
Hi @handavid ! In addition to the above comments, I see that we have unit test failures now: The good news is that this test may go away, because we now have an official Knox sub-arc under ASF's OID base. See KNOX-3346 for details. |
This removes the configurability of the control OID, updates the documentation, and adds a SchemaConstants class to gateway-spi for holding the official OID. Tests were clarified and refactored into helper methods to reduce code duplication.
412243a to
1efba9a
Compare
KNOX-3340 - Add Control to LDAPRolesLookupInterceptor
What changes were proposed in this pull request?
This commit adds a RolesLookupBypassControl for use with the LDAPRolesLookupInterceptor. The LDAPRolesLookupInterceptor will skip role mapping if this control is present and true in the request. This lets the client decide whether they will receive users' groups or roles.
How was this patch tested?
Unit tests were added to cover the new code.
Manual testing was performed. The LDAP Proxy was configured with the RolesLookup interceptor and the following
ldapsearchcommands were run.Integration Tests
no integration tests added
UI changes
no UI changes