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

ISPN-5790 AuthorizationManager rework #3726

Conversation

tristantarrant
Copy link
Member

https://issues.jboss.org/browse/ISPN-5790

  • use an internal cache instead of the Cluster Registry
  • add a GlobalSecurityManager with the ability to flush acl caches
  • don't cache per-cache acl masks
  • add a role check in addition to the existing permission check

}
int permissionMask = requiredPermission.getMask();
return (subjectMask & permissionMask) == permissionMask && requestedRole.map(r -> subjectACL.roles.contains(r)).orElse(true);
Copy link
Member

Choose a reason for hiding this comment

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

nitpick: lambda could be replaced by subjectACL.roles::contains

@tristantarrant
Copy link
Member Author

I have made some further changes:

  • the ACL cache is disabled if the global securityCacheTimeout is set to 0 (as per discussion with @Sanne yesterday on IRC) for cases where users need real-time enforcement of user permissions changes. The global security mbean has an MBean op to flush the ACL cache manually.
  • the key in the ACL cache is now a combination of cache and the Subject's user principal
  • the ACL mask for a subject is precomputed and cached
  • The ACL cache is a "simple cache", since it is local-only

@pruivo
Copy link
Member

pruivo commented Oct 8, 2015

some nitpick about GlobalSecurityManagerImpl:

  • you could use a ConcurrentHashMap when expiration is not needed.
  • Instead of storing the CacheManager and a boolean, you can store the reference to the map.

private int computeHashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((cacheName == null) ? 0 : cacheName.hashCode());
Copy link
Member

Choose a reason for hiding this comment

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

can the cacheName or the principalName be null?

Copy link
Member

Choose a reason for hiding this comment

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

That is an interesting question, but I guess not a big deal either way.

@Sanne
Copy link
Member

Sanne commented Oct 8, 2015

A cache based on the Principals's name is only effective if you assume there is a limited number of principals accessing, otherwise you're risking to store a lot of data for no good reason - and probably still have a low hit rate.
I think that's another good reason to keep the ACL cache disabled by default.

@tristantarrant
Copy link
Member Author

@Sanne not really if we assume that a principal will perform operations on the cache in bursts: you want to cache the ACL on the first op so that subsequent ops can reuse it. Set a low expiration for this case.
Another case where the ACL cache is an advantage is when principals are used to coarsely identify applications and not nominal users. So few principals, lots of repeated access.

@tristantarrant
Copy link
Member Author

@Sanne I see the use-case of lots of individual principals less practical / useful in the real world.

@tristantarrant tristantarrant force-pushed the ISPN-5790/authz_manager_rework branch 2 times, most recently from 754d61e to e6e534f Compare October 12, 2015 15:01
@tristantarrant
Copy link
Member Author

@pruivo Regarding the GlobalSecurityManagerImpl nitpicks:
Unfortunately I cannot retrieve the cache in the @Inject, since it may not be available yet at that stage. That is why I have that "cacheEnabled" boolean (which, I agree, is not very nice).

/**
* Removes the internal caches from the specified set of cache names
*/
void filterPrivateCaches(Set<String> names);
Copy link
Member

Choose a reason for hiding this comment

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

Why the name change? The javadoc still mentions internal caches...

Copy link
Member Author

Choose a reason for hiding this comment

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

The javadoc is wrong and the actual implementation was filtering the private caches :) I'll fix this

@tristantarrant
Copy link
Member Author

@danberindei ready to go !

@tristantarrant
Copy link
Member Author

@danberindei repushed :)

@@ -12,7 +12,8 @@
*/
GlobalAuthorizationConfigurationBuilder authorization();
/**
* Defines the timeout in milliseconds for which to cache user access roles
* Defines the timeout in milliseconds for which to cache user access roles. A value of -1 means the entries
Copy link
Member

Choose a reason for hiding this comment

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

I know this might be too late now. But was there a reason we forced this to be milliseconds and didn't just do the new common method of passing a long and a TimeUnit?

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed it. Added a new method and deprecated the old one

private SubjectACL computeSubjectACL(Subject subject, AuthorizationConfiguration configuration) {
PrincipalRoleMapper roleMapper = globalConfiguration.authorization().principalRoleMapper();
Set<Principal> principals = subject.getPrincipals();
Set<String> allRoles = new HashSet<>(principals.size());
Copy link
Member

Choose a reason for hiding this comment

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

Couldn't there be a lot more roles than # of principals? How many principals would a subject have normally? I wonder if we just use the default constructor which sizes the array to 16 might be better?

Copy link
Member Author

Choose a reason for hiding this comment

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

I would say that maybe not all principals would map to a role. The case where a principal might map to multiple roles is unlikely in my experience.

@wburns
Copy link
Member

wburns commented Oct 29, 2015

Just some minor things, otherwise looks good 👍

@tristantarrant
Copy link
Member Author

@wburns I addressed your comments (unless where noted)

@danberindei
Copy link
Member

@tristantarrant more test failures...

@tristantarrant
Copy link
Member Author

@danberindei only one test failure is security related, but it's to do with JGroups SASL authentication, so not connected to this PR.

- use an internal cache instead of the Cluster Registry
- add a GlobalSecurityManager with the ability to flush acl caches
- don't cache per-cache acl masks
- add a role check in addition to the existing permission check
@danberindei
Copy link
Member

Integrated at long last! Thanks Tristan!

@danberindei danberindei closed this Nov 2, 2015
@tristantarrant tristantarrant deleted the ISPN-5790/authz_manager_rework branch November 5, 2015 19:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants