- 浏览: 562467 次
- 性别:
- 来自: 长沙
文章分类
- 全部博客 (145)
- apache-struts (3)
- apache-shiro (4)
- apache-wicket (1)
- spring (34)
- spring-data-jpa (2)
- spring-mvc (20)
- spring-security (1)
- spring-webflow (1)
- hibernate (2)
- mongodb (1)
- ibatis (5)
- mysql (4)
- 开源组件 (18)
- java (3)
- maven (7)
- jBPM (1)
- EJB (1)
- JMS (2)
- servlet / jsp (9)
- javascript / jquery (10)
- 工作技巧 (12)
- ubuntu (6)
- bootstrap (10)
- javaee (1)
- 他山石 (7)
- jetbrick (1)
最新评论
-
yubao2008:
[size=x-small]为什么我也这样试了, 就是没有生效 ...
javax.servlet.http.HttpServletResponse 得到 status_code -
chenrl:
...
SpringMVC杂记(十五) spring-mvc controller 的切面 -
LONGTENGLONG:
你好,这样配置的,得到的集合为空,是什么原因?
apache-shiro杂记(一) 统计在线用户数目 -
xiafengfeiwu:
[flash=200,200][url]引用[/url][/f ...
apache-shiro 学习笔记 -
3108493554:
你好 ,有些问题想请教下,加下我qq310849354,你这上 ...
SpringMVC杂记(十二) 自定义Interceptor从Active Directory得到域信息
一)最近项目中要求实现Web应用的SSO(Single Sign On),即对于已经登录到Windows Domain中的用户,不需要输入用户名、密码而直接使用当前登录的Domain用户信息进行验证,如果验证成功则进入,否则拒绝进入。
参考了一下其他朋友的博客,大致了解了一下NTLM协议。
二) 我设计一个Interceptor,通过这个Interceptor的请求的session就会自然被设置上域名和用户名。
当然,不一定要用interceptor,servlet-filter一样可以实现同样的功能。spring-mvc用习惯了,还是interceptor顺手一些。
其中被注入的requestPredicate,是一个谓词,用来过滤一些请求,不满足的谓词要求的request会被忽略掉。如下面这个谓词用来判断Client是否已经在公司的域里了
三) 完成登录功能,登录还是由安全框架负责,如spring-security或apache-shiro
本文不赘述!
四) 开源软件jcifs的maven坐标
参考了一下其他朋友的博客,大致了解了一下NTLM协议。
二) 我设计一个Interceptor,通过这个Interceptor的请求的session就会自然被设置上域名和用户名。
<mvc:interceptor> <mvc:mapping path="/security/login"/> <bean class="ying.interceptor.ADUserInfoSetInterceptor"> <property name="domain" value="*.*.com" /> <property name="domainController" value="192.168.**" /> <!-- 域服务器ip --> <property name="requestPredicate"> <bean class="ying.function.InDomainPredicate" /> </property> </bean> </mvc:interceptor>
当然,不一定要用interceptor,servlet-filter一样可以实现同样的功能。spring-mvc用习惯了,还是interceptor顺手一些。
其中被注入的requestPredicate,是一个谓词,用来过滤一些请求,不满足的谓词要求的request会被忽略掉。如下面这个谓词用来判断Client是否已经在公司的域里了
package ying.function; import java.io.IOException; import java.io.InputStreamReader; import java.io.LineNumberReader; import javax.servlet.http.HttpServletRequest; import org.apache.commons.collections.Predicate; import org.apache.commons.lang.StringUtils; public class InDomainPredicate implements Predicate { @Override public boolean evaluate(Object object) { if (! (object instanceof HttpServletRequest)) { return false; } HttpServletRequest request = (HttpServletRequest) object; String ip = request.getRemoteHost(); if ("127.0.0.1".equals(ip) || "localhost".equals(ip)) { return false; } try { Process p = Runtime.getRuntime().exec(String.format("nbtstat -A %s", ip)); InputStreamReader ir = new InputStreamReader(p.getInputStream()); LineNumberReader input = new LineNumberReader(ir); String workstation = null; String domain = null; int k = 0; for (int i = 1; i < 20; i++) { String str = StringUtils.defaultIfEmpty((input.readLine()), ""); if (str.indexOf("<00>") != -1) { if (StringUtils.isEmpty(workstation)) { workstation = str.substring(0, str.indexOf("<00>")).trim(); k = i; } if (StringUtils.isEmpty(domain) && (k > 0 && (i == k + 1))) { domain = str.substring(0, str.indexOf("<00>")).trim(); } } } return (workstation.startsWith("ZT") && workstation.contains("-") && "ZTGAME".equals(domain)); } catch (IOException e) { return false; } } }
package ying.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import jcifs.Config; import jcifs.UniAddress; import jcifs.ntlmssp.Type1Message; import jcifs.ntlmssp.Type2Message; import jcifs.ntlmssp.Type3Message; import jcifs.smb.SmbSession; import jcifs.util.Base64; import org.apache.commons.collections.Predicate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.util.Assert; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; public class ADUserInfoSetInterceptor extends HandlerInterceptorAdapter implements InitializingBean { private static final Logger LOGGER = LoggerFactory.getLogger(ADUserInfoSetInterceptor.class); private String domainController = null; private String domain = null; private String useExtendedSecurity = "false"; private String lmCompatibility = "0"; private String cachePolicy = "1200"; private String soTimeout = "1800000"; private Predicate requestPredicate; private String domainAttributeName = "domainAttributeName"; private String nameAttributeName = "nameAttributeName"; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (requestPredicate != null && ! requestPredicate.evaluate(request)) { LOGGER.debug("requestPredicate.evaluate(request) == false"); return true; } UniAddress dc = null; String msg = request.getHeader("Authorization"); if (msg != null && msg.startsWith("NTLM ")) { byte[] src = Base64.decode(msg.substring(5)); dc = UniAddress.getByName(domainController, true); byte[] challenge = SmbSession.getChallenge(dc); if (src[8] == 1) { Type1Message type1 = new Type1Message(src); Type2Message type2 = new Type2Message(type1, challenge, null); msg = Base64.encode(type2.toByteArray()); if (response != null) { response.setHeader("WWW-Authenticate", "NTLM " + msg); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setContentLength(0); response.flushBuffer(); LOGGER.debug("C <-- S 401 Unauthorized WWW-Authenticate: NTLM <base64-encoded type-2-message>"); return false; } } else if (src[8] == 3) { Type3Message type3 = new Type3Message(src); byte[] lmResponse = type3.getLMResponse(); if (lmResponse == null) lmResponse = new byte[0]; byte[] ntResponse = type3.getNTResponse(); if (ntResponse == null) ntResponse = new byte[0]; request.getSession(true).setAttribute(this.nameAttributeName, type3.getUser()); request.getSession(true).setAttribute(this.domainAttributeName, type3.getDomain()); LOGGER.debug("C --> S GET ... Authorization: NTLM <base64-encoded type-3-message>"); } } else { response.setHeader("WWW-Authenticate", "NTLM"); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setContentLength(0); response.flushBuffer(); LOGGER.debug("C <-- S 401 Unauthorized"); return false; } return true; } private void init() { Config.setProperty("jcifs.smb.client.soTimeout", getSoTimeout()); Config.setProperty("jcifs.netbios.cachePolicy", getCachePolicy()); Config.setProperty("jcifs.smb.lmCompatibility", getLmCompatibility()); Config.setProperty("jcifs.smb.client.useExtendedSecurity", getUseExtendedSecurity()); Config.setProperty("jcifs.http.domainController", getDomainController()); Config.setProperty("jcifs.smb.client.domain", getDomain()); } @Override public void afterPropertiesSet() throws Exception { Assert.notNull(domain); Assert.notNull(domainController); init(); } // --------------------------------------------------------------------------------------------- // getter and setter // 为了节约版面不写了 }
三) 完成登录功能,登录还是由安全框架负责,如spring-security或apache-shiro
本文不赘述!
四) 开源软件jcifs的maven坐标
<dependency> <groupId>jcifs</groupId> <artifactId>jcifs</artifactId> <version>1.3.17</version> </dependency>
评论
1 楼
3108493554
2016-03-18
你好 ,有些问题想请教下,加下我qq310849354,你这上面的代码是ntlm验证成功就跳转到项目的主页,验证失败就跳到项目的登录页面是吗?
发表评论
-
SpringMVC杂记(十八) ServletRequestAttributes的应用
2014-02-28 12:38 14212看了一下SpringMVC的源代码,原来SpringMVC也提 ... -
SpringMVC杂记(十七) HandlerMethodArgumentResolver接口应用example
2014-01-24 15:29 12198自从spring3.1 开始就有了这个接口,可以为@Reque ... -
SpringWebflow杂记(一) 框架初探,与SpringMVC的集成
2013-10-23 17:18 1711今日研究了一下SpringWebFlow这个项目,作为Spri ... -
SpringMVC杂记(十六) spring-mvc 与 openid4java
2013-10-12 15:25 3869SpringMVC杂记(十六) spring-mvc 与 op ... -
SpringMVC杂记(十五) spring-mvc controller 的切面
2013-08-01 19:42 6134SpringMVC杂记(十五) spring-mvc cont ... -
Spring集成CXF
2013-06-24 15:53 1569Spring集成CXF 零) jar依赖 <dep ... -
SpringMVC杂记(十四) Ajax方式的JSR303认证
2013-06-13 07:29 4520自己定义一个Exception,用来表示数据绑定失败 im ... -
SpringMVC杂记(十三) 使用FreeMarker作为视图层
2013-06-09 11:55 3398实在没什么好说的,直接上配置文件好了 <bean i ... -
通过spring,javamail,和freemarker集成发送HTML方式的电子邮件
2013-05-30 14:02 4870一) 现在项目中用的javamail和org.springfr ... -
SpringMVC杂记(十一) 使用Excel视图
2013-04-06 16:06 6623SpringMVC杂记(十一) 使用Excel视图 一) 其 ... -
Spring集成junit
2012-12-24 10:43 1502package junit; import org. ... -
BootstrapPlugin - daterangepicker 使用笔记
2012-11-13 12:17 21073BootstrapPlugin - daterangepick ... -
SpringMVC杂记(十) 验证码生成
2012-11-06 10:18 2783以前写过一篇关于这个的博客,现在用SpringMVC了,重写一 ... -
SpringMVC杂记(九) 模拟其他类型(非GET,POST)的请求
2012-10-22 10:49 26901) 以前一个小兄弟问我,SpringMVC是否可以使用很多浏 ... -
SpringMVC杂记(八) 使用阿里巴巴的fastjson
2012-07-21 08:27 102691) 国产开源软件要支持的 <dependency& ... -
ActiveMQ学习笔记(二) JMS与Spring
2012-06-24 10:21 7425上文可见,JMS Native API使用起来不是特别方便。好 ... -
我的SpringSecurity实践
2012-04-08 07:49 8978我的SpringSecurity实践 (一) 数据库与实体类 ... -
SpringMVC杂记(七) Jackson与Hibernate LazyLoding无法正常工作解决办法
2012-03-21 13:35 7054SpringMVC杂记(七) Jackson与Hibernat ... -
SpringMVC杂记(六) 下载文件
2012-03-21 09:04 4278SpringMVC杂记(六) 下载文件 1) jar依赖 ... -
SpringMVC杂记(五) JSR303数据验证
2012-03-16 16:30 12434SpringMVC杂记(五) JSR303数据验证 1) 首 ...
相关推荐
在这个名为"springmvc-login-interceptor"的项目中,我们关注的核心是Spring MVC的拦截器(Interceptor)功能,它允许开发者在请求被控制器处理之前或之后执行自定义逻辑。拦截器在实际应用中常用于权限验证、日志...
SpringMVC+Shiro自定义过滤器的实现代码 itle"springmvc+shiro自定义过滤器的实现代码"所涉及的知识点如下: 1. SpringMVC拦截器 在SpringMVC中,拦截器(Interceptor)是一种特殊的Bean,它可以在请求处理之前、...
在Spring MVC框架中,Interceptor(拦截器)是一个强大的工具,用于在请求被控制器处理之前或之后执行特定的逻辑。它们可以用来实现通用的功能,如权限验证、日志记录、性能统计等,避免在每个控制器方法中重复编写...
- **拦截器(Interceptor)**:自定义拦截器可以实现全局的功能,比如权限验证、日志记录、性能统计等。通过实现HandlerInterceptor接口并将其注册到SpringMVC配置中,即可在请求处理前后执行自定义逻辑。 - **...
在进行web项目的开发时,如果时间让用户自己输入,该怎么处理,SpringMVC的转换器可以处理,但是需要自己定义,如何定义和搭配呢?
在本篇《SpringMVC杂记(五) JSR303数据验证》中,我们将深入探讨SpringMVC框架如何集成并使用JSR303(JavaBeans Validation)来进行数据验证,这是一种强大的验证机制,可以确保应用程序接收到的数据是合法且符合...
在本篇博文中,我们将深入探讨SpringMVC框架中的向导型Controller的实现,这是SpringMVC 3.1.1版本的一个重要特性。向导型Controller通常用于处理多步骤的用户交互流程,如购物车结账、用户注册等,它能够引导用户...
本示例聚焦于如何通过自定义注解来获取用户登录信息,以增强应用的安全性和用户体验。下面将详细阐述这个过程中的关键知识点。 1. **Spring MVC与Spring Boot简介** Spring MVC是Spring框架的一个模块,专门用于...
以Maven构建的聚合项目,使用SpringMVC+Mybatis框架,基于JSP Tag技术的分页标签,详细说明见: http://blog.csdn.net/autfish/article/details/52023143
单图片上传到本地,编辑框回显, 多图片上传 回显。springmvc整合完成项目 详情 https://blog.csdn.net/m0_37946870/article/details/79913803
本文抛砖引玉,并没有详细的介绍更全面的内容,通过一个例子让初次使用的人能够快速入门,简单的介绍一下。 第一,注解: @Before – 目标
例如,我们可以创建一个自定义的ViewResolver实现,重写`resolveViewName`方法,该方法接受视图名和本地化信息作为参数,然后根据视图名返回相应的视图实例。视图实例可以是任何形式的,如FreeMarker模板、Thymeleaf...
自定义拦截器是扩展Spring MVC功能、添加自定义行为的一种常见方式。以下是对自定义拦截器实现步骤的详细解释: ### 1. 自定义拦截器类 #### 1.1 继承 `HandlerInterceptorAdapter` 你可以选择继承`...
在SpringMVC框架中,拦截器(Interceptor)是一种强大的机制,它可以用来在请求处理之前、之后或处理过程中执行额外的逻辑。自定义拦截器允许开发者根据业务需求进行更精细的控制,例如权限验证、日志记录、性能统计...
SpringMVC 的拦截器(Interceptor)允许在请求处理前后执行自定义逻辑,例如登录检查、日志记录、性能监控等。拦截器通过 HandlerInterceptor 接口实现。 九、数据绑定与验证 SpringMVC 提供了自动的数据绑定功能,...
在Spring MVC框架中,拦截器(Interceptor)是一个强大的工具,它允许我们在请求处理前后执行自定义逻辑,如权限检查、日志记录、性能监控等。本文将深入探讨如何使用注解来自定义Spring MVC的拦截器。 首先,...
SpringMVC DispatcherServlet重写、自定义拦截器拦截器源码
【标题】"fengchao111-springmvc-interceptor-master" 是一个关于Spring MVC拦截器(Interceptor)的开源项目。Spring MVC是Spring框架的一部分,专门用于构建Web应用程序,而拦截器则是在请求被控制器处理之前或...
本项目“Spring+SpringMvc+MybatisPlus+Aop(自定义注解)动态切换数据源”正是针对这一需求提供的一种解决方案。下面将详细介绍这个项目中的关键技术点和实现原理。 首先,Spring框架是Java企业级应用开发的核心...
springMvc中的自定义捕获异常 必须在spring.xml文件中注释mvc:default-servlet-handler / 在DispatcherServlet中重写noHandlerFound方法,将重定向到sx.java上的/ demo / notFound路径和定义找不到请求。 方法