jcifs包实现域认证的单点登录带来了个奇怪的问题



先简述一下系统使用的技术,框架是struts1.2,action继承LookupDispatchAction,页面的验证使用validation,应用服务器为jboss4.2
问题描述:
在web.xml配置文件中配置了实现域登录的Servlet后出现如下问题:
点击系统的“增加”按钮弹出的页面中的“保存”按钮无法调用action中对应的方法;
“修改”按钮弹出页面的“保存”则出现如下错误
WARN [RequestProcessor] Unhandled Exception thrown: classjavax.servlet.ServletException
INFO [[/]] Request[/doc/docmanagedetailaction] does not contain handlerparameter named 'act'. This may be caused by whitespace in the label text.

jsp页面中的“保存”按钮代码
<html:submit styleClass="button" property="act"onclick="return chkpagecount();">
<bean:message key="button.save" />
</html:submit>


实现域登录的Java文件(http://www.jcifs.com/可以下载相应的jar包)
/**
* 本java文件来自于jcifs.http.NtlmHttpFilter.java
*/

@SuppressWarnings({"serial","unused"})
public class ADServlet extends HttpServlet {

private static LogStream log = LogStream.getInstance();

private String defaultDomain;

private String domainController;

private boolean loadBalance;

private boolean enableBasic;

private boolean insecureBasic;

private String realm;

private Map map;

/**

* Initialize this servlet.

*

* @exception ServletException

* if we cannot configure ourselves correctly

*/

public void init(ServletConfig config) throws ServletException {

map=new HashMap();

Config.setProperty("jcifs.smb.client.soTimeout","1800000");

Config.setProperty("jcifs.netbios.cachePolicy","1200");

Config.setProperty("jcifs.smb.lmCompatibility","0");

Config.setProperty("jcifs.smb.client.useExtendedSecurity","false");

Enumeration e = config.getInitParameterNames();

do {

if (!e.hasMoreElements()) {

break;

}

String name = (String) e.nextElement();

if (name.startsWith("jcifs.")) {

Config.setProperty(name, config.getInitParameter(name));

}

} while (true);

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";

}

int level;

if ((level = Config.getInt("jcifs.util.loglevel", -1)) != -1){

LogStream.setLevel(level);

}

LogStream _tmp = log;

if (LogStream.level > 2) {

try {

Config.store(log, "JCIFS PROPERTIES");

} catch (IOException ioe) {



}

}

}



public void doGet(HttpServletRequest request, HttpServletResponseresponse)

throws IOException, ServletException {

NtlmPasswordAuthentication ntlm;

try{

if ((ntlm = negotiate(request, response, false)) == null) {



return;

} else {

String uuname=(String)map.get("adremoteuser");

System.out.println("\t\t域登陆用户名:"+uuname);

uuname=uuname.substring(uuname.indexOf("\\")+1,uuname.length());response.sendRedirect(request.getContextPath()+"/loginaction.do?act=login&companycode=test&username="+uuname+"&password=***");

return;

}

}catch (Exception e) {

e.printStackTrace();

}

}



public void doPost(HttpServletRequest request, HttpServletResponseresponse)

throws IOException, ServletException {

doGet(request, response);

}

public void destroy() {

map=null;

}



protected NtlmPasswordAuthentication negotiate(HttpServletRequest req,HttpServletResponse resp,

boolean skipAuthentication) throws IOException, ServletException {

NtlmPasswordAuthentication ntlm = null;

String msg = req.getHeader("Authorization");

boolean offerBasic = enableBasic && (insecureBasic ||req.isSecure());

if (msg != null && (msg.startsWith("NTLM ") ||offerBasic && msg.startsWith("Basic "))) {

UniAddress dc;

if (msg.startsWith("NTLM ")) {

HttpSession ssn = req.getSession();

byte challenge[];

if (loadBalance) {

NtlmChallenge chal = (NtlmChallenge) ssn.getAttribute("NtlmHttpChal");

if (chal == null) {

chal = SmbSession.getChallengeForDomain();

ssn.setAttribute("NtlmHttpChal", chal);

}

dc = chal.dc;

challenge = chal.challenge;

} else {

dc = UniAddress.getByName(domainController, true);

challenge = SmbSession.getChallenge(dc);

}

if ((ntlm = NtlmSsp.authenticate(req, resp, challenge)) == null) {

return null;

}

ssn.removeAttribute("NtlmHttpChal");

} else {

String auth = new String(Base64.decode(msg.substring(6)),"US-ASCII");

int index = auth.indexOf(':');

String user = index == -1 ? auth : auth.substring(0, index);

String password = index == -1 ? "" : auth.substring(index +1);

index = user.indexOf('\\');

if (index == -1) {

index = user.indexOf('/');

}

String domain = index == -1 ? defaultDomain : user.substring(0,index);

user = index == -1 ? user : user.substring(index + 1);

ntlm = new NtlmPasswordAuthentication(domain, user, password);

dc = UniAddress.getByName(domainController, true);

}

map.put("adremoteuser", ntlm.getName());

try {

SmbSession.logon(dc, ntlm);

LogStream _tmp = log;

if (LogStream.level > 2) {

log.println("NtlmHttpFilter: " + ntlm + " successfullyauthenticated against " + dc);

}

} catch (SmbAuthException sae) {

LogStream _tmp1 = log;

if (LogStream.level > 1) {

log.println("NtlmHttpFilter: " + ntlm.getName() + ":0x" + Hexdump.toHexString(sae.getNtStatus(), 8) + ": " + sae);

}

SmbAuthException _tmp2 = sae;

if (sae.getNtStatus() == 0xc0000005) {

HttpSession ssn = req.getSession(false);

if (ssn != null) {

ssn.removeAttribute("NtlmHttpAuth");

}

}

resp.setHeader("WWW-Authenticate", "NTLM");

if (offerBasic) {

resp.addHeader("WWW-Authenticate", "Basicrealm=\"" + realm + "\"");

}

resp.setStatus(401);

resp.setContentLength(0);

resp.flushBuffer();

return null;

}

req.getSession().setAttribute("NtlmHttpAuth", ntlm);

} else if (!skipAuthentication) {

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", "Basicrealm=\"" + realm + "\"");

}

resp.setStatus(401);

resp.setContentLength(0);

resp.flushBuffer();

return null;

}

}

return ntlm;

}

}

Web.Xml中配置
<servlet>
<servlet-name>myadservlet</servlet-name>
<servlet-class>com. company.test.ADServlet</servlet-class>
<init-param>
<param-name>jcifs.http.domainController</param-name>
<param-value>172.16.2.101</param-value>
</init-param>
<init-param>
<param-name>jcifs.netbios.wins</param-name>
<param-value>172.16.2.101,172.16.2.105</param-value>
</init-param>
<init-param>
<param-name>jcifs.smb.client.domain</param-name>
<param-value>dns. company.net.cn</param-value>
</init-param>
<init-param>
<param-name>jcifs.smb.client.soTimeout</param-name>
<param-value>18000</param-value>
</init-param>
<init-param>
<param-name>jcifs.netbios.cachePolicy</param-name>
<param-value>1200</param-value>
</init-param>
<init-param>
<param-name>jcifs.util.loglevel</param-name>
<param-value>0</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>

若要解决此问题,从客户端,使用注册表编辑器 (Regedt32.exe) 将值添加到以下注册表项:
HKEY_CURRENT_USER/软件/microsoft/windows/CurrentVersion/internet设置 /
注意上面的注册表项是一个路径,它经过了折行以提高可读性。

添加以下注册表值:
值名称: DisableNTLMPreAuth
数据类型: REG_DWORD
值: 1
除了注册表项还需要关闭 Internet Explorer 中 启用集成 Windows 身份验证。 若要这样做,请按照下列步骤操作:
启动 Internet Explorer。
单击 工具,请单击 Internet 选项,然后单击 高级 选项卡。
在 安全,下单击以取消选择 启用集成 Windows 身份验证 (需要重启动),然后单击 应用。
关闭 Internet Explorer。
若要解决此问题,从服务器端,配置网站以使用下列身份验证方法之一:
若要允许匿名访问仅网站进行配置。
配置为允许匿名访问和 NLTM 身份验证 (集成 Windows 身份验证) 的网站

你可能感兴趣的:(单点登录)