spring-projects / spring-projects/spring-security

SEC-1908: Remove bounded wildcard return types

Open
#2,127 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

in: core in: ldap type: breaks-passivity type: jira
Dominant language
Java
Stars
9.6k
Forks
6.3k
Avg merge
2d 11h
Merged PRs (30d)
52

Description

Mikhail Mazursky (Migrated from SEC-1908) said:

I was updating spring 3.0.x to 3.1.0 and one of my tests (with Mockito) showed a compilation error. The problem i encountered was the same as described here 1:

LdapAuthoritiesPopulator authoritiesPopulator = mock(LdapAuthoritiesPopulator.class);

when(authoritiesPopulator.getGrantedAuthorities(userData, USERNAME)).thenReturn(AuthorityUtils.NO_AUTHORITIES);

This is not type safe but that problem can be worked around by:

doReturn(AuthorityUtils.NO_AUTHORITIES).when(authoritiesPopulator).getGrantedAuthorities(userData, USERNAME);

The question is should the LdapAuthoritiesPopulator interface's method getGrantedAuthorities have a bounded wildcard return type or not? I think it's better to remove wildcard as it gives nothing to the calling code.

Spring 3.0.x have it as:

Collection getGrantedAuthorities(DirContextOperations userData, String username);

and 3.1.0 as:

Collection<? extends GrantedAuthority> getGrantedAuthorities(DirContextOperations userData, String username);

The same problem with GrantedAuthoritiesMapper, GrantedAuthoritiesContainer, Attributes2GrantedAuthoritiesMapper, WebSpherePreAuthenticatedWebAuthenticationDetailsSource and possibly some other classes/ifaces.

Interesting reading on the topic 2.

Methods with bounded wildcard return types

PUBLIC

  • ~.FindBoundedWildcardsTest$Here#here
  • ~.access.annotation.AnnotationMetadataExtractor#extractAttributes
  • ~.access.annotation.BusinessService#methodReturningAList
  • ~.access.annotation.BusinessServiceImpl#methodReturningAList
  • ~.access.annotation.ExpressionProtectedBusinessServiceImpl#methodReturningAList
  • ~.access.annotation.Jsr250BusinessServiceImpl#methodReturningAList
  • ~.access.annotation.SecuredAnnotationSecurityMetadataSourceTests$CustomSecurityAnnotationMetadataExtractor#extractAttributes
  • ~.access.expression.method.PrePostAnnotationSecurityMetadataSourceTests$ReturnAList#doSomething
  • ~.access.expression.method.PrePostAnnotationSecurityMetadataSourceTests$ReturnAListImpl1#doSomething
  • ~.access.expression.method.PrePostAnnotationSecurityMetadataSourceTests$ReturnAListImpl2#doSomething
  • ~.access.expression.method.PrePostAnnotationSecurityMetadataSourceTests$ReturnAnotherList#doSomething
  • ~.access.expression.method.PrePostAnnotationSecurityMetadataSourceTests$ReturnAnotherListImpl1#doSomething
  • ~.access.expression.method.PrePostAnnotationSecurityMetadataSourceTests$ReturnAnotherListImpl2#doSomething
  • ~.access.hierarchicalroles.NullRoleHierarchy#getReachableGrantedAuthorities
  • ~.access.hierarchicalroles.RoleHierarchy#getReachableGrantedAuthorities
  • ~.access.hierarchicalroles.RoleHierarchyAuthoritiesMapper#mapAuthorities
  • ~.access.intercept.AbstractSecurityInterceptor#getSecureObjectClass
  • ~.access.intercept.AbstractSecurityInterceptorTests$MockSecurityInterceptorReturnsNull#getSecureObjectClass
  • ~.access.intercept.AbstractSecurityInterceptorTests$MockSecurityInterceptorWhichOnlySupportsStrings#getSecureObjectClass
  • ~.access.intercept.RunAsUserToken#getOriginalAuthentication
  • ~.access.intercept.aopalliance.MethodSecurityInterceptor#getSecureObjectClass
  • ~.access.vote.AbstractAccessDecisionManager#getDecisionVoters
  • ~.access.vote.AbstractAclVoter#getProcessDomainObjectClass
  • ~.authentication.event.InteractiveAuthenticationSuccessEvent#getGeneratedBy
  • ~.authorization.method.PreAuthorizeAuthorizationManagerTests$TestTargetClassAware#getTargetClass
  • ~.authorization.method.SecuredAuthorizationManagerTests$TestTargetClassAware#getTargetClass
  • ~.concurrent.DelegatingSecurityContextExecutorService#submit
  • ~.concurrent.DelegatingSecurityContextScheduledExecutorService#schedule
  • ~.concurrent.DelegatingSecurityContextScheduledExecutorService#scheduleAtFixedRate
  • ~.concurrent.DelegatingSecurityContextScheduledExecutorService#scheduleWithFixedDelay
  • ~.config.annotation.AbstractConfiguredSecurityBuilder#getSharedObjects
  • ~.config.annotation.web.FormLoginDsl#getAuthenticationDetailsSource
  • ~.config.annotation.web.HttpBasicDsl#getAuthenticationDetailsSource
  • ~.config.annotation.web.OAuth2LoginDsl#getAuthenticationDetailsSource
  • ~.config.annotation.web.messaging.MessageSecurityMetadataSourceRegistry$MatcherBuilder#build
  • ~.config.annotation.web.messaging.MessageSecurityMetadataSourceRegistry$PathMatcherMessageMatcherBuilder#build
  • ~.config.annotation.web.messaging.MessageSecurityMetadataSourceRegistry$PreBuiltMatcherBuilder#build
  • ~.config.annotation.web.oauth2.resourceserver.JwtDsl#getJwtAuthenticationConverter
  • ~.config.annotation.web.oauth2.resourceserver.JwtDslTests$CustomJwtAuthenticationConverterConfig$Companion#getCONVERTER
  • ~.config.authentication.AuthenticationManagerFactoryBean#getObjectType
  • ~.config.core.userdetails.ReactiveUserDetailsServiceResourceFactoryBean#getObjectType
  • ~.config.core.userdetails.UserDetailsMapFactoryBean#getObjectType
  • ~.config.core.userdetails.UserDetailsResourceFactoryBean#getObjectType
  • ~.config.http.HandlerMappingIntrospectorFactoryBean#getObjectType
  • ~.config.http.HttpConfigurationBuilder$SecurityContextHolderStrategyFactory#getObjectType
  • ~.config.http.OAuth2ResourceServerBeanDefinitionParser$NimbusJwtDecoderJwkSetUriFactoryBean#getObjectType
  • ~.config.http.OAuth2ResourceServerBeanDefinitionParserTests$ClockFactoryBean#getObjectType
  • ~.config.http.OAuth2ResourceServerBeanDefinitionParserTests$JwtDecoderFactoryBean#getObjectType
  • ~.config.http.OAuth2ResourceServerBeanDefinitionParserTests$MockWebServerFactoryBean#getObjectType
  • ~.config.http.OAuth2ResourceServerBeanDefinitionParserTests$MockWebServerPropertiesFactoryBean#getObjectType
  • ~.config.http.OAuth2ResourceServerBeanDefinitionParserTests$OpaqueTokenIntrospectorFactoryBean#getObjectType
  • ~.config.ldap.EmbeddedLdapServerContextSourceFactoryBean#getObjectType
  • #11805
  • #11804
  • #11803
  • #11802
  • #11801
  • ~.config.provisioning.UserDetailsManagerResourceFactoryBean#getObjectType
  • ~.config.web.server.ServerJwtDsl#getJwtAuthenticationConverter
  • ~.config.web.server.ServerJwtDslTests$CustomJwtAuthenticationConverterConfig$Companion#getCONVERTER
  • ~.config.websocket.WebSocketMessageBrokerConfigTests$ExceptingInterceptor#preSend
  • ~.config.websocket.WebSocketMessageBrokerSecurityBeanDefinitionParser$SecurityContextHolderStrategyFactory#getObjectType
  • ~.core.Authentication#getAuthorities
  • ~.core.authority.GrantedAuthoritiesContainer#getGrantedAuthorities
  • ~.core.authority.mapping.Attributes2GrantedAuthoritiesMapper#getGrantedAuthorities
  • ~.core.authority.mapping.GrantedAuthoritiesMapper#mapAuthorities
  • ~.core.authority.mapping.NullAuthoritiesMapper#mapAuthorities
  • ~.core.userdetails.UserDetails#getAuthorities
  • ~.jackson2.UnmodifiableMapDeserializer#deserialize
  • ~.ldap.authentication.UserDetailsServiceLdapAuthoritiesPopulator#getGrantedAuthorities
  • ~.ldap.userdetails.LdapAuthoritiesPopulator#getGrantedAuthorities
  • ~.messaging.access.intercept.AuthorizationChannelInterceptor#preSend
  • ~.messaging.access.intercept.ChannelSecurityInterceptor#getSecureObjectClass
  • ~.messaging.access.intercept.ChannelSecurityInterceptor#postReceive
  • ~.messaging.access.intercept.ChannelSecurityInterceptor#preSend
  • ~.messaging.access.intercept.MessageMatcherDelegatingAuthorizationManager$Builder#build
  • ~.messaging.context.SecurityContextChannelInterceptor#beforeHandle
  • ~.messaging.context.SecurityContextChannelInterceptor#preSend
  • ~.messaging.web.csrf.CsrfChannelInterceptor#preSend
  • ~.oauth2.client.endpoint.AbstractOAuth2AuthorizationGrantRequestEntityConverter#convert
  • ~.oauth2.client.oidc.authentication.OidcIdTokenDecoderFactory#createDefaultClaimTypeConverters
  • ~.oauth2.client.oidc.authentication.ReactiveOidcIdTokenDecoderFactory#createDefaultClaimTypeConverters
  • ~.oauth2.client.oidc.userinfo.OidcReactiveOAuth2UserService#createDefaultClaimTypeConverters
  • ~.oauth2.client.oidc.userinfo.OidcUserService#createDefaultClaimTypeConverters
  • ~.oauth2.client.userinfo.OAuth2UserRequestEntityConverter#convert
  • ~.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction#defaultRequest
  • ~.oauth2.core.DefaultOAuth2AuthenticatedPrincipal#getAuthorities
  • ~.oauth2.core.OAuth2AuthenticatedPrincipal#getAuthorities
  • ~.oauth2.core.user.DefaultOAuth2User#getAuthorities
  • ~.oauth2.server.resource.introspection.OAuth2IntrospectionAuthenticatedPrincipal#getAuthorities
  • ~.provisioning.MutableUser#getAuthorities
  • ~.scheduling.DelegatingSecurityContextTaskScheduler#schedule
  • ~.scheduling.DelegatingSecurityContextTaskScheduler#scheduleAtFixedRate
  • ~.scheduling.DelegatingSecurityContextTaskScheduler#scheduleWithFixedDelay
  • ~.task.DelegatingSecurityContextAsyncTaskExecutor#submit
  • ~.test.context.showcase.CustomUserDetails#getAuthorities
  • ~.test.context.support.WithSecurityContext#factory
  • ~.web.access.intercept.FilterSecurityInterceptor#getSecureObjectClass
  • ~.web.authentication.switchuser.SwitchUserAuthorityChanger#modifyGrantedAuthorities
  • ~.web.authentication.www.BasicAuthenticationConverter#getAuthenticationDetailsSource

PROTECTED

  • ~.acls.afterinvocation.AbstractAclProvider#getProcessDomainObjectClass
  • ~.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer$AuthorizedUrl#getMatchers
  • ~.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer$AuthorizedUrl#getMatchers
  • ~.config.annotation.web.configurers.UrlAuthorizationConfigurer$AuthorizedUrl#getMatchers
  • ~.config.web.server.ServerHttpSecurity$OAuth2ResourceServerSpec$JwtSpec#getJwtAuthenticationConverter
  • ~.ldap.authentication.AbstractLdapAuthenticationProvider#loadUserAuthorities
  • ~.ldap.authentication.LdapAuthenticationProvider#loadUserAuthorities
  • ~.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider#loadUserAuthorities
  • ~.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter#getAuthenticationDetailsSource
  • ~.web.authentication.rememberme.AbstractRememberMeServices#getAuthenticationDetailsSource

DEFAULT

  • ~.access.vote.RoleHierarchyVoter#extractAuthorities
  • ~.access.vote.RoleVoter#extractAuthorities
  • ~.authentication.AuthenticationTrustResolverImpl#getAnonymousClass
  • ~.authentication.AuthenticationTrustResolverImpl#getRememberMeClass
  • ~.config.annotation.ObjectPostProcessorTests$PerformConversion#perform
  • ~.config.annotation.web.configurers.AbstractInterceptUrlConfigurer#getDecisionVoters
  • ~.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer#getDecisionVoters
  • ~.config.annotation.web.configurers.NamespaceHttpBasicTests$AuthenticationDetailsSourceHttpBasicConfig#authenticationDetailsSource
  • ~.config.annotation.web.configurers.NamespaceHttpBasicTests$AuthenticationDetailsSourceHttpBasicLambdaConfig#authenticationDetailsSource
  • ~.config.annotation.web.configurers.UrlAuthorizationConfigurer#getDecisionVoters
  • ~.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer$JwtConfigurer#getJwtAuthenticationConverter
  • ~.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurerTests$CustomAuthenticationDetailsSource#authenticationDetailsSource
  • ~.config.annotation.web.socket.WebSocketMessageBrokerSecurityConfigurationDocTests$WebSocketSecurityConfig#authorizationManager
  • ~.config.annotation.web.socket.WebSocketMessageBrokerSecurityConfigurationTests$DefaultPatternMatcherConfig#authorizationManager
  • ~.config.annotation.web.socket.WebSocketMessageBrokerSecurityConfigurationTests$MsmsRegistryCustomPatternMatcherConfig#authorizationManager
  • ~.config.annotation.web.socket.WebSocketMessageBrokerSecurityConfigurationTests$OverrideMsmsRegistryCustomPatternMatcherConfig#authorizationManager
  • ~.config.annotation.web.socket.WebSocketMessageBrokerSecurityConfigurationTests$SockJsProxylessSecurityConfig#authorizationManager
  • ~.config.annotation.web.socket.WebSocketMessageBrokerSecurityConfigurationTests$SockJsSecurityConfig#authorizationManager
  • ~.config.annotation.web.socket.WebSocketMessageBrokerSecurityConfigurationTests$WebSocketSecurityConfig#authorizationManager
  • ~.messaging.access.intercept.MessageMatcherDelegatingAuthorizationManager$Entry#getMessageMatcher

PRIVATE

  • ~.aot.hint.CoreSecurityRuntimeHintsTests#getAuthenticationEvents
  • ~.aot.hint.CoreSecurityRuntimeHintsTests#getAuthenticationExceptions
  • ~.authentication.DefaultAuthenticationEventPublisher#getEventConstructor
  • ~.authorization.AuthorityAuthorizationManager#getGrantedAuthorities
  • ~.authorization.method.AuthorizationManagerAfterReactiveMethodInterceptor#postAuthorize
  • ~.authorization.method.PostFilterAuthorizationReactiveMethodInterceptor#filterMultiValue
  • ~.authorization.method.PostFilterAuthorizationReactiveMethodInterceptor#filterSingleValue
  • ~.authorization.method.PostFilterAuthorizationReactiveMethodInterceptor#postFilter
  • ~.authorization.method.PreFilterAuthorizationReactiveMethodInterceptor#filterMultiValue
  • ~.authorization.method.PreFilterAuthorizationReactiveMethodInterceptor#filterSingleValue
  • ~.config.annotation.web.builders.HttpSecurityAddFilterTest#assertThatFilters
  • ~.config.annotation.web.configuration.HttpSecurityConfiguration#createSharedObjects
  • ~.config.annotation.web.configuration.WebSecurityConfigurerAdapter#createSharedObjects
  • ~.config.annotation.web.configurers.NamespaceDebugTests#filterChainClass
  • ~.config.annotation.web.configurers.NamespaceHttpCustomFilterTests#assertThatFilters
  • ~.config.http.UserDetailsServiceFactoryBean#getBeansOfType
  • ~.config.ldap.ContextSourceSettingPostProcessor#getContextSourceClass
  • ~.config.websocket.WebSocketMessageBrokerConfigTests#message
  • ~.config.websocket.WebSocketMessageBrokerSecurityBeanDefinitionParser$MessageMatcherDelegatingAuthorizationManagerFactory#createMessageMatcherDelegatingAuthorizationManager
  • ~.htmlunit.server.HtmlUnitWebTestClient#content
  • ~.jackson2.SecurityJackson2Modules#createAllowlistedDefaultTyping
  • ~.messaging.access.intercept.MessageMatcherDelegatingAuthorizationManager#authorizationContext
  • ~.oauth2.client.oidc.authentication.OidcIdTokenDecoderFactory#getConverter
  • ~.oauth2.client.oidc.authentication.ReactiveOidcIdTokenDecoderFactory#getConverter
  • ~.oauth2.client.oidc.userinfo.OidcReactiveOAuth2UserService#getConverter
  • ~.oauth2.client.oidc.userinfo.OidcUserService#getConverter
  • ~.oauth2.client.userinfo.DefaultReactiveOAuth2UserService#getRequestHeaderSpec
  • ~.oauth2.core.converter.ClaimTypeConverterTests#getConverter
  • ~.oauth2.core.oidc.user.TestOidcUsers#authorities
  • ~.oauth2.jwt.MappedJwtClaimSetConverter#getConverter
  • ~.oauth2.server.resource.authentication.JwtAuthenticationProviderTests#errorCode
  • ~.oauth2.server.resource.introspection.NimbusOpaqueTokenIntrospector#defaultRequestEntityConverter
  • ~.oauth2.server.resource.introspection.SpringOpaqueTokenIntrospector#defaultRequestEntityConverter
  • ~.saml2.provider.service.authentication.OpenSamlAuthenticationProvider#getAssertionAuthorities
  • ~.test.context.support.WithSecurityContextTestExecutionListener#createFactory
  • ~.web.authentication.preauth.websphere.DefaultWASUsernameAndGroupsExtractor#getClass
  • ~.web.authentication.preauth.websphere.DefaultWASUsernameAndGroupsExtractor#getWSCredentialClass
  • ~.web.authentication.preauth.websphere.WebSpherePreAuthenticatedWebAuthenticationDetailsSource#getWebSphereGroupsBasedGrantedAuthorities

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the LdapAuthoritiesPopulator and related authority interfaces named in the issue, then use the public, protected, and default method checklists to map the remaining bounded wildcard return types. Review the listed declarations and project tests or build checks; the work is done when the applicable signatures no longer use bounded wildcard returns and the project still passes its checks.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
security
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.