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

Merge 3.0.0 prepare to master #323

Merged
merged 22 commits into from
Jun 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
834e521
Update dependencies to EE 10 and adjust code where needed for that.
arjantijms Mar 3, 2022
41a1929
Fixed several warnings
arjantijms Mar 3, 2022
2938856
Update Arquillian plug-in for GF
arjantijms Mar 5, 2022
730aa0d
Add content to beans.xml as required now by CDI 4
arjantijms Mar 6, 2022
d43a497
Fix OpenID tests
arjantijms Mar 7, 2022
9d083cc
Integrate OpenId with existing CDI extension.
arjantijms Mar 7, 2022
70fb085
Refactoring
arjantijms Mar 7, 2022
2648c39
Moven OpenId to the mechanisms package
arjantijms Mar 7, 2022
6eabe6b
Take advantage of new Jakarta Authentication 3 APIs
arjantijms Mar 7, 2022
b8e1ceb
Separate profiles for GlassFish with updated and not updated jars.
arjantijms Mar 7, 2022
125bd91
Update authentication API to 3.0.0
arjantijms Mar 7, 2022
5a00589
Integrate Jakarta Security 3.0.0-RC2
arjantijms Mar 8, 2022
ab015c0
Added some extra features to test base class
arjantijms Mar 17, 2022
ec23eae
Update Jakarta Authorization API and Nimbus
arjantijms Mar 17, 2022
c770c05
Add test for OpenID using certified OpenID Provider Mitre
arjantijms Mar 17, 2022
c345624
Update to RC3 API
arjantijms Mar 17, 2022
01984bf
Adjust for latest snapshot API
arjantijms Mar 20, 2022
1441212
Move HttpStorageController to servlet package
arjantijms Mar 21, 2022
85a1c87
Set http timeout to infinite for tests when debug param used
arjantijms Mar 21, 2022
592d27c
Add default method to storage controller for no-timeout
arjantijms Mar 21, 2022
a096dcf
Implement redirect to original resource functionality
arjantijms Mar 23, 2022
8a8a42f
Update version in pom and some small refactoring
arjantijms Mar 29, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions impl/pom.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

Copyright (c) 2022, 2022 Contributors to the Eclipse Foundation.
Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.

This program and the accompanying materials are made available under the
Expand Down Expand Up @@ -37,7 +38,7 @@
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>5.1.1</version>
<version>5.1.4</version>
<extensions>true</extensions>
<configuration>
<instructions>
Expand Down Expand Up @@ -82,7 +83,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<version>3.2.2</version>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@
import jakarta.security.enterprise.CallerPrincipal;

public class WrappingCallerPrincipal extends CallerPrincipal {

private static final long serialVersionUID = 1L;

private final Principal wrapped;

public WrappingCallerPrincipal(Principal wrapped) {
super(wrapped.getName());
this.wrapped = wrapped;
}

public Principal getWrapped() {
return wrapped;
}
Expand Down
142 changes: 116 additions & 26 deletions impl/src/main/java/org/glassfish/soteria/cdi/CdiExtension.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import static org.glassfish.soteria.cdi.CdiUtils.addAnnotatedTypes;
import static org.glassfish.soteria.cdi.CdiUtils.getAnnotation;
import static org.glassfish.soteria.cdi.CdiUtils.getBeanReference;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
Expand All @@ -28,13 +29,39 @@
import java.util.logging.Level;
import java.util.logging.Logger;

import org.glassfish.soteria.SecurityContextImpl;
import org.glassfish.soteria.SoteriaServiceProviders;
import org.glassfish.soteria.cdi.spi.BeanDecorator;
import org.glassfish.soteria.cdi.spi.WebXmlLoginConfig;
import org.glassfish.soteria.identitystores.DatabaseIdentityStore;
import org.glassfish.soteria.identitystores.EmbeddedIdentityStore;
import org.glassfish.soteria.identitystores.LdapIdentityStore;
import org.glassfish.soteria.identitystores.annotation.EmbeddedIdentityStoreDefinition;
import org.glassfish.soteria.identitystores.hash.Pbkdf2PasswordHashImpl;
import org.glassfish.soteria.mechanisms.BasicAuthenticationMechanism;
import org.glassfish.soteria.mechanisms.CustomFormAuthenticationMechanism;
import org.glassfish.soteria.mechanisms.FormAuthenticationMechanism;
import org.glassfish.soteria.mechanisms.OpenIdAuthenticationMechanism;
import org.glassfish.soteria.mechanisms.openid.OpenIdIdentityStore;
import org.glassfish.soteria.mechanisms.openid.controller.AuthenticationController;
import org.glassfish.soteria.mechanisms.openid.controller.ConfigurationController;
import org.glassfish.soteria.mechanisms.openid.controller.JWTValidator;
import org.glassfish.soteria.mechanisms.openid.controller.NonceController;
import org.glassfish.soteria.mechanisms.openid.controller.ProviderMetadataController;
import org.glassfish.soteria.mechanisms.openid.controller.StateController;
import org.glassfish.soteria.mechanisms.openid.controller.TokenController;
import org.glassfish.soteria.mechanisms.openid.controller.UserInfoController;
import org.glassfish.soteria.mechanisms.openid.domain.OpenIdContextImpl;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.Dependent;
import jakarta.enterprise.event.Observes;
import jakarta.enterprise.inject.spi.AfterBeanDiscovery;
import jakarta.enterprise.inject.spi.Annotated;
import jakarta.enterprise.inject.spi.Bean;
import jakarta.enterprise.inject.spi.BeanManager;
import jakarta.enterprise.inject.spi.BeforeBeanDiscovery;
import jakarta.enterprise.inject.spi.DefinitionException;
import jakarta.enterprise.inject.spi.Extension;
import jakarta.enterprise.inject.spi.ProcessBean;
import jakarta.security.enterprise.authentication.mechanism.http.AutoApplySession;
Expand All @@ -43,25 +70,13 @@
import jakarta.security.enterprise.authentication.mechanism.http.FormAuthenticationMechanismDefinition;
import jakarta.security.enterprise.authentication.mechanism.http.HttpAuthenticationMechanism;
import jakarta.security.enterprise.authentication.mechanism.http.LoginToContinue;
import jakarta.security.enterprise.authentication.mechanism.http.OpenIdAuthenticationMechanismDefinition;
import jakarta.security.enterprise.authentication.mechanism.http.RememberMe;
import jakarta.security.enterprise.identitystore.DatabaseIdentityStoreDefinition;
import jakarta.security.enterprise.identitystore.IdentityStore;
import jakarta.security.enterprise.identitystore.IdentityStoreHandler;
import jakarta.security.enterprise.identitystore.LdapIdentityStoreDefinition;

import org.glassfish.soteria.SecurityContextImpl;
import org.glassfish.soteria.SoteriaServiceProviders;
import org.glassfish.soteria.cdi.spi.BeanDecorator;
import org.glassfish.soteria.cdi.spi.WebXmlLoginConfig;
import org.glassfish.soteria.identitystores.DatabaseIdentityStore;
import org.glassfish.soteria.identitystores.EmbeddedIdentityStore;
import org.glassfish.soteria.identitystores.LdapIdentityStore;
import org.glassfish.soteria.identitystores.annotation.EmbeddedIdentityStoreDefinition;
import org.glassfish.soteria.identitystores.hash.Pbkdf2PasswordHashImpl;
import org.glassfish.soteria.mechanisms.BasicAuthenticationMechanism;
import org.glassfish.soteria.mechanisms.CustomFormAuthenticationMechanism;
import org.glassfish.soteria.mechanisms.FormAuthenticationMechanism;

public class CdiExtension implements Extension {

private static final Logger LOGGER = Logger.getLogger(CdiExtension.class.getName());
Expand All @@ -71,6 +86,8 @@ public class CdiExtension implements Extension {
// This could be extended later to support multiple
private List<Bean<IdentityStore>> identityStoreBeans = new ArrayList<>();
private Bean<HttpAuthenticationMechanism> authenticationMechanismBean;
private List<Bean<?>> extraBeans = new ArrayList<>();

private boolean httpAuthenticationMechanismFound;

public void register(@Observes BeforeBeanDiscovery beforeBean, BeanManager beanManager) {
Expand All @@ -82,15 +99,27 @@ public void register(@Observes BeforeBeanDiscovery beforeBean, BeanManager beanM
CustomFormAuthenticationMechanism.class,
SecurityContextImpl.class,
IdentityStoreHandler.class,
Pbkdf2PasswordHashImpl.class
Pbkdf2PasswordHashImpl.class,

// OpenID types
AuthenticationController.class,
ConfigurationController.class,
NonceController.class,
ProviderMetadataController.class,
StateController.class,
TokenController.class,
UserInfoController.class,
OpenIdContextImpl.class,
OpenIdIdentityStore.class,
OpenIdAuthenticationMechanism.class,
JWTValidator.class
);
}

public <T> void processBean(@Observes ProcessBean<T> eventIn, BeanManager beanManager) {

ProcessBean<T> event = eventIn; // JDK8 u60 workaround

Class<?> beanClass = event.getBean().getBeanClass();

Optional<EmbeddedIdentityStoreDefinition> optionalEmbeddedStore = getAnnotation(beanManager, event.getAnnotated(), EmbeddedIdentityStoreDefinition.class);
optionalEmbeddedStore.ifPresent(embeddedIdentityStoreDefinition -> {
logActivatedIdentityStore(EmbeddedIdentityStore.class, beanClass);
Expand Down Expand Up @@ -148,8 +177,6 @@ public <T> void processBean(@Observes ProcessBean<T> eventIn, BeanManager beanMa
basicAuthenticationMechanismDefinition)));
});



Optional<FormAuthenticationMechanismDefinition> optionalFormMechanism = getAnnotation(beanManager, event.getAnnotated(), FormAuthenticationMechanismDefinition.class);
optionalFormMechanism.ifPresent(formAuthenticationMechanismDefinition -> {
logActivatedAuthenticationMechanism(FormAuthenticationMechanismDefinition.class, beanClass);
Expand Down Expand Up @@ -183,11 +210,43 @@ public <T> void processBean(@Observes ProcessBean<T> eventIn, BeanManager beanMa

authMethod.setLoginToContinue(
LoginToContinueAnnotationLiteral.eval(customFormAuthenticationMechanismDefinition.loginToContinue()));

return authMethod;
});
});

Optional<OpenIdAuthenticationMechanismDefinition> opentionalOpenIdMechanism = getAnnotation(beanManager, event.getAnnotated(), OpenIdAuthenticationMechanismDefinition.class);
opentionalOpenIdMechanism.ifPresent(definition -> {
logActivatedAuthenticationMechanism(OpenIdAuthenticationMechanismDefinition.class, beanClass);

validateOpenIdParametersFormat(definition);

authenticationMechanismBean = new CdiProducer<HttpAuthenticationMechanism>()
.scope(ApplicationScoped.class)
.beanClass(HttpAuthenticationMechanism.class)
.types(HttpAuthenticationMechanism.class)
.addToId(OpenIdAuthenticationMechanism.class)
.create(e -> getBeanReference(OpenIdAuthenticationMechanism.class));

identityStoreBeans.add(new CdiProducer<IdentityStore>()
.scope(ApplicationScoped.class)
.beanClass(IdentityStore.class)
.types(IdentityStore.class)
.addToId(OpenIdIdentityStore.class)
.create(e -> getBeanReference(OpenIdIdentityStore.class))
);

extraBeans.add(new CdiProducer<OpenIdAuthenticationMechanismDefinition>()
.scope(ApplicationScoped.class)
.beanClass(OpenIdAuthenticationMechanismDefinition.class)
.types(OpenIdAuthenticationMechanismDefinition.class)
.addToId("OpenId Definition")
.create(e -> definition)
);
});



if (event.getBean().getTypes().contains(HttpAuthenticationMechanism.class)) {
// enabled bean implementing the HttpAuthenticationMechanism found
httpAuthenticationMechanismFound = true;
Expand All @@ -207,19 +266,19 @@ public void afterBean(final @Observes AfterBeanDiscovery afterBeanDiscovery, Bea
decorator.decorateBean(identityStoreBean, IdentityStore.class, beanManager));
}
}

if (authenticationMechanismBean == null && loginConfig.getAuthMethod() != null) {

if ("basic".equalsIgnoreCase(loginConfig.getAuthMethod())) {
authenticationMechanismBean = new CdiProducer<HttpAuthenticationMechanism>()
.scope(ApplicationScoped.class)
.beanClass(BasicAuthenticationMechanism.class)
.types(Object.class, HttpAuthenticationMechanism.class, BasicAuthenticationMechanism.class)
.addToId(BasicAuthenticationMechanismDefinition.class)
.create(e ->
.create(e ->
new BasicAuthenticationMechanism(
new BasicAuthenticationMechanismDefinitionAnnotationLiteral(loginConfig.getRealmName())));

httpAuthenticationMechanismFound = true;
} else if ("form".equalsIgnoreCase(loginConfig.getAuthMethod())) {
authenticationMechanismBean = new CdiProducer<HttpAuthenticationMechanism>()
Expand All @@ -232,8 +291,8 @@ public void afterBean(final @Observes AfterBeanDiscovery afterBeanDiscovery, Bea

authMethod.setLoginToContinue(
new LoginToContinueAnnotationLiteral(
loginConfig.getFormLoginPage(),
true, null,
loginConfig.getFormLoginPage(),
true, null,
loginConfig.getFormErrorPage())
);

Expand All @@ -247,7 +306,25 @@ public void afterBean(final @Observes AfterBeanDiscovery afterBeanDiscovery, Bea
afterBeanDiscovery.addBean(
decorator.decorateBean(authenticationMechanismBean, HttpAuthenticationMechanism.class, beanManager));
}


for (Bean<?> bean : extraBeans) {
afterBeanDiscovery.addBean(bean);
}

if (extraBeans.isEmpty()) {
// Publish empty definition to prevent injection errors. The helper components will not work, but
// will not cause definition error. This is quite unlucky situation, but when definition is on an
// alternative bean we don't know before this moment whether the bean is enabled or not.

// Probably can circumvent this using programmatic lookup or Instance injection
afterBeanDiscovery.addBean()
.scope(Dependent.class)
.beanClass(OpenIdAuthenticationMechanismDefinition.class)
.types(OpenIdAuthenticationMechanismDefinition.class)
.id("Null OpenId Definition")
.createWith(cc -> null);
}

afterBeanDiscovery.addBean(
decorator.decorateBean(
new CdiProducer<IdentityStoreHandler>()
Expand Down Expand Up @@ -291,4 +368,17 @@ private void checkForWrongUseOfInterceptors(Annotated annotated, Class<?> beanCl
}
}
}

private void validateOpenIdParametersFormat(OpenIdAuthenticationMechanismDefinition definition) {
for (String extraParameter : definition.extraParameters()) {
String[] parts = extraParameter.split("=");
if (parts.length != 2) {
throw new DefinitionException(
OpenIdAuthenticationMechanismDefinition.class.getSimpleName()
+ ".extraParameters() value '" + extraParameter
+ "' is not of the format key=value"
);
}
}
}
}
Loading