Class SecurityConfig
applicationContext-security.xml.
This class is the Phase-3 XML→Java config migration for everything in that XML file except the parts that already moved:
<s:global-method-security>→MethodSecurityConfig- ACL stack (JdbcMutableAclService, AclCache, AclAuthorizationStrategy, etc.) →
GemmaAclConfiguration - Hibernate PostInsert/PostDelete ACL listener →
AclEventListenerConfig
What this class still defines:
- Re-imports the gsec context (gsec's
applicationContext-gsec.xmldefinedanonymousAuthenticationProvider,permissionEvaluator,roleHierarchy, the 14 other after-invocation providers, etc.). Done viaImportResourcesince the gsec artifact still ships its bean definitions as XML. passwordEncoder(Gemma-specific legacy-aware encoder).daoAuthenticationProvider(Gemma'sLegacyAwareDaoAuthenticationProviderbinding the username to the encoder's ThreadLocal for SHA-1 legacy hashes).runAsManager+runAsAuthenticationProvider(both keyed by${gemma.runas.password}).authenticationManager(Spring Security 6ProviderManagerwiring up the three providers in the legacy XML's order).sessionRegistry(used by the web-side concurrency-control filter).authenticationLoggerListener(Spring's stockLoggerListener).- Four Gemma-specific after-invocation provider beans (composite-sequence,
data-vector, differential-expression-result collection filters) defined here so
they can be looked up by name from
MethodSecurityConfig.AFTER_INVOCATION_PROVIDER_BEAN_NAMES. Only three of the four are currently wired; the fourth (and a fifth — composite sequence single) are present-but-unwired pending future hook-up. - AspectJ autoproxy now consolidated on
ComponentScanConfigvia@EnableAspectJAutoProxy(replaces the legacy<aop:aspectj-autoproxy/>declarations from this XML plusapplicationContext-hibernate.xmlandapplicationContext-serviceBeans.xml).
Spring Security 6 idioms. This is the modern stack: an explicit
ProviderManager bean rather than the deprecated XML
<s:authentication-manager> namespace, no
WebSecurityConfigurerAdapter, no SecurityFilterChain (URL-filter chains
for Gemma live in gemma-web/src/main/resources/ubic/gemma/applicationContext-security.xml
and are out of scope for this migration).
Bean naming. @Bean(name = "...") is used everywhere a downstream
consumer references the bean id literally (e.g. the four after-invocation provider beans
looked up by name from MethodSecurityConfig; the passwordEncoder that
gsec's userManager consumes by id; the runAsManager that
MethodSecurityConfig.runAsManager() pulls via @Qualifier("runAsManager")).
For beans referenced only by type the default method-name id is used.
userDetailsManager / groupManager aliases. gsec expects two
UserDetailsService-shaped beans by those names. Both are aliases for Gemma's
userManager (UserManagerImpl). The XML used <alias>; Java config
does this with secondary @Bean methods that return the same instance under the
required name, achieved by injecting the existing bean and re-exposing it.
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionafterAclCompositeSequenceCollectionRead(org.springframework.security.acls.model.AclService aclService, org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy, org.springframework.security.acls.model.SidRetrievalStrategy sidRetrievalStrategy) afterAclCompositeSequenceRead(org.springframework.security.acls.model.AclService aclService, org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy, org.springframework.security.acls.model.SidRetrievalStrategy sidRetrievalStrategy) afterAclDataVectorCollectionRead(org.springframework.security.acls.model.AclService aclService, org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy, org.springframework.security.acls.model.SidRetrievalStrategy sidRetrievalStrategy) afterAclDifferentialExpressionAnalysisResultCollectionRead(org.springframework.security.acls.model.AclService aclService, org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy, org.springframework.security.acls.model.SidRetrievalStrategy sidRetrievalStrategy) org.springframework.security.authentication.event.LoggerListenerStock Spring SecurityLoggerListenerthat logs authentication events at INFO.org.springframework.security.authentication.AuthenticationManagerauthenticationManager(org.springframework.security.authentication.AuthenticationProvider daoAuthenticationProvider, org.springframework.security.authentication.AuthenticationProvider runAsAuthenticationProvider, org.springframework.security.authentication.AuthenticationProvider anonymousAuthenticationProvider) The GemmaAuthenticationManager.daoAuthenticationProvider(org.springframework.security.core.userdetails.UserDetailsService userManager, org.springframework.security.crypto.password.PasswordEncoder passwordEncoder, String legacySalt) CustomDaoAuthenticationProviderthat binds the username to the password encoder's ThreadLocal soGemmaLegacyAwarePasswordEncodercan recompute the legacy SHA-1(rawPassword + "{" + username + "}") hash.gemmaAfterAclMyDataRead(org.springframework.security.acls.model.AclService aclService, org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy, org.springframework.security.acls.model.SidRetrievalStrategy sidRetrievalStrategy) Gemma-owned replacement for gsec'safterAclMyDataRead.gemmaAfterAclMyPrivateDataRead(org.springframework.security.acls.model.AclService aclService, org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy, org.springframework.security.acls.model.SidRetrievalStrategy sidRetrievalStrategy) Gemma-owned replacement for gsec'safterAclMyPrivateDataRead.gemmaAfterAclReadQuiet(org.springframework.security.acls.model.AclService aclService, org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy, org.springframework.security.acls.model.SidRetrievalStrategy sidRetrievalStrategy) Gemma-owned replacement for gsec'safterAclReadQuiet.gemmaAfterAclStreamRead(AclService aclService, org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy, org.springframework.security.acls.model.SidRetrievalStrategy sidRetrievalStrategy) Gemma-owned replacement for gsec'safterAclStreamRead.gemmaAfterAclValueObjectCollectionRead(org.springframework.security.acls.model.AclService aclService, org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy, org.springframework.security.acls.model.SidRetrievalStrategy sidRetrievalStrategy) Gemma-owned replacement for gsec'safterAclValueObjectCollection.gemmaAfterAclValueObjectMapRead(org.springframework.security.acls.model.AclService aclService, org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy, org.springframework.security.acls.model.SidRetrievalStrategy sidRetrievalStrategy) Gemma-owned replacement for gsec'safterAclValueObjectMap.gemmaAfterAclValueObjectRead(org.springframework.security.acls.model.AclService aclService, org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy, org.springframework.security.acls.model.SidRetrievalStrategy sidRetrievalStrategy) Gemma-owned replacement for gsec'safterAclValueObject.org.springframework.security.crypto.password.PasswordEncoderGemma-specific legacy-aware password encoder.org.springframework.security.access.intercept.RunAsImplAuthenticationProviderrunAsAuthenticationProvider(String runAsPassword) Provider that validates the temporaryRunAsUserTokenproduced byrunAsManager(String).org.springframework.security.access.intercept.RunAsManagerrunAsManager(String runAsPassword) RunAsManagerImplkeyed by${gemma.runas.password}with role prefixGROUP_.org.springframework.security.core.session.SessionRegistrySession registry consumed by the<s:concurrency-control>element ingemma-web'sapplicationContext-security.xml.static org.springframework.beans.factory.config.BeanFactoryPostProcessorRegister theuserDetailsManagerandgroupManageraliases for theuserManagerbean (UserManagerImpl).
-
Constructor Details
-
SecurityConfig
public SecurityConfig()
-
-
Method Details
-
userManagerAliases
@Bean public static org.springframework.beans.factory.config.BeanFactoryPostProcessor userManagerAliases()Register theuserDetailsManagerandgroupManageraliases for theuserManagerbean (UserManagerImpl). gsec'sapplicationContext-gsec.xmlconsumes both names by reference (see thesecurityServiceconstructor); the legacy XML used<alias>elements to satisfy that contract.Java config has no native alias declaration, so we register the aliases via a
BeanFactoryPostProcessorthat runs before any bean is instantiated. Both aliases must be wired at registry level (not via additional@Beanmethods) so the underlying singleton is the actualuserManagerinstance — gsec's code that pullsuserDetailsManageranduserServicegets the same object back, preserving the legacy semantics.Declared
staticso Spring instantiates it early (before any@Configurationclass processing) without leaking a partialSecurityConfiginstance. -
passwordEncoder
@Bean(name="passwordEncoder") public org.springframework.security.crypto.password.PasswordEncoder passwordEncoder()Gemma-specific legacy-aware password encoder. Recognizes both the legacy SHA-1(rawPassword + "{" + username + "}") format (bare 40-hex digest, no prefix -- see sql/init-data.sql) AND new BCrypt hashes ({bcrypt} prefix per DelegatingPasswordEncoder convention). New encodings produce BCrypt; legacy hashes are flagged for upgrade-on-next-login viaPasswordEncoder.upgradeEncoding(String).Declared with the explicit id
passwordEncoderso it is injected by id intodaoAuthenticationProviderbelow AND intoubic.gemma.core.security.authentication.UserManagerImpl(which still uses field injection by type but which gsec's XML may shadow with a fallback bean of the same id). -
daoAuthenticationProvider
@Bean(name="daoAuthenticationProvider") public LegacyAwareDaoAuthenticationProvider daoAuthenticationProvider(@Qualifier("userManager") org.springframework.security.core.userdetails.UserDetailsService userManager, @Qualifier("passwordEncoder") org.springframework.security.crypto.password.PasswordEncoder passwordEncoder, @Value("${gemma.legacy.salt:gooblyfoobly}") String legacySalt) CustomDaoAuthenticationProviderthat binds the username to the password encoder's ThreadLocal soGemmaLegacyAwarePasswordEncodercan recompute the legacy SHA-1(rawPassword + "{" + username + "}") hash.The XML configured this as a plain bean rather than via the
<s:authentication-provider user-service-ref="...">namespace shortcut, because that shortcut only builds a vanillaDaoAuthenticationProvider. The Java equivalent is the same: build the provider, set itsUserDetailsServiceandPasswordEncoderexplicitly. -
runAsManager
@Bean(name="runAsManager") public org.springframework.security.access.intercept.RunAsManager runAsManager(@Value("${gemma.runas.password}") String runAsPassword) RunAsManagerImplkeyed by${gemma.runas.password}with role prefixGROUP_. This is the manager consulted by the method-security interceptor when@Secured("RUN_AS_ADMIN")is encountered, producing a temporary authentication with theGROUP_RUN_AS_ADMINauthority. -
runAsAuthenticationProvider
@Bean(name="runAsAuthenticationProvider") public org.springframework.security.access.intercept.RunAsImplAuthenticationProvider runAsAuthenticationProvider(@Value("${gemma.runas.password}") String runAsPassword) Provider that validates the temporaryRunAsUserTokenproduced byrunAsManager(String). The key MUST match the run-as manager's key, elseAuthorizationServiceExceptionis thrown at theauthenticatecall. -
authenticationManager
@Bean(name="authenticationManager") public org.springframework.security.authentication.AuthenticationManager authenticationManager(@Qualifier("daoAuthenticationProvider") org.springframework.security.authentication.AuthenticationProvider daoAuthenticationProvider, @Qualifier("runAsAuthenticationProvider") org.springframework.security.authentication.AuthenticationProvider runAsAuthenticationProvider, @Qualifier("anonymousAuthenticationProvider") org.springframework.security.authentication.AuthenticationProvider anonymousAuthenticationProvider) The GemmaAuthenticationManager.Spring Security 6 retires the deprecated XML
<s:authentication-manager>namespace in favour of an explicitProviderManagerbean. Order of providers preserved from the XML (daoAuthenticationProvider first, then runAsAuthenticationProvider, then anonymousAuthenticationProvider). The first provider thatsupportsthe incoming token wins; ordering matters for the case where multiple providers claim a token type.The XML used
alias="authenticationManager"which produced a bean registered under both the namespace's internal id ANDauthenticationManager; the explicit@Bean(name = "authenticationManager")produces the same effective registration.anonymousAuthenticationProvidercomes from gsec'sapplicationContext-gsec.xml(re-imported here viaImportResource). -
sessionRegistry
@Bean(name="sessionRegistry") public org.springframework.security.core.session.SessionRegistry sessionRegistry()Session registry consumed by the<s:concurrency-control>element ingemma-web'sapplicationContext-security.xml. Single-session enforcement is wired on the web side; this bean is the shared store.Works in conjunction with the
HttpSessionEventPublisherconfigured inweb.xml. -
authenticationLoggerListener
@Bean(name="authenticationLoggerListener") public org.springframework.security.authentication.event.LoggerListener authenticationLoggerListener()Stock Spring SecurityLoggerListenerthat logs authentication events at INFO. -
afterAclCompositeSequenceCollectionRead
@Bean(name="afterAclCompositeSequenceCollectionRead") public AclEntryAfterInvocationCompositeSequenceCollectionByArrayDesignFilteringProvider afterAclCompositeSequenceCollectionRead(@Qualifier("aclService") org.springframework.security.acls.model.AclService aclService, org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy, org.springframework.security.acls.model.SidRetrievalStrategy sidRetrievalStrategy) -
afterAclCompositeSequenceRead
@Bean(name="afterAclCompositeSequenceRead") public AclEntryAfterInvocationCompositeSequenceByArrayDesignFilteringProvider afterAclCompositeSequenceRead(@Qualifier("aclService") org.springframework.security.acls.model.AclService aclService, org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy, org.springframework.security.acls.model.SidRetrievalStrategy sidRetrievalStrategy) -
afterAclDataVectorCollectionRead
@Bean(name="afterAclDataVectorCollectionRead") public AclEntryAfterInvocationDataVectorCollectionByExpressionExperimentFilteringProvider afterAclDataVectorCollectionRead(@Qualifier("aclService") org.springframework.security.acls.model.AclService aclService, org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy, org.springframework.security.acls.model.SidRetrievalStrategy sidRetrievalStrategy) -
afterAclDifferentialExpressionAnalysisResultCollectionRead
@Bean(name="afterAclDifferentialExpressionAnalysisResultCollectionRead") public AclEntryAfterInvocationDifferentialExpressionAnalysisResultCollectionByResultSetFilteringProvider afterAclDifferentialExpressionAnalysisResultCollectionRead(@Qualifier("aclService") org.springframework.security.acls.model.AclService aclService, org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy, org.springframework.security.acls.model.SidRetrievalStrategy sidRetrievalStrategy) -
gemmaAfterAclReadQuiet
@Bean(name="gemmaAfterAclReadQuiet") public AclEntryAfterInvocationQuietReadProvider gemmaAfterAclReadQuiet(@Qualifier("aclService") org.springframework.security.acls.model.AclService aclService, org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy, org.springframework.security.acls.model.SidRetrievalStrategy sidRetrievalStrategy) Gemma-owned replacement for gsec'safterAclReadQuiet. Same semantics (READ-or-ADMIN check, null on denial) but lives in gemma-core. Used by 17@Secured({..., "AFTER_ACL_READ_QUIET"})call sites. Cannot be expressed as@PostAuthorize: that annotation has no "return null on denial" mode. -
gemmaAfterAclValueObjectRead
@Bean(name="gemmaAfterAclValueObjectRead") public AclEntryAfterInvocationValueObjectReadProvider gemmaAfterAclValueObjectRead(@Qualifier("aclService") org.springframework.security.acls.model.AclService aclService, org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy, org.springframework.security.acls.model.SidRetrievalStrategy sidRetrievalStrategy) Gemma-owned replacement for gsec'safterAclValueObject. Single-object ACL READ check that also populates the SecureValueObject security-metadata fields (isPublic / isShared / userOwned / userCanWrite) as a side-effect of the ACL fetch. Cannot be expressed as@PostAuthorize: the side-effect on the returned VO is load-bearing (drives lock / share / edit UI affordances in the web layer). -
gemmaAfterAclValueObjectCollectionRead
@Bean(name="gemmaAfterAclValueObjectCollectionRead") public AclEntryAfterInvocationValueObjectCollectionReadProvider gemmaAfterAclValueObjectCollectionRead(@Qualifier("aclService") org.springframework.security.acls.model.AclService aclService, org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy, org.springframework.security.acls.model.SidRetrievalStrategy sidRetrievalStrategy) Gemma-owned replacement for gsec'safterAclValueObjectCollection. Bulk ACL READ filter over a collection of SecureValueObjects, populating per-row security-metadata fields on every retained VO. Cannot be expressed as@PostFilter: the per-row side-effect is load-bearing. -
gemmaAfterAclValueObjectMapRead
@Bean(name="gemmaAfterAclValueObjectMapRead") public AclEntryAfterInvocationValueObjectMapReadProvider gemmaAfterAclValueObjectMapRead(@Qualifier("aclService") org.springframework.security.acls.model.AclService aclService, org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy, org.springframework.security.acls.model.SidRetrievalStrategy sidRetrievalStrategy) Gemma-owned replacement for gsec'safterAclValueObjectMap. Bulk ACL READ filter over a Map whose keys are SecureValueObjects, populating per-key security-metadata fields on every retained key VO. Map values are NOT checked. -
gemmaAfterAclMyDataRead
@Bean(name="gemmaAfterAclMyDataRead") public AclEntryAfterInvocationOwnedCollectionFilteringProvider gemmaAfterAclMyDataRead(@Qualifier("aclService") org.springframework.security.acls.model.AclService aclService, org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy, org.springframework.security.acls.model.SidRetrievalStrategy sidRetrievalStrategy) Gemma-owned replacement for gsec'safterAclMyDataRead. Owner-and-permission filter (ADMIN-or-WRITE) over Securable collections. -
gemmaAfterAclMyPrivateDataRead
@Bean(name="gemmaAfterAclMyPrivateDataRead") public AclEntryAfterInvocationPrivateCollectionFilteringProvider gemmaAfterAclMyPrivateDataRead(@Qualifier("aclService") org.springframework.security.acls.model.AclService aclService, org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy, org.springframework.security.acls.model.SidRetrievalStrategy sidRetrievalStrategy) Gemma-owned replacement for gsec'safterAclMyPrivateDataRead. Private-and-readable filter (ADMIN-or-WRITE-or-READ) over Securable collections. -
gemmaAfterAclStreamRead
@Bean(name="gemmaAfterAclStreamRead") public AclEntryAfterInvocationStreamFilteringProvider gemmaAfterAclStreamRead(@Qualifier("aclService") AclService aclService, org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy, org.springframework.security.acls.model.SidRetrievalStrategy sidRetrievalStrategy) Gemma-owned replacement for gsec'safterAclStreamRead. Lazy READ-or-ADMIN filter forStream<? extends Securable>return types.
-