Hi Sergey, Done, removed unnecessary attributes from HttpServletRequest if pass authentication.
Cheers ------------- Freeman(Yue) Fang Red Hat, Inc. FuseSource is now part of Red Hat Web: http://fusesource.com | http://www.redhat.com/ Twitter: freemanfang Blog: http://freemanfang.blogspot.com http://blog.sina.com.cn/u/1473905042 weibo: @Freeman小屋 On 2013-7-29, at 下午5:41, Sergey Beryozkin wrote: > Hi Freeman > > Can you please update ServiceListGeneratorServlet to actually remove the temp > HTTPServletRequest attributes - because they are not needed any more after > that ? > > The reason is that these attributes will leak into JAX-RS > ContainerRequestFilter.getProperties() - unfortunately this method has been > tied to HTTPServletRequest attributes, > > Thanks, Sergey > > Thanks, Sergey > On 29/07/13 10:31, [email protected] wrote: >> Author: ffang >> Date: Mon Jul 29 09:31:48 2013 >> New Revision: 1507984 >> >> URL: http://svn.apache.org/r1507984 >> Log: >> [CXF-5165]add a JAAS authenticator for ServiceListPage >> >> Added: >> >> cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/servicelist/ServiceListJAASAuthenticator.java >> Modified: >> >> cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/ServletController.java >> >> cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/servicelist/ServiceListGeneratorServlet.java >> >> cxf/trunk/rt/transports/http/src/main/resources/OSGI-INF/blueprint/osgiservlet.xml >> >> Modified: >> cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/ServletController.java >> URL: >> http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/ServletController.java?rev=1507984&r1=1507983&r2=1507984&view=diff >> ============================================================================== >> --- >> cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/ServletController.java >> (original) >> +++ >> cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/ServletController.java >> Mon Jul 29 09:31:48 2013 >> @@ -40,12 +40,17 @@ import org.apache.cxf.transport.http.Abs >> import org.apache.cxf.transport.http.DestinationRegistry; >> >> public class ServletController { >> + >> + public static final String AUTH_SERVICE_LIST = "auth.service.list"; >> + public static final String AUTH_SERVICE_LIST_REALM = >> "auth.service.list.realm"; >> protected static final String DEFAULT_LISTINGS_CLASSIFIER = "/services"; >> private static final Logger LOG = >> LogUtils.getL7dLogger(ServletController.class); >> private static final String HTTP_PREFIX = "http"; >> - >> + >> protected boolean isHideServiceList; >> + protected boolean isAuthServiceListPage; >> protected boolean disableAddressUpdates; >> + protected String authServiceListPageRealm; >> protected String forcedBaseAddress; >> protected String serviceListRelativePath = DEFAULT_LISTINGS_CLASSIFIER; >> protected ServletConfig servletConfig; >> @@ -108,6 +113,17 @@ public class ServletController { >> if (!StringUtils.isEmpty(hideServiceList)) { >> this.isHideServiceList = Boolean.valueOf(hideServiceList); >> } >> + >> + String authServiceListPage = >> servletConfig.getInitParameter("service-list-page-authenticate"); >> + if (!StringUtils.isEmpty(authServiceListPage)) { >> + this.isAuthServiceListPage = >> Boolean.valueOf(authServiceListPage); >> + } >> + >> + String authServiceListRealm = >> servletConfig.getInitParameter("service-list-page-authenticate-realm"); >> + if (!StringUtils.isEmpty(authServiceListRealm)) { >> + this.authServiceListPageRealm = authServiceListRealm; >> + } >> + >> String isDisableAddressUpdates = >> servletConfig.getInitParameter("disable-address-updates"); >> if (!StringUtils.isEmpty(isDisableAddressUpdates)) { >> this.disableAddressUpdates = >> Boolean.valueOf(isDisableAddressUpdates); >> @@ -143,6 +159,9 @@ public class ServletController { >> || >> request.getRequestURI().endsWith(serviceListRelativePath + "/") >> || StringUtils.isEmpty(pathInfo) >> || "/".equals(pathInfo))) { >> + if (isAuthServiceListPage) { >> + setAuthServiceListPageAttribute(request); >> + } >> setBaseURLAttribute(request); >> serviceListGenerator.service(request, res); >> } else { >> @@ -188,6 +207,12 @@ public class ServletController { >> return true; >> } >> >> + private void setAuthServiceListPageAttribute(HttpServletRequest >> request) { >> + request.setAttribute(ServletController.AUTH_SERVICE_LIST, >> this.isAuthServiceListPage); >> + request.setAttribute(ServletController.AUTH_SERVICE_LIST_REALM, >> this.authServiceListPageRealm); >> + >> + } >> + >> public void invokeDestination(final HttpServletRequest request, >> HttpServletResponse response, >> AbstractHTTPDestination d) throws >> ServletException { >> if (LOG.isLoggable(Level.FINE)) { >> >> Modified: >> cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/servicelist/ServiceListGeneratorServlet.java >> URL: >> http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/servicelist/ServiceListGeneratorServlet.java?rev=1507984&r1=1507983&r2=1507984&view=diff >> ============================================================================== >> --- >> cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/servicelist/ServiceListGeneratorServlet.java >> (original) >> +++ >> cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/servicelist/ServiceListGeneratorServlet.java >> Mon Jul 29 09:31:48 2013 >> @@ -39,6 +39,7 @@ import org.apache.cxf.message.Message; >> import org.apache.cxf.service.model.EndpointInfo; >> import org.apache.cxf.transport.AbstractDestination; >> import org.apache.cxf.transport.http.DestinationRegistry; >> +import org.apache.cxf.transport.servlet.ServletController; >> >> public class ServiceListGeneratorServlet extends HttpServlet { >> private static final long serialVersionUID = -113918058557537996L; >> @@ -67,6 +68,19 @@ public class ServiceListGeneratorServlet >> @Override >> public void service(HttpServletRequest request, >> HttpServletResponse response) throws >> ServletException, IOException { >> + Object obj = >> request.getAttribute(ServletController.AUTH_SERVICE_LIST); >> + boolean isAuthServiceList = false; >> + if (obj != null) { >> + isAuthServiceList = Boolean.valueOf(obj.toString()); >> + } >> + if (isAuthServiceList) { >> + String authServiceListRealm = >> (String)request.getAttribute(ServletController.AUTH_SERVICE_LIST_REALM); >> + ServiceListJAASAuthenticator authenticator = new >> ServiceListJAASAuthenticator(); >> + authenticator.setRealm(authServiceListRealm); >> + if (!authenticator.authenticate(request, response)) { >> + return; >> + } >> + } >> PrintWriter writer = response.getWriter(); >> AbstractDestination[] destinations = >> destinationRegistry.getSortedDestinations(); >> if (request.getParameter("stylesheet") != null) { >> >> Added: >> cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/servicelist/ServiceListJAASAuthenticator.java >> URL: >> http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/servicelist/ServiceListJAASAuthenticator.java?rev=1507984&view=auto >> ============================================================================== >> --- >> cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/servicelist/ServiceListJAASAuthenticator.java >> (added) >> +++ >> cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/servicelist/ServiceListJAASAuthenticator.java >> Mon Jul 29 09:31:48 2013 >> @@ -0,0 +1,163 @@ >> +/** >> + * 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.cxf.transport.servlet.servicelist; >> + >> +import java.io.IOException; >> +import java.io.UnsupportedEncodingException; >> +import java.security.GeneralSecurityException; >> +import java.util.logging.Level; >> +import java.util.logging.Logger; >> + >> +import javax.security.auth.Subject; >> +import javax.security.auth.callback.Callback; >> +import javax.security.auth.callback.CallbackHandler; >> +import javax.security.auth.callback.NameCallback; >> +import javax.security.auth.callback.PasswordCallback; >> +import javax.security.auth.callback.UnsupportedCallbackException; >> +import javax.security.auth.login.AccountException; >> +import javax.security.auth.login.FailedLoginException; >> +import javax.security.auth.login.LoginContext; >> +import javax.servlet.http.HttpServletRequest; >> +import javax.servlet.http.HttpServletResponse; >> + >> +import org.apache.cxf.common.logging.LogUtils; >> +import org.apache.cxf.common.util.Base64Exception; >> +import org.apache.cxf.common.util.Base64Utility; >> +import >> org.apache.cxf.transport.http.blueprint.HttpDestinationBPBeanDefinitionParser; >> + >> + >> + >> +public class ServiceListJAASAuthenticator { >> + >> + private static final Logger LOG = >> LogUtils.getL7dLogger(HttpDestinationBPBeanDefinitionParser.class); >> + >> + private static final String HEADER_WWW_AUTHENTICATE = >> "WWW-Authenticate"; >> + >> + private static final String HEADER_AUTHORIZATION = "Authorization"; >> + >> + private static final String AUTHENTICATION_SCHEME_BASIC = "Basic"; >> + >> + private String realm; >> + >> + public String getRealm() { >> + return realm; >> + } >> + >> + public void setRealm(String realm) { >> + this.realm = realm; >> + } >> + >> + >> + public Object authenticate(final String username, final String >> password) { >> + return doAuthenticate(username, password); >> + } >> + >> + public Subject doAuthenticate(final String username, final String >> password) { >> + try { >> + Subject subject = new Subject(); >> + LoginContext loginContext = new LoginContext(realm, subject, >> new CallbackHandler() { >> + public void handle(Callback[] callbacks) throws >> IOException, UnsupportedCallbackException { >> + for (int i = 0; i < callbacks.length; i++) { >> + if (callbacks[i] instanceof NameCallback) { >> + ((NameCallback)callbacks[i]).setName(username); >> + } else if (callbacks[i] instanceof >> PasswordCallback) { >> + >> ((PasswordCallback)callbacks[i]).setPassword(password.toCharArray()); >> + } else { >> + throw new >> UnsupportedCallbackException(callbacks[i]); >> + } >> + } >> + } >> + }); >> + loginContext.login(); >> + return subject; >> + } catch (FailedLoginException e) { >> + LOG.log(Level.FINE, "Login failed ", e); >> + return null; >> + } catch (AccountException e) { >> + LOG.log(Level.WARNING, "Account failure ", e); >> + return null; >> + } catch (GeneralSecurityException e) { >> + LOG.log(Level.SEVERE, "General Security Exception ", e); >> + return null; >> + } >> + } >> + >> + public boolean authenticate(HttpServletRequest request, >> HttpServletResponse response) { >> + // Return immediately if the header is missing >> + String authHeader = request.getHeader(HEADER_AUTHORIZATION); >> + if (authHeader != null && authHeader.length() > 0) { >> + >> + // Get the authType (Basic, Digest) and authInfo (user/password) >> + // from the header >> + authHeader = authHeader.trim(); >> + int blank = authHeader.indexOf(' '); >> + if (blank > 0) { >> + String authType = authHeader.substring(0, blank); >> + String authInfo = authHeader.substring(blank).trim(); >> + >> + >> + if (authType.equalsIgnoreCase(AUTHENTICATION_SCHEME_BASIC)) >> { >> + try { >> + String srcString = base64Decode(authInfo); >> + >> + int i = srcString.indexOf(':'); >> + String username = srcString.substring(0, i); >> + String password = srcString.substring(i + 1); >> + >> + // authenticate >> + Subject subject = doAuthenticate(username, >> password); >> + if (subject != null) { >> + return true; >> + } >> + >> + } catch (Exception e) { >> + // Ignore >> + } >> + } >> + } >> + } >> + >> + // request authentication >> + try { >> + response.setHeader(HEADER_WWW_AUTHENTICATE, >> AUTHENTICATION_SCHEME_BASIC + " realm=\"" >> + + this.realm + >> "\""); >> + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); >> + response.setContentLength(0); >> + response.flushBuffer(); >> + } catch (IOException ioe) { >> + // failed sending the response ... cannot do anything about it >> + } >> + >> + // inform HttpService that authentication failed >> + return false; >> + } >> + >> + private static String base64Decode(String srcString) { >> + byte[] transformed = null; >> + try { >> + transformed = Base64Utility.decode(srcString); >> + return new String(transformed, "ISO-8859-1"); >> + } catch (UnsupportedEncodingException uee) { >> + return srcString; >> + } catch (Base64Exception e) { >> + return srcString; >> + } >> + } >> + >> +} >> >> Modified: >> cxf/trunk/rt/transports/http/src/main/resources/OSGI-INF/blueprint/osgiservlet.xml >> URL: >> http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/resources/OSGI-INF/blueprint/osgiservlet.xml?rev=1507984&r1=1507983&r2=1507984&view=diff >> ============================================================================== >> --- >> cxf/trunk/rt/transports/http/src/main/resources/OSGI-INF/blueprint/osgiservlet.xml >> (original) >> +++ >> cxf/trunk/rt/transports/http/src/main/resources/OSGI-INF/blueprint/osgiservlet.xml >> Mon Jul 29 09:31:48 2013 >> @@ -39,7 +39,8 @@ under the License. >> <cm:property name="org.apache.cxf.servlet.redirect-servlet-name" >> value=""/> >> <cm:property name="org.apache.cxf.servlet.redirect-servlet-path" >> value=""/> >> <cm:property name="org.apache.cxf.servlet.service-list-all-contexts" >> value=""/> >> - >> + <cm:property >> name="org.apache.cxf.servlet.service-list-page-authenticate" value="false"/> >> + <cm:property >> name="org.apache.cxf.servlet.service-list-page-authenticate-realm" >> value="karaf"/> >> </cm:default-properties> >> >> </cm:property-placeholder> >> @@ -64,6 +65,8 @@ under the License. >> <entry key="redirect-servlet-name" >> value="${org.apache.cxf.servlet.redirect-servlet-name}"/> >> <entry key="redirect-servlet-path" >> value="${org.apache.cxf.servlet.redirect-servlet-path}"/> >> <entry key="service-list-all-contexts" >> value="${org.apache.cxf.servlet.service-list-all-contexts}"/> >> + <entry key="service-list-page-authenticate" >> value="${org.apache.cxf.servlet.service-list-page-authenticate}"/> >> + <entry key="service-list-page-authenticate-realm" >> value="${org.apache.cxf.servlet.service-list-page-authenticate-realm}"/> >> </service-properties> >> </service> >> >> >> > >
