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: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to