Spring 3,Spring Web Services 2和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

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

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

相关文章

vue 日期选择器默认时间_vue-datepicker

vue-datepicker基于 Vue 的日期/时间选择组件。安装NodeJS 环境 (commonjs)npm i hyjiacan/vue-datepicker或者yarn add hyjiacan/vue-datepicker可以通过以下方式获取最新的代码git clone https://github.com/hyjiacan/vue-datepicker.git源码仓库浏览器环境 (umd)Since 2.4.0…

easyUI validate函数【总结篇-部分转】

以下是自己总结和修改别人的帖子和资源整理出来的一些常用验证函数&#xff0c;备用&#xff0c;交流。 <body>邮箱验证&#xff1a;<input type"text" validtype"email" required"true" missingMessage"不能为空" invalidMe…

CSDN挑战编程——《金色十月线上编程比赛第一题:小女孩数数》

金色十月线上编程比赛第一题&#xff1a;小女孩数数 题目详情: 【金色十月线上编程比赛规则】 一个小女孩正在用左手手指数数&#xff0c;从1数到n。她从拇指算作1开始数起&#xff0c;然后&#xff0c;食指为2&#xff0c;中指为3&#xff0c;无名指为4&#xff0c;小指为5。…

ubuntu 安装完成后的工作

以安装 ubuntu 15.10 为例 1. 备份并更改源 1 cd /etc/apt 2 sudo cp source.list source.list.bak 3 sudo vi source.list 删除所有内容并增加其他源&#xff08;用vi删除所有内容&#xff0c;命令行下gg移动光标至文件头&#xff0c;dG删除光标后所有内容&#xff09; 阿里云…

Morphia和MongoDB:不断发展的文档结构

在上一篇有关Morphia的文章中 &#xff0c;我介绍了一些典型用法&#xff0c;并提到了一些已知问题的警告和解决方法。 我展示了使用Morphia多么容易&#xff0c;以及它与Java世界的交互方式。 为了跟进该帖子&#xff0c;我将讨论如何处理一些现实生活中的需求&#xff1a;处理…

angular 点菜_Vue2与Angular5实现无人点餐、无人收银系统项目实战视频教程【组合套餐】(大地)...

Vue2实现无人点餐、无人收银系统项目实战视频教程详情地址&#xff1a;Angular5实现无人点餐、无人收银系统项目实战视频教程详情地址&#xff1a;教程介绍&#xff1a;Vue2与Angular5实现无人点餐、无人收银系统项目实战视频教程【组合套餐】是由大地老师倾情录制的最新Vue2与…

CSDN挑战编程——《金色十月线上编程比赛第二题:解密》

金色十月线上编程比赛第二题&#xff1a;解密 题目详情: 小强是一名学生&#xff0c; 同时他也是一个黑客。 考试结束后不久&#xff0c;他惊讶的发现自己的高等数学科目居然挂了&#xff0c;于是他果断入侵了学校教务部网站。在入侵的过程中&#xff0c;他发现了与成绩相关的…

iOS学习心得——UITableViewCell的复用

UITableView是在iOS开发中最常用的控件之一。我的第一篇学习心得献给它了UITableView是由一行一行的UITableViewCell构成的。首先想这样一个问题&#xff1a;现在用UITableView去做一个联系人列表&#xff0c;如果我有10个100个联系人&#xff0c;那我可以建10个100 个UITab…

Java EE 7的高峰–使用EclipseLink的多租户示例

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

vscode中如何拉取git代码_使用VSCode如何从github拉取项目的实现

使用VSCode如何从github拉取项目的实现最近使用vscode进行前端编程&#xff0c;遇到一些问题网上说明的不是很明显&#xff0c;故记录一下1.开vscode使用CTRL或者点击查看到集成终端打开控制终端到此这篇关于使用VSCode如何从github拉取项目的实现的文章就介绍到这了,更多相关V…

matlab求导

在matlab中求导要进行符号运算。 >>syms x; >>y x^cos(x); >>ydot diff(y, x, 1);%对x求一阶导数 ydot x^(cos(x) - 1)*cos(x) - x^cos(x)*log(x)*sin(x) >> y2dot diff(y, x, 2)%求二阶导数&#xff0c;求n阶导数同理。 y2dot cos(x)*(x…

带有Java和Axis2的JSON Web服务

我最近遇到一位客户&#xff0c;要求我使用Java Web服务重建其旧产品。 他们希望它模块化并且易于使用。 我想到的第一件事是使用宁静的方法。 但是让我烦恼的是&#xff0c;Java宁静的方法是使用XML !&#xff0c;我更喜欢一种更简单的通信方式&#xff0c;易于理解和解析的数…

Kosaraju算法 有向图的强连通分量

有向图的强连通分量即&#xff0c;在有向图G中&#xff0c;如果两个顶点间至少存在一条路径&#xff0c;称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通&#xff0c;称G是一个强连通图。非强连通图有向图的极大强连通子图&#xff0c;称为强连通分量(…

监管大屏系统_工厂大屏可视化管控系统,智慧工厂平台是什么,工厂管理大屏软件 - 帆软...

智慧工厂大屏可视化管控系统&#xff0c;不但注重显示数据显示信息能力&#xff0c;还要兼具监管的作用&#xff0c;配合时代新兴的大屏技术&#xff0c;早已成为精益生产工厂的必备产品。本文权威介绍智慧工厂大屏可视化管控系统是什么&#xff0c;以及3款主流软件&#xff0c…

图像二维离散傅里叶变换、幅度谱、相位谱

clear, clc I imread(...);F fftshift(fft2(I)); % 对图像进行二维 DFT(fft2)&#xff0c;并移至中心位置 magn log(abs(F)); % 加 log 是便于显示&#xff0c;缩小值域 phase log(angle(F)*180/pi); % 转换为度数…

详解CSS选择器、优先级与匹配原理

选择器种类 严格来讲&#xff0c;选择器的种类可以分为三种&#xff1a;标签名选择器、类选择器和ID选择器。而所谓的后代选择器和群组选择器只不过是对前三种选择器的扩展应用。而在标签内写入style""的方式&#xff0c;应该是CSS的一种引入方式&#xff0c;而不是选…

关于299$的企业开发者账号的申请流程

299$的企业开发者账号 Apple Developer Enterprise Program•一年1988人民币 - 企业 (Apple Developer Enterprise Program)- 公司应在邓白氏注册并拥有有效的 DUNS 号码。&#xff0d;此计划使开发者能够开发针对 Apple 设备的应用程式&#xff0c;并对其员工进行发布&#xf…

keras 多层lstm_tensorflow-如何在keras中堆叠多个lstm?

DanielAdiwardana的答案的详细说明。我们需要为除最后一层之外的所有LSTM层添加return_sequences True。将此标志设置为True可让Keras知道LSTM输出应包含所有历史生成的输出以及时间戳(3D)。 因此&#xff0c;下一个LSTM层可以进一步处理数据。如果此标志为假&#xff0c;则LS…

Java堆空间– JRockit和IBM VM

本文将为您提供JRockit Java堆空间与HotSpot VM的概述。 它还将为您提供有关JRockit和HotSpot的Oracle未来计划的一些背景知识。 Oracle JRockit VM Java堆&#xff1a;2个不同的内存空间 -Java堆&#xff08;YoungGen和OldGen&#xff09; -本机内存空间&#xff08;类池&am…

如何搭建lamp(CentOS7+Apache+MySQL+PHP)环境 [转]

在网上搜资料,自己在本地虚拟机上尝试搭建,弄了整整一天一夜,终于弄好了.网上的资料,虽然很多,但大多都是重复的,拿去试了之后,又很多都不能得到正确的结果.最终找到了适合我的linux环境的搭建方式;在这里贴出来:Install Apache, PHP And MySQL On CentOS 7 (LAMP)度娘真不给力…