Author: markt
Date: Mon Jun 15 22:11:10 2015
New Revision: 1685678
URL: http://svn.apache.org/r1685678
Log:
Implemented very basic JASPIC support with ability to register providers
Patch by fjodorver
Added:
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/JaspicCallbackHandler.java
(with props)
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/MessageInfoImpl.java
(with props)
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/PrincipalGroupCallback.java
(with props)
Modified:
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/JaspicAuthenticator.java
Modified:
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/JaspicAuthenticator.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/JaspicAuthenticator.java?rev=1685678&r1=1685677&r2=1685678&view=diff
==============================================================================
---
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/JaspicAuthenticator.java
(original)
+++
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/JaspicAuthenticator.java
Mon Jun 15 22:11:10 2015
@@ -17,38 +17,120 @@
package org.apache.catalina.authenticator.jaspic;
import java.io.IOException;
+import java.security.Principal;
+import java.util.Map;
+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.AuthConfigFactory;
+import javax.security.auth.message.config.AuthConfigProvider;
+import javax.security.auth.message.config.ServerAuthConfig;
+import javax.security.auth.message.config.ServerAuthContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
-import org.apache.catalina.Authenticator;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.authenticator.AuthenticatorBase;
import org.apache.catalina.connector.Request;
-import org.apache.catalina.connector.Response;
-import org.apache.catalina.valves.ValveBase;
+
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
-public class JaspicAuthenticator extends ValveBase implements Authenticator {
+public class JaspicAuthenticator extends AuthenticatorBase {
private static final Log log =
LogFactory.getLog(JaspicAuthenticator.class);
+ private static final String AUTH_TYPE = "JASPIC";
+ private static final String MESSAGE_LAYER = "HttpServlet";
+
+ private JaspicCallbackHandler callbackHandler;
+ private Subject serviceSubject;
+
+ @SuppressWarnings("rawtypes")
+ private Map authProperties = null;
+
+
+ @Override
+ protected synchronized void startInternal() throws LifecycleException {
+ super.startInternal();
+ callbackHandler = new JaspicCallbackHandler(container.getRealm());
+ serviceSubject = new Subject();
+ }
+
+
@Override
public boolean authenticate(Request request, HttpServletResponse response)
throws IOException {
- return true;
+ MessageInfo messageInfo = new MessageInfoImpl(request, response, true);
+ AuthConfigFactory factory = AuthConfigFactory.getFactory();
+ String appContext = request.getLocalName() + " " +
request.getContextPath();
+
+ AuthConfigProvider configProvider =
+ factory.getConfigProvider(MESSAGE_LAYER, appContext, null);
+ ServerAuthConfig authConfig = getAuthConfig(appContext,
configProvider);
+ String authContextId = authConfig.getAuthContextID(messageInfo);
+
+ ServerAuthContext authContext = null;
+ authContext = getAuthContext(authConfig, authContextId,
authProperties, authContext);
+ AuthStatus authStatus = validateRequest(messageInfo, authContext);
+
+ if (authStatus == AuthStatus.SUCCESS) {
+ Principal principal = callbackHandler.getPrincipal();
+ if (principal != null) {
+ register(request, response, principal, AUTH_TYPE, null, null);
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+
+ private AuthStatus validateRequest(MessageInfo messageInfo,
ServerAuthContext authContext) {
+ Subject clientSubject = new Subject();
+ try {
+ return authContext.validateRequest(messageInfo, clientSubject,
serviceSubject);
+ } catch (AuthException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+
+ @SuppressWarnings("rawtypes")
+ private ServerAuthContext getAuthContext(ServerAuthConfig authConfig,
String authContextId,
+ Map authProperties, ServerAuthContext authContext) {
+ try {
+ return authConfig.getAuthContext(authContextId, serviceSubject,
authProperties);
+ } catch (AuthException e) {
+ throw new IllegalStateException(e);
+ }
}
+
@Override
public void login(String userName, String password, Request request)
throws ServletException {
-
+ throw new IllegalStateException("not implemented yet!");
}
+
@Override
public void logout(Request request) {
+ throw new IllegalStateException("not implemented yet!");
+ }
+
+ private ServerAuthConfig getAuthConfig(String appContext,
AuthConfigProvider configProvider) {
+ try {
+ return configProvider.getServerAuthConfig(MESSAGE_LAYER,
appContext, callbackHandler);
+ } catch (AuthException e) {
+ throw new IllegalStateException(e);
+ }
}
+
@Override
- public void invoke(Request request, Response response) throws IOException,
ServletException {
- getNext().invoke(request, response);
+ protected String getAuthMethod() {
+ return AUTH_TYPE;
}
}
Added:
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/JaspicCallbackHandler.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/JaspicCallbackHandler.java?rev=1685678&view=auto
==============================================================================
---
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/JaspicCallbackHandler.java
(added)
+++
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/JaspicCallbackHandler.java
Mon Jun 15 22:11:10 2015
@@ -0,0 +1,76 @@
+/*
+ * 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.Collections;
+
+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 javax.security.auth.message.callback.PasswordValidationCallback;
+
+import org.apache.catalina.Realm;
+import org.apache.catalina.realm.GenericPrincipal;
+
+public class JaspicCallbackHandler implements CallbackHandler {
+
+ private Realm realm;
+
+ private ThreadLocal<PrincipalGroupCallback> principalGroupCallback = new
ThreadLocal<>();
+
+ public JaspicCallbackHandler(Realm realm) {
+ this.realm = realm;
+ }
+
+ @Override
+ public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
+ principalGroupCallback.set(new PrincipalGroupCallback());
+ for (Callback callback : callbacks) {
+ handleCallback(callback);
+ }
+ }
+
+ public Principal getPrincipal() {
+ return principalGroupCallback.get().getPrincipal();
+ }
+
+ private void handleCallback(Callback callback) {
+ if (callback instanceof CallerPrincipalCallback) {
+ principalGroupCallback.get().addCallback(callback);
+ } else if (callback instanceof GroupPrincipalCallback) {
+ principalGroupCallback.get().addCallback(callback);
+ } else if (callback instanceof PasswordValidationCallback) {
+ handlePasswordValidationCallback((PasswordValidationCallback)
callback);
+ } else {
+ throw new IllegalStateException("Unknown callback!");
+ }
+ }
+
+ private void handlePasswordValidationCallback(
+ PasswordValidationCallback passwordValidationCallback) {
+ Subject subject = passwordValidationCallback.getSubject();
+
+ passwordValidationCallback.setResult(true);
+ subject.getPrincipals().add(
+ new GenericPrincipal("user", "password",
Collections.singletonList("user")));
+ }
+}
Propchange:
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/JaspicCallbackHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/MessageInfoImpl.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/MessageInfoImpl.java?rev=1685678&view=auto
==============================================================================
---
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/MessageInfoImpl.java
(added)
+++
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/MessageInfoImpl.java
Mon Jun 15 22:11:10 2015
@@ -0,0 +1,78 @@
+/*
+ * 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.catalina.connector.Request;
+
+public class MessageInfoImpl implements MessageInfo {
+ private 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(Request 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("Request is not a servlet
request but "
+ + request.getClass().getName());
+ }
+ this.request = (HttpServletRequest) request;
+ }
+
+ @Override
+ public void setResponseMessage(Object response) {
+ if (!(response instanceof HttpServletResponse)) {
+ throw new IllegalArgumentException("response is not a servlet
response but "
+ + response.getClass().getName());
+ }
+ this.response = (HttpServletResponse) response;
+ }
+}
\ No newline at end of file
Propchange:
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/MessageInfoImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/PrincipalGroupCallback.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/PrincipalGroupCallback.java?rev=1685678&view=auto
==============================================================================
---
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/PrincipalGroupCallback.java
(added)
+++
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/PrincipalGroupCallback.java
Mon Jun 15 22:11:10 2015
@@ -0,0 +1,82 @@
+/*
+ * 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.security.Principal;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.message.callback.CallerPrincipalCallback;
+import javax.security.auth.message.callback.GroupPrincipalCallback;
+
+import org.apache.catalina.realm.GenericPrincipal;
+
+public class PrincipalGroupCallback {
+ private CallerPrincipalCallback callerPrincipalCallback;
+ private GroupPrincipalCallback groupPrincipalCallback;
+
+ public void addCallback(Callback callback) {
+ if (callback instanceof CallerPrincipalCallback) {
+ callerPrincipalCallback = (CallerPrincipalCallback) callback;
+ }
+ if (callback instanceof GroupPrincipalCallback) {
+ groupPrincipalCallback = (GroupPrincipalCallback) callback;
+ }
+ }
+
+ public Principal getPrincipal() {
+ if (callerPrincipalCallback != null) {
+ }
+ Principal userPrincipal = getUserPrincipal();
+ return new GenericPrincipal(getUserName(), null, getRoles(),
userPrincipal);
+ }
+
+ private Principal getUserPrincipal() {
+ if (callerPrincipalCallback == null) {
+ return null;
+ }
+ return callerPrincipalCallback.getPrincipal();
+ }
+
+ private List<String> getRoles() {
+ if (groupPrincipalCallback == null) {
+ return Collections.emptyList();
+ }
+ return Arrays.asList(groupPrincipalCallback.getGroups());
+ }
+
+ private String getUserName() {
+ String name = null;
+ if (callerPrincipalCallback != null) {
+ name = callerPrincipalCallback.getName();
+ }
+ if (name != null) {
+ return name;
+ }
+ return getUserPrincipalName();
+ }
+
+ private String getUserPrincipalName() {
+ Principal principal = getUserPrincipal();
+ if (principal == null) {
+ return null;
+ }
+ return principal.getName();
+ }
+}
Propchange:
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/PrincipalGroupCallback.java
------------------------------------------------------------------------------
svn:eol-style = native
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]