spring ldap_Spring 3,Spring Web Services 2和LDAP安全

spring ldap

今年的开局很好,其中另一个“截止日期不会改变” /“跳过所有繁文tape节” / “狂野西部”类型的项目中,我必须弄清楚并使用相对而言实现一些功能。新的库和技术需要进行更改,Spring 3并不是新增功能,但是在Java 5,weblogic 10(.01)和Spring 2.5.6缓慢的企业环境中,这是相对的。

由于一般的时间限制,我在这篇文章中没有过多地介绍“ fluff”,只是使用多个XSD和LDAP安全性来创建和保护Spring 3和Spring WS 2 Web服务。

代码:

服务端点:ExampleServiceEndpoint
这是将在后面的配置中使用Web服务公开的类。

package javaitzen.spring.ws;import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
import org.springframework.ws.server.endpoint.annotation.RequestPayload;
import org.springframework.ws.server.endpoint.annotation.ResponsePayload;import javax.annotation.Resource;@Endpoint
public class ExampleServiceEndpoint {private static final String NAMESPACE_URI = "http://www.briandupreez.net";/*** Autowire a POJO to handle the business logic@Resource(name = "businessComponent")private ComponentInterface businessComponent;*/public ExampleServiceEndpoint() {System.out.println(">>  javaitzen.spring.ws.ExampleServiceEndpoint loaded.");}@PayloadRoot(localPart = "ProcessExample1Request", namespace = NAMESPACE_URI + "/example1")@ResponsePayloadpublic Example1Response processExample1Request(@RequestPayload final Example1 request) {System.out.println(">> process example request1 ran.");return new Example1Response();}@PayloadRoot(localPart = "ProcessExample2Request", namespace = NAMESPACE_URI + "/example2")@ResponsePayloadpublic Example2Response processExample2Request(@RequestPayload final Example2 request) {System.out.println(">> process example request2 ran.");return new Example2Response();}}

代码:CustomValidationCallbackHandler

这是我编写的用于扩展AbstactCallbackHandler的自定义代码,它允许我们使用LDAP。
根据下面的CallbackHandler中的注释,最好有一个缓存管理器,例如Hazelcast或Ehcache来缓存经过身份验证的用户,这取决于安全/性能方面的考虑。

下面的Digest Validator可以直接在Sun库中使用,我只是想了解它是如何工作的。

package javaitzen.spring.ws;import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
import com.sun.xml.wss.impl.callback.PasswordValidationCallback;
import com.sun.xml.wss.impl.misc.Base64;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.util.Assert;
import org.springframework.ws.soap.security.callback.AbstractCallbackHandler;import javax.security.auth.callback.Callback;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.util.Properties;public class CustomValidationCallbackHandler extends AbstractCallbackHandler implements InitializingBean {private Properties users = new Properties();private AuthenticationManager ldapAuthenticationManager;@Overrideprotected void handleInternal(final Callback callback) throws IOException, UnsupportedCallbackException {if (callback instanceof PasswordValidationCallback) {final PasswordValidationCallback passwordCallback = (PasswordValidationCallback) callback;if (passwordCallback.getRequest() instanceof PasswordValidationCallback.DigestPasswordRequest) {final PasswordValidationCallback.DigestPasswordRequest digestPasswordRequest =(PasswordValidationCallback.DigestPasswordRequest) passwordCallback.getRequest();final String password = users.getProperty(digestPasswordRequest.getUsername());digestPasswordRequest.setPassword(password);passwordCallback.setValidator(new CustomDigestPasswordValidator());}if (passwordCallback.getRequest() instanceof PasswordValidationCallback.PlainTextPasswordRequest) {passwordCallback.setValidator(new LDAPPlainTextPasswordValidator());}} else {throw new UnsupportedCallbackException(callback);}}/*** Digest Validator.* This code is directly from the sun class, I was just curious how it worked.*/private class CustomDigestPasswordValidator implements PasswordValidationCallback.PasswordValidator {public boolean validate(final PasswordValidationCallback.Request request) throws PasswordValidationCallback.PasswordValidationException {final PasswordValidationCallback.DigestPasswordRequest req = (PasswordValidationCallback.DigestPasswordRequest) request;final String passwd = req.getPassword();final String nonce = req.getNonce();final String created = req.getCreated();final String passwordDigest = req.getDigest();final String username = req.getUsername();if (null == passwd)return false;byte[] decodedNonce = null;if (null != nonce) {try {decodedNonce = Base64.decode(nonce);} catch (final Base64DecodingException bde) {throw new PasswordValidationCallback.PasswordValidationException(bde);}}String utf8String = "";if (created != null) {utf8String += created;}utf8String += passwd;final byte[] utf8Bytes;try {utf8Bytes = utf8String.getBytes("utf-8");} catch (final UnsupportedEncodingException uee) {throw new PasswordValidationCallback.PasswordValidationException(uee);}final byte[] bytesToHash;if (decodedNonce != null) {bytesToHash = new byte[utf8Bytes.length + decodedNonce.length];for (int i = 0; i < decodedNonce.length; i++)bytesToHash[i] = decodedNonce[i];for (int i = decodedNonce.length;i < utf8Bytes.length + decodedNonce.length;i++)bytesToHash[i] = utf8Bytes[i - decodedNonce.length];} else {bytesToHash = utf8Bytes;}final byte[] hash;try {final MessageDigest sha = MessageDigest.getInstance("SHA-1");hash = sha.digest(bytesToHash);} catch (final Exception e) {throw new PasswordValidationCallback.PasswordValidationException("Password Digest could not be created" + e);}return (passwordDigest.equals(Base64.encode(hash)));}}/*** LDAP Plain Text validator.*/private class LDAPPlainTextPasswordValidator implementsPasswordValidationCallback.PasswordValidator {/*** Validate the callback against the injected LDAP server.* Probably a good idea to have a cache manager - ehcache /  hazelcast injected to cache authenticated users.** @param request the callback request* @return true if login successful* @throws PasswordValidationCallback.PasswordValidationException**/public boolean validate(final PasswordValidationCallback.Request request) throws PasswordValidationCallback.PasswordValidationException {final PasswordValidationCallback.PlainTextPasswordRequest plainTextPasswordRequest =(PasswordValidationCallback.PlainTextPasswordRequest) request;final String username = plainTextPasswordRequest.getUsername();final Authentication authentication;final Authentication userPassAuth = new UsernamePasswordAuthenticationToken(username, plainTextPasswordRequest.getPassword());authentication = ldapAuthenticationManager.authenticate(userPassAuth);return authentication.isAuthenticated();}}/*** Assert users.** @throws Exception error*/public void afterPropertiesSet() throws Exception {Assert.notNull(users, "Users is required.");Assert.notNull(this.ldapAuthenticationManager, "A LDAP Authentication manager is required.");}/*** Sets the users to validate against. Property names are usernames, property values are passwords.** @param users the users*/public void setUsers(final Properties users) {this.users = users;}/*** The the authentication manager.** @param ldapAuthenticationManager the provider*/public void setLdapAuthenticationManager(final AuthenticationManager ldapAuthenticationManager) {this.ldapAuthenticationManager = ldapAuthenticationManager;}
}

服务配置:
端点,CallbackHandler和LDAP身份验证管理器的配置。
应用程序上下文–服务器端:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:sws="http://www.springframework.org/schema/web-services"xmlns:s="http://www.springframework.org/schema/security"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/web-serviceshttp://www.springframework.org/schema/web-services/web-services-2.0.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/securityhttp://www.springframework.org/schema/security/spring-security-3.0.xsd"><sws:annotation-driven/><context:component-scan base-package="javaitzen.spring.ws"/><sws:dynamic-wsdl id="exampleService"portTypeName="javaitzen.spring.ws.ExampleServiceEndpoint"locationUri="/exampleService/"targetNamespace="http://www.briandupreez.net/exampleService"><sws:xsd location="classpath:/xsd/Example1Request.xsd"/><sws:xsd location="classpath:/xsd/Example1Response.xsd"/><sws:xsd location="classpath:/xsd/Example2Request.xsd"/><sws:xsd location="classpath:/xsd/Example2Response.xsd"/></sws:dynamic-wsdl><sws:interceptors><bean id="validatingInterceptor"class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor"><property name="schema" value="classpath:/xsd/Example1Request.xsd"/><property name="validateRequest" value="true"/><property name="validateResponse" value="true"/></bean><bean id="loggingInterceptor"class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/><bean class="org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor"><property name="policyConfiguration" value="/WEB-INF/securityPolicy.xml"/><property name="callbackHandlers"><list><ref bean="callbackHandler"/></list></property></bean></sws:interceptors><bean id="callbackHandler" class="javaitzen.spring.ws.CustomValidationCallbackHandler"><property name="ldapAuthenticationManager" ref="authManager" /></bean><s:authentication-manager alias="authManager"><s:ldap-authentication-provideruser-search-filter="(uid={0})"user-search-base="ou=users"group-role-attribute="cn"role-prefix="ROLE_"></s:ldap-authentication-provider></s:authentication-manager><!-- Example... (inmemory apache ldap service) --><s:ldap-server id="contextSource" root="o=example" ldif="classpath:example.ldif"/><!--If you want to connect to a real LDAP server it would look more like:<s:ldap-server  id="contextSource" url="ldap://localhost:7001/o=example" manager-dn="uid=admin,ou=system" manager-password="secret"></s:ldap-server>--><bean id="marshallingPayloadMethodProcessor"class="org.springframework.ws.server.endpoint.adapter.method.MarshallingPayloadMethodProcessor"><constructor-arg ref="serviceMarshaller"/><constructor-arg ref="serviceMarshaller"/></bean><bean id="defaultMethodEndpointAdapter"class="org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter"><property name="methodArgumentResolvers"><list><ref bean="marshallingPayloadMethodProcessor"/></list></property><property name="methodReturnValueHandlers"><list><ref bean="marshallingPayloadMethodProcessor"/></list></property></bean><bean id="serviceMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"><property name="classesToBeBound"><list><value>javaitzen.spring.ws.Example1</value><value>javaitzen.spring.ws.Example1Response</value><value>javaitzen.spring.ws.Example2</value><value>javaitzen.spring.ws.Example2Response</value></list></property><property name="marshallerProperties"><map><entry key="jaxb.formatted.output"><value type="java.lang.Boolean">true</value></entry></map></property></bean></beans>

安全上下文–服务器端:

xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config"><xwss:RequireTimestamp maxClockSkew="60" timestampFreshnessLimit="300"/><!-- Expect plain text tokens from the client --><xwss:RequireUsernameToken passwordDigestRequired="false" nonceRequired="false"/><xwss:Timestamp/><!-- server side reply token --><xwss:UsernameToken name="server" password="server1" digestPassword="false" useNonce="false"/>
</xwss:SecurityConfiguration>

Web XML:
这里没有什么特别的,只是Spring WS MessageDispatcherServlet。

spring-wsorg.springframework.ws.transport.http.MessageDispatcherServlettransformWsdlLocationstrue1spring-ws/*

客户端配置:
要测试或使用该服务,您需要:
应用程序上下文–客户端测试:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/><bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate"><constructor-arg ref="messageFactory"/><property name="marshaller" ref="serviceMarshaller"/><property name="unmarshaller" ref="serviceMarshaller"/><property name="defaultUri" value="http://localhost:7001/example/spring-ws/exampleService"/><property name="interceptors"><list><ref local="xwsSecurityInterceptor"/></list></property></bean><bean id="xwsSecurityInterceptor"class="org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor"><property name="policyConfiguration" value="testSecurityPolicy.xml"/><property name="callbackHandlers"><list><ref bean="callbackHandler"/></list></property></bean><!--  As a client the username and password generated by the server must match with the client! --><!-- a simple callback handler to configure users and passwords with an in-memory Properties object. --><bean id="callbackHandler"class="org.springframework.ws.soap.security.xwss.callback.SimplePasswordValidationCallbackHandler"><property name="users"><props><prop key="server">server1</prop></props></property></bean><bean id="serviceMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"><property name="classesToBeBound"><list><value>javaitzen.spring.ws.Example1</value><value>javaitzen.spring.ws.Example1Response</value><value>javaitzen.spring.ws.Example2</value><value>javaitzen.spring.ws.Example2Response</value></list></property><property name="marshallerProperties"><map><entry key="jaxb.formatted.output"><value type="java.lang.Boolean">true</value></entry></map></property></bean>

安全上下文–客户端:

<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config"><xwss:RequireTimestamp maxClockSkew="60" timestampFreshnessLimit="300"/><!-- Expect a plain text reply from the server --><xwss:RequireUsernameToken passwordDigestRequired="false" nonceRequired="false"/><xwss:Timestamp/><!-- Client sending to server --><xwss:UsernameToken name="example" password="pass" digestPassword="false" useNonce="false"/>
</xwss:SecurityConfiguration>

与Java一样,在jar和版本方面可能会有一些细微差别,因此下面是我使用的pom的一部分。
依赖关系:

3.0.6.RELEASE2.0.2.RELEASEorg.apache.directory.serverapacheds-all1.5.5jarcompileorg.springframework.wsspring-ws-core${spring-ws-version}org.springframeworkspring-webmvc${spring-version}org.springframeworkspring-web${spring-version}org.springframeworkspring-context${spring-version}org.springframeworkspring-core${spring-version}org.springframeworkspring-beans${spring-version}org.springframeworkspring-oxm${spring-version}org.springframework.wsspring-ws-security${spring-ws-version}org.springframework.securityspring-security-core${spring-version}org.springframework.securityspring-security-ldap${spring-version}org.springframework.ldapspring-ldap-core1.3.0.RELEASEorg.apache.ws.securitywss4j1.5.12com.sun.xml.wssxws-security3.0org.apache.ws.commons.schemaXmlSchema1.4.2</project>

参考: Spring 3,Spring Web Services 2和LDAP安全。 来自我们的JCG合作伙伴   Zen博客中的Zen领域的 Brian Du Preez。


翻译自: https://www.javacodegeeks.com/2012/02/spring-3-spring-web-services-2-ldap.html

spring ldap

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/357118.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

转: 微博的多机房部署的实践(from infoq)

转: http://www.infoq.com/cn/articles/weibo-multi-idc-architecture 在国内网络环境下&#xff0c;单机房的可靠性无法满足大型互联网服务的要求&#xff0c;如机房掉电&#xff0c;光缆被挖的情况也发生过。微信就曾发生大面积故障&#xff0c;包括微信信息无法发出、无法刷…

知道这些性能优化手段,工资起码提升一倍

1.什么是性能?性能指标有哪些&#xff1f;计算机的性能&#xff0c;其实和我们干体力劳动很像&#xff0c;好比是我们要搬东西。对于计算机的性能&#xff0c;我们需要有个标准来衡量。这个标准中主要有两个指标。第一个是响应时间&#xff08;Response time&#xff09;或者叫…

JAX-RS和JSON-P集成

这篇简短的文章讨论了JAX-RS 2.0中对JSON-P的支持 JSON-P…&#xff1f; JSON处理API &#xff08;JSON-P&#xff09;是Java EE 7中引入的。 它提供了用于处理JSON数据的标准API&#xff0c;并且与XML对应的JAXP非常相似。 JSON-B &#xff08;JSON绑定&#xff09;API已在Ja…

亲手把360奇安信软件卸载了,爽!

由于工作原因&#xff0c;在上一家公司安装了360奇安信安全软件&#xff0c;到了下一个公司还需要安装另一个安全软件&#xff0c;这个必须要卸载&#xff0c;卸载&#xff01;卸载&#xff01;但是卸载需要输入密码&#xff0c;没有密码还输入卸载不了&#xff0c;我曾经联系3…

VM虚拟机中CentOS6.4操作系统安装一

在 VMware中鼠标单击“编辑虚拟机设置”&#xff0c;在弹出的“虚拟机设置”对话框中的“硬件”标签中选择“CD/DVD&#xff08;IDE&#xff09;”&#xff0c;然后在右侧的“CD /DVD&#xff08;IDE&#xff09;”连接选项中选择“使用ISO映像文件”&#xff0c;使用“浏览”按…

vue基础教程总结篇,用最短的时间入门vue.js(持续更新...)

目前&#xff0c;vue已经成为前端工程师必会的框架之一&#xff0c;这里简单总结一下&#xff0c;可以让您快速的入门vue,师傅带进门&#xff0c;修行靠个人&#xff0c;最主要的还是自己多动手&#xff0c;多实践&#xff0c;本专栏会持续更新。 1.vue安装教程及简介 2.vue计…

gcc代码反汇编查看内存分布[2]: arm-linux-gcc

arm-none-linux-gnueabi-gcc -v gcc version 4.4.1 (Sourcery G Lite 2010q1-202) 重点: 代码中的内存分配, 地址从低到高: 代码段(RO, 保存函数代码) --> 只读数据段(RO, 保存常量) --> 数据段(RW, 已初始化并且初始值不为0的全局变量和静态变量) -->bss段(RW, 未初…

关于SP一些响应码的API返回码及解析集合

在一些金融的行业&#xff08;银行、证券、保险等&#xff09;&#xff0c;如果接触了一些中间件&#xff0c;比如长城、恒银、广电等一些厂商的设备&#xff0c;不同的厂商有不同的一些规范&#xff0c;在应用开发的过程中难免会和中间件的错误码打交道&#xff0c;这里总结一…

eclipselink_Java EE 7的高峰– EclipseLink的多租户示例

eclipselink水族馆是有关所有相关规范和参考实现中有关Java EE进度的灵感和最新信息的重要来源。 他们从Oracle的Shaun Smith&#xff08; 博客 / 推特 &#xff09;获取了有关EclipseLink作为开源项目的地位和未来的演讲。 他介绍了将在EclipseLink 2.4中提供的所有新功能&…

我们的团队目标

我们的团队目标(WBS)&#xff1a; 完成一个规范的电脑应用程序&#xff0c;实现各个模块功能&#xff0c;让用户能够随时的存放自己的代码并且方便的提取到自己想要的代码进行查阅和修改。 团队项目的主要工作项目&#xff1a; 利用sql数据库和eclipse实现文件的存取查询。 个人…

关于一些常见智柜问题的分析及解决办法

竟然还有小伙伴感觉自研项目不好的小伙伴&#xff1f;渐渐感觉不管是在小公司或者在大公司&#xff0c;能有一个值得奋斗的远方就可以了&#xff0c;比如薪资高&#xff0c;钱多事少离家近&#xff0c;自己真的对自己目前做的事情感兴趣&#xff0c;否则干啥都感觉没劲&#xf…

流绩效–您的想法

上周&#xff0c;我介绍了一些有关Java 8流性能的基准测试结果。 你们和gal足够感兴趣&#xff0c;可以留下一些想法&#xff0c;还有哪些可以介绍。 这就是我所做的&#xff0c;这是结果。 总览 最后一篇文章的序言也适用于此。 阅读它&#xff0c;以找出所有数字为何撒谎&a…

java中JVM的原理

一、java虚拟机的生命周期&#xff1a; Java虚拟机的生命周期 一个运行中的Java虚拟机有着一个清晰的任务&#xff1a;执行Java程序。程序开始执行时他才运行&#xff0c;程序结束时他就停止。你在同一台机器上运行三个程序&#xff0c;就会有 三个运行中的Java虚拟机。 Java虚…

2022将至,前端程序员们应该一起放个烟花庆祝一下,走起

前言&#xff1a;小时候&#xff0c;在我印象中&#xff0c;每到快过年的时候就有很多卖炮仗的&#xff0c;一般也就是阳历的12月份到明年的正月15号卖炮仗的商家比较多&#xff0c;省下买辣条的钱去买炮仗&#xff0c;在老家也就过年和除夕两天及正月15日这几天放烟花和炮仗比…

微信红包封面开放平台序列号

微信红包封面开放平台是一款可以领取微信红包封面的平台&#xff0c;最近网上非常流行好玩的微信红包封面&#xff0c;每一种封面都极具特色&#xff0c;让你的微信红包与众不同&#xff0c;还可以定制专属的微信红包封面&#xff0c;不过名额有限&#xff0c;这边为大家带来这…

ios多线程 -- NSOperation 简介

NSOperation的作⽤&#xff1a;配合使用NSOperation和NSOperationQueue也能实现多线程编程 NSOperation和NSOperationQueue实现多线程的具体步骤&#xff1a; 1&#xff09;先将需要执行的操作封装到一个NSOperation对象中 2&#xff09;然后将NSOperation对象添加到NSOpera…

在没有复杂插件的情况下从Eclipse启动和调试Tomcat

像Eclipse这样的现代IDE提供了各种插件来简化Web开发。 但是&#xff0c;我相信将Tomcat作为“常规” Java应用程序启动仍然可以提供最佳的调试体验。 大多数时候&#xff0c;这是因为这些工具将Tomcat或任何其他servlet容器作为外部进程启动&#xff0c;然后在其上附加一个远程…

【javascript高级教程】JavaScript 对象

JavaScript 中的所有事物都是对象&#xff1a;字符串、数值、数组、函数...及自定义对象 JavaScript 提供多个内建对象&#xff0c;比如 String、Date、Array 等等。 对象只是带有属性和方法的特殊数据类型。 布尔型可以是一个对象。数字型可以是一个对象。字符串也可以是一个…

php 字符串函数

函数名描述实例输入输出trim()删除字符串两端的空格和其他预定义字符 $str"\r\nHello\r\n"; echo trim($str) 目标字符串 清除后的字符串 rtrim()/chop() 删除字符串右边的空格或其他预定义字符 ltrim() 删除字符串左边的空格或其他预定义字符 …

Lucene分析过程指南

本文是我们名为“ Apache Lucene基础知识 ”的学院课程的一部分。 在本课程中&#xff0c;您将了解Lucene。 您将了解为什么这样的库很重要&#xff0c;然后了解Lucene中搜索的工作方式。 此外&#xff0c;您将学习如何将Lucene Search集成到您自己的应用程序中&#xff0c;以…