Skip to content

Commit

Permalink
Merge pull request #23234 from Zech-Hein/fix-javaee-security-alternative
Browse files Browse the repository at this point in the history
fix javaEE Security authMech alternative-annotation logic
  • Loading branch information
Zech-Hein authored Nov 5, 2022
2 parents 65c4739 + 8e0025a commit dde5082
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,35 @@ public void addAuthMech(String applicationName, Class<?> annotatedClass, Class<?
}
}

public Properties removeAuthMech(String applicationName, Class<?> implClass) {
return removeAuthMech(applicationName, implClass, implClass);
}

public Properties removeAuthMech(String applicationName, Class<?> annotatedClass, Class<?> implClass) {
Map<String, ModuleProperties> moduleMap = moduleMapsPerApplication.get(applicationName);
String moduleName = getModuleFromClass(annotatedClass, moduleMap);

if (tc.isDebugEnabled()) {
Tr.debug(tc, "moduleName: " + moduleName);
}

if (moduleMap.containsKey(moduleName)) {
return moduleMap.get(moduleName).removeFromAuthMechMap(implClass);
} else {
// if there is no match in the module name, it should be a shared jar file.
// so the authmech needs to be removed from all modules.
if (tc.isDebugEnabled()) {
Tr.debug(tc, "Remove the AuthMech from all modules since the module is not found. Module: " + moduleName);
}

Properties props = null;
for (Map.Entry<String, ModuleProperties> entry : moduleMap.entrySet()) {
props = entry.getValue().removeFromAuthMechMap(implClass);
}
return props;
}
}

/**
* Identify the module name from the class. If the class exists in the jar file, return war file name
* if it is located under the war file, otherwise returning jar file name.
Expand Down Expand Up @@ -165,19 +194,31 @@ protected String getClassFileLocation(Class<?> annotatedClass) {
}

public boolean existAuthMech(String applicationName, Class<?> authMechToExist) {
return (null != getExistingAuthMechClass(applicationName, authMechToExist));
}

public Class<?> getExistingAuthMechClass(String applicationName) {
return getExistingAuthMechClass(applicationName, null);
}

public Class<?> getExistingAuthMechClass(String applicationName, Class<?> authMechToExist) {
Map<Class<?>, Properties> authMechs = null;
Map<String, ModuleProperties> moduleMap = moduleMapsPerApplication.get(applicationName);
if (moduleMap != null) {
for (Map.Entry<String, ModuleProperties> entry : moduleMap.entrySet()) {
authMechs = entry.getValue().getAuthMechMap();
for (Class<?> authMech : authMechs.keySet()) {
if (authMech.equals(authMechToExist)) {
return true;
if (authMechToExist != null) {
if (authMech.equals(authMechToExist)) {
return authMech;
}
} else {
return authMech;
}
}
}
}
return false;
return null;
}

public Map<Class<?>, Properties> getAuthMechs(String applicationName, String moduleName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.Set;

import javax.enterprise.event.Observes;
import javax.enterprise.inject.Alternative;
import javax.enterprise.inject.spi.AfterBeanDiscovery;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
Expand Down Expand Up @@ -90,6 +91,7 @@ public class JavaEESecCDIExtension<T> implements Extension, WebSphereCDIExtensio
private final Set<Bean> beansToAdd = new HashSet<Bean>();
private boolean identityStoreHandlerRegistered = false;
private boolean identityStoreRegistered = false;
private boolean isAlternativeHAMAdded = false;
private final String applicationName;
private final List<LdapIdentityStoreDefinition> ldapDefinitionList = new ArrayList<LdapIdentityStoreDefinition>();
private final List<DatabaseIdentityStoreDefinition> databaseDefinitionList = new ArrayList<DatabaseIdentityStoreDefinition>();
Expand Down Expand Up @@ -155,7 +157,8 @@ public <T> void processAnnotatedType(ProcessAnnotatedType<T> processAnnotatedTyp
createModulePropertiesProviderBeanForGlobalLogin(beanManager, javaClass);
} else {
Annotation ltc = annotatedType.getAnnotation(LoginToContinue.class);
createModulePropertiesProviderBeanForApplicationAuthMechToAdd(beanManager, ltc, javaClass);
Annotation alternative = annotatedType.getAnnotation(Alternative.class);
createModulePropertiesProviderBeanForApplicationAuthMechToAdd(beanManager, ltc, alternative, javaClass);
}
}
//look at the class level annotations
Expand Down Expand Up @@ -322,7 +325,7 @@ private void createModulePropertiesProviderBeanForBasicToAdd(BeanManager beanMan
* @param implClass the implementation class
*/
@SuppressWarnings("rawtypes")
private void createModulePropertiesProviderBeanForApplicationAuthMechToAdd(BeanManager beanManager, Annotation ltc, Class implClass) {
private void createModulePropertiesProviderBeanForApplicationAuthMechToAdd(BeanManager beanManager, Annotation ltc, Annotation alternative, Class implClass) {
Properties props = null;
if (ltc != null) {
try {
Expand All @@ -333,7 +336,22 @@ private void createModulePropertiesProviderBeanForApplicationAuthMechToAdd(BeanM
e.printStackTrace();
}
}
addAuthMech(applicationName, implClass, implClass, props);
boolean isAlternative = (alternative != null);
if (isAlternative) {
// Use the alternative instead of the existing authMech
Class<?> existingAuthMechClass = httpAuthenticationMechanismsTracker.getExistingAuthMechClass(applicationName);
boolean authMechAlreadyExists = (existingAuthMechClass != null);
if (authMechAlreadyExists) {
httpAuthenticationMechanismsTracker.removeAuthMech(applicationName, existingAuthMechClass);
}
addAuthMech(applicationName, implClass, props);
isAlternativeHAMAdded = true;
if (tc.isDebugEnabled()) {
Tr.debug(tc, "adding alternative HAM: " + implClass);
}
} else if (!isAlternativeHAMAdded) {
addAuthMech(applicationName, implClass, props);
}
}

/**
Expand Down Expand Up @@ -365,6 +383,10 @@ public void addAuthMech(String applicationName, Class<?> annotatedClass, Class<?
httpAuthenticationMechanismsTracker.addAuthMech(applicationName, annotatedClass, implClass, props);
}

public void addAuthMech(String applicationName, Class<?> implClass, Properties props) {
httpAuthenticationMechanismsTracker.addAuthMech(applicationName, implClass, implClass, props);
}

/**
* @param ltcAnnotation
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.util.Set;

import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.Alternative;
import javax.enterprise.inject.spi.AfterBeanDiscovery;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
Expand Down Expand Up @@ -322,6 +323,8 @@ public void processAnnotatedTypeApplicationHAM() {
will(returnValue(at1));
one(at1).getAnnotation(LoginToContinue.class);
will(returnValue(ltc));
one(at1).getAnnotation(Alternative.class);
will(returnValue(null));
one(wasc).getOverrideHttpAuthMethod();
will(returnValue(null));
one(at1).getAnnotations();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017 IBM Corporation and others.
* Copyright (c) 2017, 2022 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
Expand All @@ -15,9 +15,6 @@
import java.util.Map;
import java.util.Properties;

import com.ibm.websphere.ras.Tr;
import com.ibm.websphere.ras.TraceComponent;

public class ModuleProperties {
private Map<Class<?>, Properties> authMechMap;
private URL location;
Expand Down Expand Up @@ -45,6 +42,7 @@ public ModuleProperties() {
public Map<Class<?>, Properties> getAuthMechMap() {
return authMechMap;
}

public Properties getFromAuthMechMap(Class<?> className) {
return authMechMap.get(className);
}
Expand All @@ -56,4 +54,8 @@ public URL getLocation() {
public Properties putToAuthMechMap(Class<?> className, Properties props) {
return authMechMap.put(className, props);
}

public Properties removeFromAuthMechMap(Class<?> className) {
return authMechMap.remove(className);
}
}

0 comments on commit dde5082

Please sign in to comment.