需求说明
局方所有人的电脑都在一个域中管理,员工通过域账号和密码登录他的计算机之后,在登录应用系统之后不再需要做登入操作,直接进入系统;
实现方法
通过查询资料,JCIFS可以实现域单点登入,实现原理可以查看这个链接:
http://www.cnblogs.com/adylee/articles/975213.html
实现方法也比较简单,步骤如下:
1.jcifs官网http://jcifs.samba.org/下载最新jar包
2.配置过滤器
<filter>
<filter-name>NtlmHttpFilter</filter-name>
<filter-class>jcifs.http.NtlmHttpFilter</filter-class>
<init-param>
<param-name>jcifs.http.domainController</param-name>
<param-value>10.45.40.222</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>NtlmHttpFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
由于我只要通过JCIFS获取客户端的系统用户,并没有通过JCIFS登入AD验证用户(用户登入的时候已经验证了),所有这里配的参数就一个。
3.修改过滤器NtlmHttpFilter的代码,去掉AD登入
protected NtlmPasswordAuthentication negotiate(HttpServletRequest req, HttpServletResponse resp,
boolean skipAuthentication) throws IOException, ServletException {
UniAddress dc;
String msg;
NtlmPasswordAuthentication ntlm = null;
msg = req.getHeader("Authorization");
boolean offerBasic = enableBasic && (insecureBasic || req.isSecure());
logger.info("NtlmHttpFilter negotiate msg:" + msg);
logger.info("NtlmHttpFilter negotiate offerBasic:" + offerBasic);
if (msg != null && (msg.startsWith("NTLM ") || (offerBasic && msg.startsWith("Basic ")))) {
if (msg.startsWith("NTLM ")) {
HttpSession ssn = req.getSession();
byte[] challenge;
logger.info("NtlmHttpFilter negotiate loadBalance:" + loadBalance);
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;
}
/* negotiation complete, remove the challenge object */
ssn.removeAttribute("NtlmHttpChal");
} 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);
dc = UniAddress.getByName(domainController, true);
}
/*
* try { logger.info(
* "NtlmHttpFilter SmbSession logon....ntlm.getName():"
* +ntlm==null?null:ntlm.getName()); SmbSession.logon( dc, ntlm );
*
* if( log.level > 2 ) { logger.info( "NtlmHttpFilter: " + ntlm +
* " successfully authenticated against " + dc ); } logger.info(
* "NtlmHttpFilter SmbSession logon successfully...."); }
* catch(SmbException sae ) { logger.info(
* "NtlmHttpFilter SmbSession logon error....msg:"+ntlm.getName()+
* " auth error:"+sae.getMessage());
*
* if( log.level > 1 ) { logger.info( "NtlmHttpFilter: " +
* ntlm.getName() + ": 0x" + jcifs.util.Hexdump.toHexString(
* sae.getNtStatus(), 8 ) + ": " + sae ); } if( sae.getNtStatus() ==
* SmbAuthException.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 + "\""); }
* if(showDlg){ resp.setStatus( HttpServletResponse.SC_UNAUTHORIZED
* ); resp.setContentLength(0); Marcel Feb-15-2005
* resp.flushBuffer(); }
*
*
* return null; } req.getSession().setAttribute( "NtlmHttpAuth",
* ntlm );
*/
} else {
if (!skipAuthentication) {
HttpSession ssn1 = req.getSession(false);
if (ssn1 == null || (ntlm = (NtlmPasswordAuthentication) ssn1.getAttribute("NtlmHttpAuth")) == null) {
resp.setHeader("WWW-Authenticate", "NTLM");
if (offerBasic) {
resp.addHeader("WWW-Authenticate", "Basic realm=\"" + realm + "\"");
}
resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
resp.setContentLength(0);
resp.flushBuffer();
return null;
}
}
}
return ntlm;
}
完成以上几步,就可以通过request.getUserPrincipal();获取客户端系统用户名了。
在项目中,把过滤器整合进去,虽然实现了需求,但是遇到个问题。
加了这个过滤器后,之后的所有请求都会发多次,查看附件图片
这个也能理解,因为JCIFS实现的原理就是在请求的头文件加Authorization。这样每次请求都需要验证一次。那么问题就来了,由于框架是通过request.getInputStream获取请求参数再做分析,而http发送的验证请求body是为空,导致后面的程序报错。就不得不再后面的解析中判断一下输入流是否为空,再做处理。
我就想能不能怎么控制HTTP只在发登入请求的时候才发验证请求,其他的请求就不要用了。
想办法删掉headers中的Authorization参数,查找资料只有
response.setHeader("WWW-Authenticate","NTLM"");却没有移除这个参数的方法。。
求大神们指点一二
- 描述: 每个请求发多次
- 大小: 96.7 KB
分享到:
相关推荐
Fluent电弧,激光,熔滴一体模拟。 UDF包括高斯旋转体热源、双椭球热源(未使用)、VOF梯度计算、反冲压力、磁场力、表面张力,以及熔滴过渡所需的熔滴速度场、熔滴温度场和熔滴VOF。
基于协同过滤算法商品推荐系统.zip
锂电池半自动带电液舱标准手套箱(sw16可编辑+工程图)全套技术资料100%好用.zip
这是一款基于jQuery实现的经典扫雷小游戏源码,玩家根据游戏规则进行游戏,末尾再在确定的地雷位置单击右键安插上小红旗即可赢得游戏!是一款非常经典的jQuery游戏代码。本源码改进了获胜之后的读数暂停功能。另外建议用户使用支持HTML5与css3效果较好的火狐或谷歌等浏览器预览本源码,可以看到地图的远景拉伸效果。
Android studio 健康管理系统期末大作业App源码
校园表白墙网站源码、表白墙网站制作、网页表白墙源码 效果演示https://www.hybiaobai.cn/ 校园表白墙网站源码、表白墙网站制作、网页表白墙源码
In the video, a person stands alone in a snowy night, holding a delicate wine cup, with a desolate expression. The snowflakes are falling gently, and the person seems lost in deep thoughts and memories. They take a few steps, as if trying to follow the wind, with a sense of yearning and melancholy. The background shows an ancient Chinese-style house with eaves covered in snow, adding to the lonely and nostalgic atmosphere. The person's movements are slow and graceful, reflecting the complex emot
①软件 程序 网站开发路面附着系数估计,采用UKF和EKF两种算法。 软件为Matlab Simulink,非Carsim联合仿真。 dugoff轮胎模块:纯simulink搭非代码 整车模块:7自由度整车模型 估计模块:无迹卡尔曼滤波,扩展卡尔曼滤波,均是simulink现成模块应用无需S-function 带有相关文献和估计说明
基于Spring Boot的在线考试系统--论文.zip
内容概要:本文介绍了一种新方法,用于识别仅由轮廓表示的部分遮挡物体。该方法通过对拐点检测来创建对象的近似多边形形状描述符,并采用一种简单易实施的匹配算法。描述符能够对噪声和部分遮挡保持较好的鲁棒性,在计算机视觉应用中尤其有效。研究涉及多种测试,涵盖人工数据、现实世界图像及不同条件下的变化(如加性高斯噪声、部分遮挡等),展示了良好的效果以及相较于同类方法的优势。 适用人群:从事计算机视觉相关工作的科研人员及技术人员。 使用场景及目标:适用于需要自动化的部分遮挡目标检测和匹配的各种应用场景,尤其是在机器学习项目中涉及光学字符识别等领域。通过使用该算法可以提高复杂环境中物体匹配的成功率,增强系统鲁棒性和适应范围。 其他说明:作者还讨论了关于边界表示法的一些优缺点并提出未来改进方向,例如自动生成迭代次数及引入新的层级化匹配策略。此外,文中提到的所有实验均在标准条件下进行,但当应用于实际环境中时可能需要额外调整参数以达到最佳性能。
【Python】基于Python的美篇高清图片爬虫
node-v14.17.5-x64 msi安装包
ie8 升级到ie11 离线安装包 先安装补丁,再安装ie,某个补丁安装不上就跳过,先安装其他补丁,再回来安装。最后能装IE11就可以了
Title: 《设计与实现基于JavaWeb的校园兼职信息平台——毕业设计/课程设计》 项目概述 本项目是一款针对校园环境的兼职信息平台,旨在为学生提供寻找兼职工作的机会,同时为企业提供一个发布兼职信息的平台。该平台采用JavaWeb技术,结合SSM(Spring, SpringMVC, MyBatis)框架开发,专注于解决学生兼职信息不对称的问题。 功能模块 兼职信息发布:企业用户可以发布兼职信息,包括职位描述、要求、薪资等。 兼职信息浏览:学生用户可以浏览兼职信息,并根据条件筛选合适的兼职。 评论与反馈:用户可以对兼职信息和雇主进行评论和反馈。 用户管理:包括学生和企业用户的注册、登录、信息修改等。 消息通知:系统会向用户推送相关的兼职信息和评论通知。 项目特色 评论功能(Comment Part-time):学生可以对企业发布的兼职进行评价,帮助其他学生更好地选择兼职。 信息审核:确保兼职信息的真实性和有效性。 用户互动:提供私信功能,方便学生与企业之间的沟通。 项目目标 帮助学生更快地找到合适的兼职工作。 为企业提供高效的人才招聘渠道。 增强校园内的就业服务和信息交流。 开发流
基于springboot的应急救援物资管理系统.zip
内容概要:本文档详细讲解了利用 Python 和 python-telegram-bot 库创建一个简易但实用性强的 Telegram 接口的方法。主要内容涵盖了从配置所需环境(如安装相关库)、编写登录验证逻辑,到实现获取好友列表和实施即时通信(聊天)等功能的具体代码演示及解释。文中还提供了关于用户认证的基本方法、简单用户数据模拟、基本的日志记录方式,以及启动机器人并维持监听状态的操作指导,最后提醒开发者替换成自己的 bot token 并指出了一些安全方面的考量,比如严格验证用户输入以保障应用程序的安全性。 适合人群:对于有兴趣探索社交平台集成或是初次接触即时通讯软件自动化构建,尤其是想基于 Python 来快速搭建一个 Telegram Bot 的初学者或是拥有基础编程经验的人士来说非常适合。 使用场景及目标:适用于想要快速建立个人或者小团队之间的信息交流渠道,测试和熟悉 Telegram Bot API 的工作机制,以及进一步理解和提升在社交平台上自动化工具开发技能的情况。这有助于加深理解 API 调用流程、异步消息传输机制等相关知识点,同时也可以作为更大规模项目的基础模块之一来考虑扩展。 其他说明:本指南侧重于理论联系实际的应用层面教学,不仅提供了完整的代码案例让读者可以亲手操作,还强调了良好编码习惯的重要性(像添加适当的注释),并且提及到了未来可能遇到的技术挑战——例如用户数据的真实保存与维护(推荐采用数据库解决方案)。这对于提高读者的实际动手能力和激发更多自主思考都起到了积极作用。
手搓人工神经网络的教程。在CSDN文章中也有,但CSDN文章排版略有偏差,因此附上pdf文档
回旋提升式柔性链输送机sw16可编辑全套技术资料100%好用.zip
视觉点胶+伺服打螺丝+压装+电测试生产线x_t全套技术资料100%好用.zip
调试过可以运行。 开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包:Maven3.3.9