Simon Wong (Migrated from SEC-1351) said:
Most of the Spring Security 3.0 API has been refactored to use Collection rather than native Java Array. e.g. UserDetails.getAuthorities() now returns Collection. However, this would result API inconsistency for historical classes. One of them is GrantedAuthoritiesContainerImpl.get/setGrantedAuthorities which accept List. Sometimes, down casting is possible, but sometimes doesn't (For example, grantedAuthoritiesContainerImpl.setGrantedAuthorities(userDetails.getAuthorities()) will not be compiled). The API should be refactored a step more such that consistency could be maintained. Personal speaking, List is preferred to Collection<?> as it supports get(index) function rather than just retrieve element through iteration.
Luke Taylor said:
The choice of Collection over List is mainly intended to allow the use of a Set for the authorities collection. Some implementations use very large numbers of permissions which are mapped to authorities. Using a List or array, the performance of an access-control check degrades as the number of authorities increases. A set can potentially allow a more efficient implementation to be used.
The GrantedAuthoritiesContainer is typically implemented by the Authentication details object, as a means of obtaining pre-authenticated authorities from an incoming request, so it is unlikely that the collection loaded from a UserDetails would be passed to the setGrantedAuthorities method.
I'm not sure whether we should attempt to squeeze in an interface change like this to an early 3.0.1 release or not. It is inconsistent, but it is not a serious problem. On the other hand, the impact would also be negligible and it is unlikely to affect many people. Those upgrading from 2 will need to change the interface anyway.
Actually, thinking about this some more, I don't really see any pressing reason for interfaces like GrantedAuthoritiesContainer to use a collection instead of a List. The motivation is clear for Authentication (and thus, indirectly, UserDetails) but I don't really see a problem with GrantedAuthoritiesContainer using a List.
Leaving as is for now.
Simon Wong said:
Sorry that I am busy on my project development before and late for leaving comment. My scenarios are as follows.
I guess step 3 is the arguable whether it is the correct approach or not.
That's not really the intended use of GrantedAuthoritiesContainerImpl. You would normally load the authorities through the PreAuthenticationAuthenticationProvider.
Plus you can always cast or convert the collection to a list if required.
Let me try to update my program to follow the correct use of GrantedAuthoritiesContainerImpl.
Down casting from Collection to List requires explicit cast and not always works between version (You might implements Collection through Set for performance reason in later version, such that it throws ClassCastException and will breaks the program). Anyway, this issue is just a minor one and always have workaround.
As I said, you should be loading the authorities from the provider in any case through the injected UserDetailsService. The GrantedAuthoritiesContainer is intended for containing information extracted from the incoming request, not by accessing a database.