Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove equals & hashcode based on JWT, KafkaPrincipal ones will be in effect #60

Closed
wants to merge 5 commits into from

Conversation

uwburn
Copy link
Contributor

@uwburn uwburn commented Jun 2, 2020

No description provided.

@uwburn uwburn force-pushed the jwtkafkaprincipal_equality branch from 54de20b to 46a0d16 Compare June 2, 2020 09:57
@scholzj scholzj requested a review from mstruk June 2, 2020 11:35
@scholzj
Copy link
Member

scholzj commented Jun 2, 2020

Can you add some tests that the equals(...) method still works after your change?

@scholzj
Copy link
Member

scholzj commented Jun 2, 2020

You should also look at the spotbugs - it looks like you should have some equals imeplementation there.

[ERROR] io.strimzi.kafka.oauth.server.authorizer.JwtKafkaPrincipal doesn't override org.apache.kafka.common.security.auth.KafkaPrincipal.equals(Object) [io.strimzi.kafka.oauth.server.authorizer.JwtKafkaPrincipal] At JwtKafkaPrincipal.java:[line 1] EQ_DOESNT_OVERRIDE_EQUALS

@uwburn
Copy link
Contributor Author

uwburn commented Jun 2, 2020

Thanks for the headup about spotbug, i will also try to arrange a the test.

There's a thing i would like to point out, in any case: connections.max.reauth.ms is VERY important from what i've understood, because without it, the client does refresh the token, but the reauth does not take place against the broker, meaning it will keep the old auth data, and i'm quite sure that when also dealing with authz this is incovenient. I have verified this by looking at the net traffic with wireshark, without the option the token is sent to Kafka just when the connection is estabilished, with the option the token is actually sent periodically. I went through this because i'm trying to add the support for the Node.js client.

If you have time, i suggest you to take a look at it, the behaviour of the oauth plugin, while seemingly fine from what i have experienced so far (apart the equality stuff), probably needs some checks and it should also be pointed out in the documentation the relevancy of specifying connections.max.reauth.ms.

@uwburn
Copy link
Contributor Author

uwburn commented Jun 2, 2020

I'm a bit lost on the test. I see that there are in place test with various providers as integration/system tests.

I'm afraid testing the effects of the equals implementation is really entangled with Kafka internals that are beyond my possibility of digging out.

Also i'm not familiar with spotbugs, i tried mvn spotbugs:check to replicate Travis error, but to no avail. Is it the correct command?

I changed the equals/hashcode to:

    @Override
    public boolean equals(Object o) {
        return super.equals(o);
    }

    @Override
    public int hashCode() {
        return super.hashCode();
    }

But that's really silly, and any other meaningful check on the JWT itself seems redundant with what's already in place on the KafkaPrincipal implementation, for how JwtKafkaPrincipal is constructed.

@scholzj
Copy link
Member

scholzj commented Jun 2, 2020

Also i'm not familiar with spotbugs, i tried mvn spotbugs:check to replicate Travis error, but to no avail. Is it the correct command?

mvn spotbugs:check seems to be what the Travis is running. So that should be it. I think Spotbugs needs to to build it first, so maybe you should run mvn clean package spotbugs:check or something similar?

I'm a bit lost on the test. I see that there are in place test with various providers as integration/system tests.

I'm not sure if @mstruk has any ideas. But I think you should add. simple Unit test which would show that twoprincipals which should equal return true and two principals which should not equal should return false.

@mstruk
Copy link
Contributor

mstruk commented Jun 3, 2020

@uwburn Thank you for a very valuable analysis.

We had some discussion around equals() / hashCode() on initial PR of authz support with @tombentley and the intuitively safe no-op implementation like you suggested as silly was deemed as such back then. It wasn't quite clear to me at the time how this is used and where it might cause problems - e.g. is it or will it be one day used in a HashMap in what should it mean exactly ...

It's clear now that the extra payload of jwt field should not be included in the equals() evaluation, and thus the safest approach really is for super.equals() to be used in case they add some relevant extra information. Another approach for the future is to store JWT completely separately from the principal object - into a cache.

The override with just delegation to super has a benefit of telling everyone that we didn't forget about thinking about equals() and hashCode(), and that's the intent of the spotbugs - although it's very easy to brainlessly add it as a routine, and it does look a bit silly by itself. On the other hand if we just suppress the warning that also means that we had to think about it at least a little bit, so it's the same.

I'd say we just remove equals() and hashCode(), add the warning suppresion annotation on the class, and add a comment that we delegate equals() / and hashCode() to super on purpose.

We don't really have unit tests, just the integration tests. I'd have to think some more where exactly to put the test, let me look at that some more.

Copy link
Contributor

@mstruk mstruk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the test. See: uwburn#1

@mstruk
Copy link
Contributor

mstruk commented Jun 4, 2020

@uwburn If you merge my uwburn#1 PR to your branch, we can then merge this PR.

Add test for the JwtKafkaPrincipal equals() and hashCode()
@scholzj scholzj requested a review from tombentley June 4, 2020 14:39
@scholzj
Copy link
Member

scholzj commented Jun 8, 2020

@tombentley Could you have a look at this please if you have a minute?

@scholzj scholzj added this to the 0.6.0 milestone Jun 8, 2020
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

/**
* This class uses the KafkaPrincipal object to store additional info obtained at sesion authentication time,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* This class uses the KafkaPrincipal object to store additional info obtained at sesion authentication time,
* This class uses the KafkaPrincipal object to store additional info obtained at session authentication time,

*
* Any additional fields should not be included in equals / hashcode check. If they are, that will break re-authentication.
*/
@SuppressFBWarnings("EQ_DOESNT_OVERRIDE_EQUALS")
public class JwtKafkaPrincipal extends KafkaPrincipal {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't ever expect this class to be subclassed, but I guess if it were the subclass could override equals()/hashCode(), breaking this contract. So I suppose we should either make this class final, or do it as originally with overridden (but final) equals()/hashCode() delegating to super.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like an overkill to me, but sure, we can make the class final.
Not that it should be treated like a contract with third party devs that might get an impression that it's a good idea to extend our classes, and think that we won't one day completely change them. Everything in terms of classes, methods, and configuration that we don't explicitly document should be treated as an implementation detail that can change at any time.
This final should only be considered a failsafe for a contributor to this project, to save them from inadvertently re-introducing the bug.

@mstruk
Copy link
Contributor

mstruk commented Jun 8, 2020

@uwburn If you can merge uwburn#2, and then we're done here.

Make JwtKafkaPrincipal final + fix typo as suggested in strimzi#60
@uwburn
Copy link
Contributor Author

uwburn commented Jun 9, 2020

Sorry for the delay, i was away from home.

mstruk added a commit to mstruk/strimzi-kafka-oauth that referenced this pull request Jun 15, 2020
@mstruk
Copy link
Contributor

mstruk commented Jun 15, 2020

Continuing this in #64.

@uwburn Thanks again for the contribution.

@mstruk mstruk closed this Jun 15, 2020
scholzj pushed a commit that referenced this pull request Jun 15, 2020
…cation (#64)

* Remove equals & hashcode based on JWT, KafkaPrincipal ones will apply

Signed-off-by: Michele Tibaldi <[email protected]>

* Add test for the JwtKafkaPrincipal equals() and hashCode()

Signed-off-by: Marko Strukelj <[email protected]>

* Make JwtKafkaPrincipal final + fix typo as suggested in #60

Signed-off-by: Marko Strukelj <[email protected]>

Co-authored-by: Michele Tibaldi <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants