This commit is contained in:
2024-11-30 19:03:49 +08:00
commit 1e6763c160
3806 changed files with 737676 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,121 @@
/*
* 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.catalina.authenticator.jaspic;
import java.io.IOException;
import java.security.Principal;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.message.callback.CallerPrincipalCallback;
import javax.security.auth.message.callback.GroupPrincipalCallback;
import org.apache.catalina.realm.GenericPrincipal;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.res.StringManager;
/**
* Implemented as a singleton since the class is stateless.
*/
public class CallbackHandlerImpl implements CallbackHandler {
private static final StringManager sm = StringManager.getManager(CallbackHandlerImpl.class);
private static CallbackHandler instance;
static {
instance = new CallbackHandlerImpl();
}
public static CallbackHandler getInstance() {
return instance;
}
private CallbackHandlerImpl() {
// Hide default constructor
}
@Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
String name = null;
Principal principal = null;
Subject subject = null;
String[] groups = null;
if (callbacks != null) {
// Need to combine data from multiple callbacks so use this to hold
// the data
// Process the callbacks
for (Callback callback : callbacks) {
if (callback instanceof CallerPrincipalCallback) {
CallerPrincipalCallback cpc = (CallerPrincipalCallback) callback;
name = cpc.getName();
principal = cpc.getPrincipal();
subject = cpc.getSubject();
} else if (callback instanceof GroupPrincipalCallback) {
GroupPrincipalCallback gpc = (GroupPrincipalCallback) callback;
groups = gpc.getGroups();
} else {
// This is a singleton so need to get correct Logger for
// current TCCL
Log log = LogFactory.getLog(CallbackHandlerImpl.class);
log.error(sm.getString("callbackHandlerImpl.jaspicCallbackMissing",
callback.getClass().getName()));
}
}
// Create the GenericPrincipal
Principal gp = getPrincipal(principal, name, groups);
if (subject != null && gp != null) {
subject.getPrivateCredentials().add(gp);
}
}
}
private Principal getPrincipal(Principal principal, String name, String[] groups) {
// If the Principal is cached in the session JASPIC may simply return it
if (principal instanceof GenericPrincipal) {
return principal;
}
if (name == null && principal != null) {
name = principal.getName();
}
if (name == null) {
return null;
}
List<String> roles;
if (groups == null || groups.length == 0) {
roles = Collections.emptyList();
} else {
roles = Arrays.asList(groups);
}
return new GenericPrincipal(name, null, roles, principal);
}
}

View File

@@ -0,0 +1,30 @@
# 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.
authConfigFactoryImpl.load=Loading persistent provider registrations from [{0}]
authConfigFactoryImpl.registerClass=Registering class [{0}] for layer [{1}] and application context [{2}]
authConfigFactoryImpl.registerInstance=Registering instance of type[{0}] for layer [{1}] and application context [{2}]
authConfigFactoryImpl.zeroLengthAppContext=A zero length application context name is not valid
authConfigFactoryImpl.zeroLengthMessageLayer=A zero length message layer name is not valid
callbackHandlerImpl.jaspicCallbackMissing=Unsupported JASPIC callback of type [{0}] received which was ignored
jaspicAuthenticator.authenticate=Authenticating request for [{0}] via JASPIC
persistentProviderRegistrations.deleteFail=The temporary file [{0}] cannot be deleted
persistentProviderRegistrations.existsDeleteFail=The temporary file [{0}] already exists and cannot be deleted
persistentProviderRegistrations.moveFail=Failed to move [{0}] to [{1}]
simpleServerAuthConfig.noModules="No ServerAuthModules configured"

View File

@@ -0,0 +1,18 @@
# 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.
authConfigFactoryImpl.zeroLengthAppContext=Ein leerer Name für einen Applikationskontext ist nicht erlaubt.
persistentProviderRegistrations.existsDeleteFail=Die temporäre Datei [{0}] existiert bereits und kann nicht gelöscht werden

View File

@@ -0,0 +1,18 @@
# 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.
authConfigFactoryImpl.zeroLengthAppContext=Un nombre de aplicación con nombre de contexto de longitud cero no es válido
persistentProviderRegistrations.existsDeleteFail=El archivo temporal [{0}] ya existe y no puede ser borrado

View File

@@ -0,0 +1,30 @@
# 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.
authConfigFactoryImpl.load=Chargement des enregistrements pour le fournisseurs persistants à partir de [{0}]
authConfigFactoryImpl.registerClass=Enregistrement de la classe [{0}] pour la couche [{1}] et le contexte d''application [{2}]
authConfigFactoryImpl.registerInstance=Enregistrement de l''instance de type [{0}] pour la couche [{1}] et le contexte d''application [{2}]
authConfigFactoryImpl.zeroLengthAppContext=Un nom de contexte vide n'est pas valide
authConfigFactoryImpl.zeroLengthMessageLayer=Un message vide de nom de couche est invalide
callbackHandlerImpl.jaspicCallbackMissing=Le rappel (callback) JASPIC de type [{0}] reçu n''est pas supporté et a été ignoré
jaspicAuthenticator.authenticate=Authentification de la requête pour [{0}] avec JASPIC
persistentProviderRegistrations.deleteFail=Le fichier temporaire [{0}] n''a pas pu être effacé
persistentProviderRegistrations.existsDeleteFail=Le fichier temporaire [{0}] existe déjà et ne peut être effacé
persistentProviderRegistrations.moveFail=Echec de déplacement de [{0}] vers [{1}]
simpleServerAuthConfig.noModules=Aucun ServerAuthModules n'est configuré

View File

@@ -0,0 +1,30 @@
# 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.
authConfigFactoryImpl.load=[{0}]から永続的なプロバイダ登録を読み込みます。
authConfigFactoryImpl.registerClass=アプリケーションコンテキスト [{2}] のレイヤー [{1}] にクラス [{0}] を登録します。
authConfigFactoryImpl.registerInstance=レイヤ[{1}]とアプリケーションコンテキスト[{2}]のタイプ[{0}]のインスタンスの登録
authConfigFactoryImpl.zeroLengthAppContext=文字列長が 0 のアプリケーションコンテキスト名は不正です。
authConfigFactoryImpl.zeroLengthMessageLayer=長さゼロのメッセージ層名は無効です
callbackHandlerImpl.jaspicCallbackMissing=受信したタイプ[{0}]のサポートされていないJASPICコールバックが無視されました。
jaspicAuthenticator.authenticate=JASPIC経由で[{0}]へのリクエストを認証しています
persistentProviderRegistrations.deleteFail=一時ファイル [{0}] を削除できません。
persistentProviderRegistrations.existsDeleteFail=同名の一時ファイル [{0}] が存在し、削除もできませんでした。
persistentProviderRegistrations.moveFail=[{0}]を[{1}]に移動できませんでした。
simpleServerAuthConfig.noModules="ServerAuthModulesが設定されていません"

View File

@@ -0,0 +1,30 @@
# 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.
authConfigFactoryImpl.load=[{0}](으)로부터 persistent provider 등록 사항들을 로드합니다.
authConfigFactoryImpl.registerClass=레이어 [{1}]와(과) 애플리케이션 컨텍스트 [{2}]을(를) 위한 클래스 [{0}]을(를) 등록합니다.
authConfigFactoryImpl.registerInstance=레이어 [{1}]와(과) 애플리케이션 컨텍스트 [{2}]을(를) 위한 타입 [{0}]의 인스턴스를 등록합니다.
authConfigFactoryImpl.zeroLengthAppContext=애플리케이션 컨텍스트 이름의 길이가 0으로, 이는 유효하지 않습니다.
authConfigFactoryImpl.zeroLengthMessageLayer=길이가 0인 메시지 레이어 이름은 유효하지 않습니다.
callbackHandlerImpl.jaspicCallbackMissing=타입이 [{0}]인 지원되지 않는 JASPIC 콜백을 받았는데, 이는 무시됩니다.
jaspicAuthenticator.authenticate=[{0}]을(를) 위한 요청을 JASPIC를 통하여 인증합니다.
persistentProviderRegistrations.deleteFail=임시 파일 [{0}]을(를) 삭제할 수 없습니다.
persistentProviderRegistrations.existsDeleteFail=임시 파일 [{0}]이(가) 이미 존재하며 삭제될 수 없습니다.
persistentProviderRegistrations.moveFail=[{0}]을(를) [{1}](으)로 이동시키지 못했습니다.
simpleServerAuthConfig.noModules="ServerAuthModule이 설정되지 않음"

View File

@@ -0,0 +1,16 @@
# 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.
persistentProviderRegistrations.existsDeleteFail=Временный файл [{0}] уже существует и не может быть удалён

View File

@@ -0,0 +1,26 @@
# 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.
authConfigFactoryImpl.load=从[{0}]加载持久化提供者注册信息
authConfigFactoryImpl.zeroLengthAppContext=:)应用上下文名称的长度为0是无效的
authConfigFactoryImpl.zeroLengthMessageLayer=零长度的消息层名称是无效的
jaspicAuthenticator.authenticate=通过JASPIC验证[{0}]的请求
persistentProviderRegistrations.deleteFail=无法删除临时文件[{0}]
persistentProviderRegistrations.existsDeleteFail=临时文件[{0}]已存在且无法删除
persistentProviderRegistrations.moveFail=无法将[{0}]移至[{1}]
simpleServerAuthConfig.noModules=“没有配置ServerAuthModules”

View File

@@ -0,0 +1,80 @@
/*
* 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.catalina.authenticator.jaspic;
import java.util.HashMap;
import java.util.Map;
import javax.security.auth.message.MessageInfo;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.tomcat.util.res.StringManager;
public class MessageInfoImpl implements MessageInfo {
protected static final StringManager sm = StringManager.getManager(MessageInfoImpl.class);
public static final String IS_MANDATORY = "javax.security.auth.message.MessagePolicy.isMandatory";
private final Map<String, Object> map = new HashMap<>();
private HttpServletRequest request;
private HttpServletResponse response;
public MessageInfoImpl() {
}
public MessageInfoImpl(HttpServletRequest request, HttpServletResponse response, boolean authMandatory) {
this.request = request;
this.response = response;
map.put(IS_MANDATORY, Boolean.toString(authMandatory));
}
@Override
@SuppressWarnings("rawtypes")
// JASPIC uses raw types
public Map getMap() {
return map;
}
@Override
public Object getRequestMessage() {
return request;
}
@Override
public Object getResponseMessage() {
return response;
}
@Override
public void setRequestMessage(Object request) {
if (!(request instanceof HttpServletRequest)) {
throw new IllegalArgumentException(sm.getString("authenticator.jaspic.badRequestType",
request.getClass().getName()));
}
this.request = (HttpServletRequest) request;
}
@Override
public void setResponseMessage(Object response) {
if (!(response instanceof HttpServletResponse)) {
throw new IllegalArgumentException(sm.getString("authenticator.jaspic.badResponseType",
response.getClass().getName()));
}
this.response = (HttpServletResponse) response;
}
}

View File

@@ -0,0 +1,265 @@
/**
* 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.catalina.authenticator.jaspic;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.digester.Digester;
import org.apache.tomcat.util.res.StringManager;
import org.xml.sax.SAXException;
/**
* Utility class for the loading and saving of JASPIC persistent provider
* registrations.
*/
final class PersistentProviderRegistrations {
private static final StringManager sm =
StringManager.getManager(PersistentProviderRegistrations.class);
private PersistentProviderRegistrations() {
// Utility class. Hide default constructor
}
static Providers loadProviders(File configFile) {
try (InputStream is = new FileInputStream(configFile)) {
// Construct a digester to read the XML input file
Digester digester = new Digester();
try {
digester.setFeature("http://apache.org/xml/features/allow-java-encodings", true);
digester.setValidating(true);
digester.setNamespaceAware(true);
} catch (Exception e) {
throw new SecurityException(e);
}
// Create an object to hold the parse results and put it on the top
// of the digester's stack
Providers result = new Providers();
digester.push(result);
// Configure the digester
digester.addObjectCreate("jaspic-providers/provider", Provider.class.getName());
digester.addSetProperties("jaspic-providers/provider");
digester.addSetNext("jaspic-providers/provider", "addProvider", Provider.class.getName());
digester.addObjectCreate("jaspic-providers/provider/property", Property.class.getName());
digester.addSetProperties("jaspic-providers/provider/property");
digester.addSetNext("jaspic-providers/provider/property", "addProperty", Property.class.getName());
// Parse the input
digester.parse(is);
return result;
} catch (IOException | SAXException e) {
throw new SecurityException(e);
}
}
static void writeProviders(Providers providers, File configFile) {
File configFileOld = new File(configFile.getAbsolutePath() + ".old");
File configFileNew = new File(configFile.getAbsolutePath() + ".new");
// Remove left over temporary files if present
if (configFileOld.exists()) {
if (configFileOld.delete()) {
throw new SecurityException(sm.getString(
"persistentProviderRegistrations.existsDeleteFail",
configFileOld.getAbsolutePath()));
}
}
if (configFileNew.exists()) {
if (configFileNew.delete()) {
throw new SecurityException(sm.getString(
"persistentProviderRegistrations.existsDeleteFail",
configFileNew.getAbsolutePath()));
}
}
// Write out the providers to the temporary new file
try (OutputStream fos = new FileOutputStream(configFileNew);
Writer writer = new OutputStreamWriter(fos, StandardCharsets.UTF_8)) {
writer.write(
"<?xml version='1.0' encoding='utf-8'?>\n" +
"<jaspic-providers\n" +
" xmlns=\"http://tomcat.apache.org/xml\"\n" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
" xsi:schemaLocation=\"http://tomcat.apache.org/xml jaspic-providers.xsd\"\n" +
" version=\"1.0\">\n");
for (Provider provider : providers.providers) {
writer.write(" <provider");
writeOptional("className", provider.getClassName(), writer);
writeOptional("layer", provider.getLayer(), writer);
writeOptional("appContext", provider.getAppContext(), writer);
writeOptional("description", provider.getDescription(), writer);
writer.write(">\n");
for (Entry<String,String> entry : provider.getProperties().entrySet()) {
writer.write(" <property name=\"");
writer.write(entry.getKey());
writer.write("\" value=\"");
writer.write(entry.getValue());
writer.write("\"/>\n");
}
writer.write(" </provider>\n");
}
writer.write("</jaspic-providers>\n");
} catch (IOException e) {
if (!configFileNew.delete()) {
Log log = LogFactory.getLog(PersistentProviderRegistrations.class);
log.warn(sm.getString("persistentProviderRegistrations.deleteFail",
configFileNew.getAbsolutePath()));
}
throw new SecurityException(e);
}
// Move the current file out of the way
if (configFile.isFile()) {
if (!configFile.renameTo(configFileOld)) {
throw new SecurityException(sm.getString("persistentProviderRegistrations.moveFail",
configFile.getAbsolutePath(), configFileOld.getAbsolutePath()));
}
}
// Move the new file into place
if (!configFileNew.renameTo(configFile)) {
throw new SecurityException(sm.getString("persistentProviderRegistrations.moveFail",
configFileNew.getAbsolutePath(), configFile.getAbsolutePath()));
}
// Remove the old file
if (configFileOld.exists() && !configFileOld.delete()) {
Log log = LogFactory.getLog(PersistentProviderRegistrations.class);
log.warn(sm.getString("persistentProviderRegistrations.deleteFail",
configFileOld.getAbsolutePath()));
}
}
private static void writeOptional(String name, String value, Writer writer) throws IOException {
if (value != null) {
writer.write(" " + name + "=\"");
writer.write(value);
writer.write("\"");
}
}
public static class Providers {
private final List<Provider> providers = new ArrayList<>();
public void addProvider(Provider provider) {
providers.add(provider);
}
public List<Provider> getProviders() {
return providers;
}
}
public static class Provider {
private String className;
private String layer;
private String appContext;
private String description;
private final Map<String,String> properties = new HashMap<>();
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getLayer() {
return layer;
}
public void setLayer(String layer) {
this.layer = layer;
}
public String getAppContext() {
return appContext;
}
public void setAppContext(String appContext) {
this.appContext = appContext;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public void addProperty(Property property) {
properties.put(property.getName(), property.getValue());
}
void addProperty(String name, String value) {
properties.put(name, value);
}
public Map<String,String> getProperties() {
return properties;
}
}
public static class Property {
private String name;
private String value;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}

View File

@@ -0,0 +1,89 @@
/**
* 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.catalina.authenticator.jaspic;
import java.util.Map;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.message.AuthException;
import javax.security.auth.message.config.AuthConfigFactory;
import javax.security.auth.message.config.AuthConfigProvider;
import javax.security.auth.message.config.ClientAuthConfig;
import javax.security.auth.message.config.ServerAuthConfig;
/**
* Basic implementation primarily intended for use when using third-party
* {@link javax.security.auth.message.module.ServerAuthModule} implementations
* that only provide the module.
*/
public class SimpleAuthConfigProvider implements AuthConfigProvider {
private final Map<String,String> properties;
private volatile ServerAuthConfig serverAuthConfig;
public SimpleAuthConfigProvider(Map<String,String> properties, AuthConfigFactory factory) {
this.properties = properties;
if (factory != null) {
factory.registerConfigProvider(this, null, null, "Automatic registration");
}
}
/**
* {@inheritDoc}
* <p>
* This implementation does not support client-side authentication and
* therefore always returns {@code null}.
*/
@Override
public ClientAuthConfig getClientAuthConfig(String layer, String appContext,
CallbackHandler handler) throws AuthException {
return null;
}
@Override
public ServerAuthConfig getServerAuthConfig(String layer, String appContext,
CallbackHandler handler) throws AuthException {
ServerAuthConfig serverAuthConfig = this.serverAuthConfig;
if (serverAuthConfig == null) {
synchronized (this) {
if (this.serverAuthConfig == null) {
this.serverAuthConfig = createServerAuthConfig(layer, appContext, handler, properties);
}
serverAuthConfig = this.serverAuthConfig;
}
}
return serverAuthConfig;
}
protected ServerAuthConfig createServerAuthConfig(String layer, String appContext,
CallbackHandler handler, Map<String,String> properties) {
return new SimpleServerAuthConfig(layer, appContext, handler, properties);
}
@Override
public void refresh() {
ServerAuthConfig serverAuthConfig = this.serverAuthConfig;
if (serverAuthConfig != null) {
serverAuthConfig.refresh();
}
}
}

View File

@@ -0,0 +1,150 @@
/**
* 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.catalina.authenticator.jaspic;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.message.AuthException;
import javax.security.auth.message.MessageInfo;
import javax.security.auth.message.config.ServerAuthConfig;
import javax.security.auth.message.config.ServerAuthContext;
import javax.security.auth.message.module.ServerAuthModule;
import org.apache.tomcat.util.res.StringManager;
/**
* Basic implementation primarily intended for use when using third-party
* {@link ServerAuthModule} implementations that only provide the module. This
* implementation supports configuring the {@link ServerAuthContext} with
* multiple modules.
*/
public class SimpleServerAuthConfig implements ServerAuthConfig {
private static StringManager sm = StringManager.getManager(SimpleServerAuthConfig.class);
private static final String SERVER_AUTH_MODULE_KEY_PREFIX =
"org.apache.catalina.authenticator.jaspic.ServerAuthModule.";
private final String layer;
private final String appContext;
private final CallbackHandler handler;
private final Map<String,String> properties;
private volatile ServerAuthContext serverAuthContext;
public SimpleServerAuthConfig(String layer, String appContext, CallbackHandler handler,
Map<String,String> properties) {
this.layer = layer;
this.appContext = appContext;
this.handler = handler;
this.properties = properties;
}
@Override
public String getMessageLayer() {
return layer;
}
@Override
public String getAppContext() {
return appContext;
}
@Override
public String getAuthContextID(MessageInfo messageInfo) {
return messageInfo.toString();
}
@Override
public void refresh() {
serverAuthContext = null;
}
@Override
public boolean isProtected() {
return false;
}
@SuppressWarnings({"rawtypes", "unchecked"}) // JASPIC API uses raw types
@Override
public ServerAuthContext getAuthContext(String authContextID, Subject serviceSubject,
Map properties) throws AuthException {
ServerAuthContext serverAuthContext = this.serverAuthContext;
if (serverAuthContext == null) {
synchronized (this) {
if (this.serverAuthContext == null) {
Map<String,String> mergedProperties = new HashMap<>();
if (this.properties != null) {
mergedProperties.putAll(this.properties);
}
if (properties != null) {
mergedProperties.putAll(properties);
}
List<ServerAuthModule> modules = new ArrayList<>();
int moduleIndex = 1;
String key = SERVER_AUTH_MODULE_KEY_PREFIX + moduleIndex;
String moduleClassName = mergedProperties.get(key);
while (moduleClassName != null) {
try {
Class<?> clazz = Class.forName(moduleClassName);
ServerAuthModule module =
(ServerAuthModule) clazz.getConstructor().newInstance();
module.initialize(null, null, handler, mergedProperties);
modules.add(module);
} catch (ReflectiveOperationException | IllegalArgumentException |
SecurityException e) {
AuthException ae = new AuthException();
ae.initCause(e);
throw ae;
}
// Look for the next module
moduleIndex++;
key = SERVER_AUTH_MODULE_KEY_PREFIX + moduleIndex;
moduleClassName = mergedProperties.get(key);
}
if (modules.size() == 0) {
throw new AuthException(sm.getString("simpleServerAuthConfig.noModules"));
}
this.serverAuthContext = createServerAuthContext(modules);
}
serverAuthContext = this.serverAuthContext;
}
}
return serverAuthContext;
}
protected ServerAuthContext createServerAuthContext(List<ServerAuthModule> modules) {
return new SimpleServerAuthContext(modules);
}
}

View File

@@ -0,0 +1,74 @@
/**
* 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.catalina.authenticator.jaspic;
import java.util.List;
import javax.security.auth.Subject;
import javax.security.auth.message.AuthException;
import javax.security.auth.message.AuthStatus;
import javax.security.auth.message.MessageInfo;
import javax.security.auth.message.config.ServerAuthContext;
import javax.security.auth.message.module.ServerAuthModule;
/**
* Basic implementation primarily intended for use when using third-party
* {@link ServerAuthModule} implementations that only provide the module. This
* implementation supports multiple modules and will treat the user as
* authenticated if any one module is able to authenticate the user.
*/
public class SimpleServerAuthContext implements ServerAuthContext {
private final List<ServerAuthModule> modules;
public SimpleServerAuthContext(List<ServerAuthModule> modules) {
this.modules = modules;
}
@SuppressWarnings("unchecked") // JASPIC API uses raw types
@Override
public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject,
Subject serviceSubject) throws AuthException {
for (int moduleIndex = 0; moduleIndex < modules.size(); moduleIndex++) {
ServerAuthModule module = modules.get(moduleIndex);
AuthStatus result = module.validateRequest(messageInfo, clientSubject, serviceSubject);
if (result != AuthStatus.SEND_FAILURE) {
messageInfo.getMap().put("moduleIndex", Integer.valueOf(moduleIndex));
return result;
}
}
return AuthStatus.SEND_FAILURE;
}
@Override
public AuthStatus secureResponse(MessageInfo messageInfo, Subject serviceSubject)
throws AuthException {
ServerAuthModule module = modules.get(((Integer) messageInfo.getMap().get("moduleIndex")).intValue());
return module.secureResponse(messageInfo, serviceSubject);
}
@Override
public void cleanSubject(MessageInfo messageInfo, Subject subject) throws AuthException {
for (ServerAuthModule module : modules) {
module.cleanSubject(messageInfo, subject);
}
}
}