blob: 43f85be3fdbce930c52d2c64e37dadb32da7b378 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.geronimo.microprofile.impl.jwtauth.servlet;
import static java.util.Optional.ofNullable;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.Set;
import java.util.function.Supplier;
import javax.servlet.DispatcherType;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.annotation.HandlesTypes;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import org.apache.geronimo.microprofile.impl.jwtauth.config.GeronimoJwtAuthConfig;
import org.eclipse.microprofile.auth.LoginConfig;
@HandlesTypes(LoginConfig.class)
public class GeronimoJwtAuthInitializer implements ServletContainerInitializer {
@Override
public void onStartup(final Set<Class<?>> classes, final ServletContext ctx) throws ServletException {
final Supplier<GeronimoJwtAuthConfig> config = new Supplier<GeronimoJwtAuthConfig>() {
private GeronimoJwtAuthConfig config;
@Override
public GeronimoJwtAuthConfig get() {
return config == null ? config = GeronimoJwtAuthConfig.create() : config;
}
};
ofNullable(classes).filter(c -> !c.isEmpty()).ifPresent(marked -> // needed? what's the issue dropping it?
// nothing normally
// to be deterministic
marked.stream()
.filter(Application.class::isAssignableFrom) // needed? what's the issue dropping it? nothing
// normally
.filter(app -> "true".equalsIgnoreCase(config.get().read("filter.active", "false")) ||
(app.isAnnotationPresent(LoginConfig.class) && "MP-JWT".equalsIgnoreCase(app.getAnnotation(LoginConfig.class).authMethod())))
.min(Comparator.comparing(Class::getName))
.ifPresent(app -> {
final FilterRegistration.Dynamic filter = ctx.addFilter("geronimo-microprofile-jwt-auth-filter", GeronimoJwtAuthFilter.class);
filter.setAsyncSupported(true);
final String[] mappings = ofNullable(app.getAnnotation(ApplicationPath.class))
.map(ApplicationPath::value)
.map(v -> (!v.startsWith("/") ? "/" : "") +
(v.contains("{") ? v.substring(0, v.indexOf("{")) : v) +
(v.endsWith("/") ? "" : "/") +
"*")
.map(v -> new String[]{v})
.orElseGet(() -> {
final ServletRegistration defaultServlet = ctx.getServletRegistration(Application.class.getName());
if (defaultServlet != null && !defaultServlet.getMappings().isEmpty()) {
return defaultServlet.getMappings().toArray(new String[defaultServlet.getMappings().size()]);
}
final String[] servletMapping = ctx.getServletRegistrations().values().stream()
.filter(r -> r.getInitParameter("javax.ws.rs.Application") != null)
.flatMap(r -> r.getMappings().stream())
.toArray(String[]::new);
if (servletMapping.length > 0) {
return servletMapping;
}
// unlikely
return new String[]{config.get().read("filter.mapping.default", "/*")};
});
filter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, mappings);
}));
}
}