[jcifs] NtlmHttpFilter for SunApp Server 8
Kelvin Phan
Phan.Kelvin at con-way.com
Fri Aug 27 20:44:21 GMT 2004
Here is the code to work with SUNWappserver 8 for those who need it.
Kelvin
==========================================
web.xml
-----------
<filter>
<filter-name>NtlmHttpFilter</filter-name>
<filter-class>jcifs.http.NtlmHttpFilterSunApp</filter-class>
<init-param>
<param-name>jcifs.http.domainController</param-name>
<param-value>your.domain.controller.ipaddress</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>NtlmHttpFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
================================
NtlmHttpFilterSunApp.java
--------------------------
/* jcifs smb client library in Java
* Copyright (C) 2002 "Phan Kelvin"
* Modify to work with sun app server server 8
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.http;
import java.io.*;
import java.util.Enumeration;
import java.net.UnknownHostException;
import javax.servlet.*;
import javax.servlet.http.*;
import jcifs.*;
import jcifs.smb.SmbSession;
import jcifs.smb.NtlmPasswordAuthentication;
import jcifs.smb.SmbAuthException;
import jcifs.util.Base64;
import jcifs.netbios.NbtAddress;
import javax.security.auth.AuthPermission;
import javax.security.auth.Subject;
//must have sunapp library appser-rt.jar in classpath
import com.sun.web.security.WebPrincipal;
import com.sun.enterprise.security.SecurityContext;
import java.security.Principal;
import java.security.cert.X509Certificate;
/**
* This servlet Filter can be used to negotiate password hashes with
* MSIE clients using NTLM SSP. This is similar to <tt>Authentication:
* BASIC</tt> but weakly encrypted and without requiring the user to re-supply
* authentication credentials.
* <p>
* Read <a href="../../../ntlmhttpauth.html">jCIFS NTLM HTTP Authentication
and the Network Explorer Servlet</a> for complete details.
*/
public class NtlmHttpFilterSunApp implements Filter {
private String defaultDomain;
private String domainController;
private boolean loadBalance;
private boolean enableBasic;
private boolean insecureBasic;
private String realm;
public void init( FilterConfig filterConfig ) throws ServletException {
String name;
/* Set jcifs properties we know we want; soTimeout and cachePolicy to
10min.
*/
Config.setProperty( "jcifs.smb.client.soTimeout", "300000" );
Config.setProperty( "jcifs.netbios.cachePolicy", "600" );
Enumeration e = filterConfig.getInitParameterNames();
while( e.hasMoreElements() ) {
name = (String)e.nextElement();
if( name.startsWith( "jcifs." )) {
Config.setProperty( name, filterConfig.getInitParameter(
name ));
}
}
defaultDomain = Config.getProperty("jcifs.smb.client.domain");
domainController = Config.getProperty( "jcifs.http.domainController" );
if( domainController == null ) {
domainController = defaultDomain;
loadBalance = Config.getBoolean( "jcifs.http.loadBalance", true );
}
enableBasic = Boolean.valueOf(
Config.getProperty("jcifs.http.enableBasic")).booleanValue();
insecureBasic = Boolean.valueOf(
Config.getProperty("jcifs.http.insecureBasic")).booleanValue();
realm = Config.getProperty("jcifs.http.basicRealm");
if (realm == null) realm = "jCIFS";
}
public void destroy() {
}
public void doFilter( ServletRequest request,
ServletResponse response,
FilterChain chain ) throws IOException, ServletException {
HttpServletRequest req;
HttpServletResponse resp;
UniAddress dc;
String msg;
NtlmPasswordAuthentication ntlm = null;
req = (HttpServletRequest)request;
resp = (HttpServletResponse)response;
msg = req.getHeader( "Authorization" );
boolean offerBasic = enableBasic && (insecureBasic || req.isSecure());
if( msg != null && (msg.startsWith( "NTLM " ) ||
(offerBasic && msg.startsWith("Basic ")))) {
if( loadBalance ) {
dc = new UniAddress( NbtAddress.getByName( domainController,
0x1C, null ));
} else {
dc = UniAddress.getByName( domainController, true );
}
if (msg.startsWith("NTLM ")) {
req.getSession();
byte[] challenge = SmbSession.getChallenge( dc );
if(( ntlm = NtlmSsp.authenticate( req, resp, challenge )) ==
null ) {
return;
}
} else {
String auth = new String(Base64.decode(msg.substring(6)),
"US-ASCII");
int index = auth.indexOf(':');
String user = (index != -1) ? auth.substring(0, index) : auth;
String password = (index != -1) ? auth.substring(index + 1) :
"";
index = user.indexOf('\\');
if (index == -1) index = user.indexOf('/');
String domain = (index != -1) ? user.substring(0, index) :
defaultDomain;
user = (index != -1) ? user.substring(index + 1) : user;
ntlm = new NtlmPasswordAuthentication(domain, user, password);
}
try {
SmbSession.logon( dc, ntlm );
} catch( SmbAuthException sae ) {
if( sae.getNtStatus() == sae.NT_STATUS_ACCESS_VIOLATION ) {
/* Server challenge no longer valid for
* externally supplied password hashes.
*/
HttpSession ssn = req.getSession(false);
if (ssn != null) {
ssn.removeAttribute( "NtlmHttpAuth" );
}
}
resp.setHeader( "WWW-Authenticate", "NTLM" );
if (offerBasic) {
resp.addHeader( "WWW-Authenticate", "Basic realm=\"" +
realm + "\"");
}
resp.setStatus( HttpServletResponse.SC_UNAUTHORIZED );
resp.flushBuffer();
return;
}
HttpSession session = req.getSession();
session.setAttribute( "NtlmHttpAuth", ntlm );
String remoteUser = ntlm.getName().toUpperCase();
int index = remoteUser.indexOf("\\");
if(index >= 0){
String domain = remoteUser.substring(0, index);
String username = remoteUser.substring(index+1);
session.setAttribute("NTLM.RemoteUser", remoteUser);
session.setAttribute("NTLM.Username", username);
session.setAttribute("NTLM.Domain", domain);
}
} else {
HttpSession ssn = req.getSession(false);
if (ssn == null || (ntlm = (NtlmPasswordAuthentication)
ssn.getAttribute("NtlmHttpAuth")) == null) {
resp.setHeader( "WWW-Authenticate", "NTLM" );
if (offerBasic) {
resp.addHeader( "WWW-Authenticate", "Basic realm=\"" +
realm + "\"");
}
resp.setStatus( HttpServletResponse.SC_UNAUTHORIZED );
resp.flushBuffer();
return;
}
}
//becuase SUN APPSERVER 8 CAST PRINCIPAL TO WEBPRICIPAL,
//WE NEED TO CONVERT NTLM PRINCIPAL INTO WEBPRINCIPAL.
SecurityContext secContext = new SecurityContext(ntlm.getName(), new
Subject());
WebPrincipal webPrincipal = new WebPrincipal(ntlm.getName(),
ntlm.getPassword(), secContext);
chain.doFilter( new NtlmHttpServletRequest( req, webPrincipal ),
response );
}
// Added by cgross to work with weblogic 6.1.
public void setFilterConfig( FilterConfig f ) {
try {
init( f );
} catch( Exception e ) {
e.printStackTrace();
}
}
public FilterConfig getFilterConfig() {
return null;
}
}
More information about the jcifs
mailing list