jax-ws之webservice security(安全)教程第三天

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 前言: 在今天的学习中,我们讲开始过渡到一个真正的websecurity例子。 第二天中我们知道了如何使用handler来处理客户端提交上来的用户名与密码,而在今天的学习中,我们将会使用服务端预先配置的用户名与密码来authenticate客户端提交上来的值。

前言:

在今天的学习中,我们讲开始过渡到一个真正的websecurity例子。

第二天中我们知道了如何使用handler来处理客户端提交上来的用户名与密码,而在今天的学习中,我们将会使用服务端预先配置的用户名与密码来authenticate客户端提交上来的值。

相对于第二天的学习,如果客户端提交的用户名与密码输错,但还是能够与服务端建立http连接来说,第三天中的例子的安全性则更高,当客户端提交上来的用户名与密码错误则更本不可能和服务端建立起有效的http连接。该例子同时适用于一切J2EE AppServer,比如说:IBMWAS, ORACLE WEBLOGIC。

同时,通过该例子将讲述ws-security与相关的ws-policy进而一步步过渡到QoS。

一、配置服务端的相关角色

1.1 配置J2EE AppServer中的相关用户名与密码

打开tomcat下的cnof/tomcat-user.xml文件:

<?xml version='1.0' encoding='utf-8'?>

<tomcat-users>

  <role rolename="operator"/>

  <user username="tomcatws" password="123456" roles="operator"/>

</tomcat-users>

通过上述配置,我们可以知道我们在tomcat中增加了一个角色叫”operator”,同时配置了一个用户叫”tomcatws”密码为”123456”,该用户属于operator角色。

1.2 配置web应用中的相关安全角色

请打开你工程的web.xml文件,加入下述这段内容:

<security-role>

                   <description>Normal operator user</description>

                   <role-name>operator</role-name>

</security-role>

<security-constraint>

                   <web-resource-collection>

                            <web-resource-name>Operator Roles Security</web-resource-name>

                            <url-pattern>/AuthHelloService</url-pattern>

                   </web-resource-collection>

                   <auth-constraint>

                            <role-name>operator</role-name>

                   </auth-constraint>

                   <user-data-constraint>

                            <transport-guarantee>NONE</transport-guarantee>

                   </user-data-constraint>

</security-constraint>

<login-config>

                   <auth-method>BASIC</auth-method>

</login-config>

这边可以看到,我们把一个WebService的访问置于了web security的保护下,如果需要该问该web资源,服务端需要验证两部分内容:

1)      是否是合法group/role中的用户

2)      由于<auth-method>设置为basic,即客户端要访问相关的web资源时还需要提供用户名与密码

二、 开发我们的webservice

2.1 接口

package ctsjavacoe.ws.fromjava;

import javax.jws.WebMethod;

import javax.jws.WebService;

import javax.jws.soap.SOAPBinding;

import javax.jws.soap.SOAPBinding.Style;

@WebService

@SOAPBinding(style = Style.RPC)

public interface AuthHello {

         @WebMethod

         public String say(String name);

}

2.2 实现

package ctsjavacoe.ws.fromjava;

import javax.jws.WebService;

@WebService(endpointInterface = "ctsjavacoe.ws.fromjava.AuthHello")

public class AuthHelloImpl implements AuthHello {

         @Override

         public String say(String name) {

                   return "hello: " + name;

         }

}

该Web Service没有任何特殊的地方,也没有使用任何的handler,一切都交给了j2ee App容器去做认证

1.4 布署webservice

布署完后,我们访问:http://localhost:8080/JaxWSSample/AuthHelloService?wsdl

看看我们得到了什么:

OK,我们输入tomcatws,密码为123456

然后我们就得到正确的wsdl的输出了,接下来我们用客户端去连服务端。

三、书写客户端

package ctsjavacoe.ws.fromjava;

import javax.xml.namespace.QName;

import javax.xml.ws.Response;

import javax.xml.ws.BindingProvider;

import javax.xml.ws.Service;

import java.net.URL;

public class AuthHelloClient {

         private static final String WS_URL =

"file:D://wspace/JaxWSClient/wsdl/AuthHelloImplService.wsdl";

         private static final String S_URL =

"http://localhost:8080/JaxWSSample/AuthHelloService?wsdl";

         public static void main(String[] args) throws Exception {

                   URL url = new URL(WS_URL);

                   QName qname = new QName("http://fromjava.ws.ctsjavacoe/",

                                     "AuthHelloImplService");

                   Service service = Service.create(url, qname);

                   AuthHello port = service.getPort(AuthHello.class);

                   BindingProvider bp = (BindingProvider) port;

                   bp.getRequestContext().put(

BindingProvider.USERNAME_PROPERTY,

                                   "tomcatws");

                   bp.getRequestContext().put(

BindingProvider.PASSWORD_PROPERTY, "123456");

                   bp.getRequestContext().put(

BindingProvider.ENDPOINT_ADDRESS_PROPERTY,

                                   S_URL);

                   String rtnMessage = port.say("MK");

                   System.out.println("rtnMessage=====" + rtnMessage);

         }

}

关键语句我已经用红色标粗。

 

要点:

1)      根据wsdl create出来一个Service,这边需要一个wsdl,我们不可能用http://这样形式的wsdl,因为我们此时没有用户名和密码,如果我们使用的是http://这样形式的wsdl直接会抛“授权认证出错”,因此我们使用jax-ws在编译服务端时生成的本地wsdl

2)      使用BindingProvider输入用户名与密码,最后再使用BindingProvider输入真正的我们服务端的wsdl即:http://localhost:8080/JaxWSSample/AuthHelloService?wsdl

下面来看运行效果:

故意输错用户名与密码,我们输入:

bp.getRequestContext().put(

BindingProvider.USERNAME_PROPERTY,

                               "tomcatws");

bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "12345");

再来运行一下:

可以看到,如果用户名密码没有输对,根本无法通过认证,即连http连接都无法正确建立,这样我们的安全程度极大的提高了。

四、最终安全宝鉴

4.1 加装SSL通信

即实现服务端与客户端的HTTPS通信,这一般可以保证传输过程中你的soap报文不会被拦截

4.2 报文加密

我们的用户名与密码是嵌在soapheader中的,是以明文方式存在的,如果一旦被推截,将造成灾难性的结果,因此我们需要将我们的soap报文中header部分进行加密,这就是ws-security。

五、ws-security与wcf

且慢些加密我们的soap-header,要加密很简单,直接使用对称或者非对称算法把用户名密码加个密然后传输至服务端解密不就完了。

是,是可以这么做,但你有没有想过,如果你的客户端使用的是Java,服务端使用的是.net或者php怎么办?对方能用java api来解密吗?

这时,我们就要使用wcf了,一起来看,什么叫wcf.

5.1 wcf

Industry Standard WS-Security

Sun Microsystems and Microsoft jointly test Metro against WCF toensure that Sun web service clients (consumers) and web services (producers) doin fact interoperate with WCF web services applications and vice versa. Thistesting ensures that the following interoperability goals are realized:

l  Metro web services clients can access and consume WCF web services.

l  WCF web services clients can access and consume Metro web services.

Sun provides Metro on the Java platform and Microsoft provides WCFon the .NET 3.0 and .NET 3.5 platforms. The sections that follow describe theweb services specifications implemented by Sun Microsystems in Web ServicesInteroperability Technologies (WSIT) and provide high-level descriptions of howeach WSIT technology works.

这边出现了一个名词叫:Metro,这是一个基于JAXWS实现ws-security的标准框架,而Metro支持wcf协议。

现在知道我为什么让大家用jax-ws的意图了吧。

5.2 Metro

Metro支持的ws-security有以下几种:

ü  Username Authentication with Symmetric Key

ü  Username Authentication with Password Derived Keys

ü  Mutual Certificates Security

ü  Symmetric Binding with Kerberos Tokens

ü  Transport Security (SSL)

ü  Message Authentication over SSL

ü  SAML Authorization over SSL

ü  Endorsing Certificate

ü  SAML Sender Vouches with Certificates

ü  SAML Holder of Key

ü  STS Issued Token

ü  STS Issued Token with Service Certificate

ü  STS Issued Endorsing Token

真够多的啊,我们看第一种,就是我们说的基于用户名密码的ws-security,而且这个soap报文中的用户名与密码是被加密的。

5.3 QoS

要写符合WCF的webservice需要在webservice中引入QoS概念。

什么是QoS,从字面上理解就是qualityof service,它是一个很广的概念,它主要是把传统的一个webservice从架构上再分成7个部分,即你的webservice需要包含下面7个主要的方面:

ü  Availability

ü  Performance

ü  Reliability

ü  Regulatory

ü  Security

ü  Integrity

ü  Accessibility

QoS所处的位置:

看到这边大家头不要大,我们一起来看,到底怎么来实现QoS呢?

 

 

 

 

 

 

 

 

 

 

5.4 使用QoS中的security

我们使用QoS中的security来实现我们的soap报文的加密与传输,下面给出一个soap报文片段:

<?xml version="1.0" encoding="UTF-8"?>

<soapenv:Envelope xmlns:soapenv="..." xmlns:wsa="...">

<soapenv:Header>

<wsse:Security xmlns:wsse="..." soapenv:mustUnderstand="1">

<wsse:BinarySecurityToken xmlns:wsu=...>MIIBvT...BnesE0=</wsse:BinarySecurityToken>

<EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">

<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>

<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">

<wsse:SecurityTokenReference>

<wsse:KeyIdentifier EncodingType="..." ValueType="...">hS6nfYE9axFgay+gorMEo0I4GfY=

</wsse:KeyIdentifier>

</wsse:SecurityTokenReference>

</ds:KeyInfo>

<CipherData>

<CipherValue>OULe5mAxLwYibommo1Ui/...1gvtagYQ=</CipherValue>

</CipherData>


5.5 ws-policy

如何生成上面这个soap报文的呢?

此时,你的webservice需要引入一个policy描述,即ws-policy,下面给出一个policy的片段:

    <wsp:Policy wsu:Id="HelloPortBindingPolicy">

        <wsp:ExactlyOne>

            <wsp:All>

                <wsam:Addressing wsp:Optional="false"/>

                <sp:SymmetricBinding>

                    <wsp:Policy>

                        <sp:ProtectionToken>

                            <wsp:Policy>

                                <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never">

                                    <wsp:Policy>

                                        <sp:WssX509V3Token10/>

                                        <sp:RequireIssuerSerialReference/>

                                    </wsp:Policy>

                                </sp:X509Token>

                            </wsp:Policy>

                        </sp:ProtectionToken>

                        <sp:Layout>

                            <wsp:Policy>

                                <sp:Strict/>

                            </wsp:Policy>

                        </sp:Layout>

                        <sp:IncludeTimestamp/>

                        <sp:OnlySignEntireHeadersAndBody/>

                        <sp:AlgorithmSuite>

                            <wsp:Policy>

                                <sp:Basic128/>

                            </wsp:Policy>

                        </sp:AlgorithmSuite>

即,在布署webservice时,需要把空上policy和wsdl一起编译成带有QoS的webservice。

5.6 后话

在这个教程中,我不会带出从头至尾如何生成ws-policy和相应的带有QoS的Webservice以及相关的客户端。

因为大家如果把jax-ws的前五天基础教程看完后,加上我这后三天的教程,完全可以自己有能力去用Metro来自己实现相关的soap报文加密。

这属于非常easy的事,搞个2-3天就能实现。

同时,一般的项目,能够真正用到通过soap报文传递用户名与密码或者通过handler的,并不多,一般都是用http://login.do?username=xxx&pwd=xxx这种拍屁股的做法在传用户名与密码,顶多加个https了不得了。

如果当你碰到真正做到了带有QoS的webservice时,自己结合我这8天教程,自己搞一下Metro就能搞得定,实在不行了,再来找我。

最后,给大家推荐3样东西:

1.      Tomcat6扔了吧,用7了

2.      下载netbean7.0.1(其中自带tomcat7)

3.      使用glassfish3(支持J2EE6规范),一个缩小免费版的weblogic

如果你对QoS有兴趣,使用上述3样东西会简化你的学习过程。



目录
相关文章
|
移动开发 安全 网络安全
|
安全 数据安全/隐私保护 前端开发
WebService 简单安全验证
原文:WebService 简单安全验证         最近新接了一个需要调用第三方WebService的项目,看到这个第三方WebService被调用的时候,需要授权用户名和密码,于是自己也想对WebService的安全授权这个方面进行了一下研究,以前调用的WebService大部分都是局域网内部调用,几乎没有什么权限需要增加的,今天借此机会,深入研究了一下,发现实现起来还是挺容易的。
1481 0
|
Web App开发 存储 安全
使用WSE实现Web Service安全----我的第一篇
原文: 使用WSE实现Web Service安全----我的第一篇 WSE(Web Services Enhancements)是微软为了使开发者通过.NET创建出更强大,更好用的Web Services而推出功能增强插件。
1317 0
|
Java Maven 网络架构
简单的Jax-WS WebService实现
目录   1       定义Service 2       服务端发布Service 2.1      排除WebService中的某个方法 3       客户端访问Service 4       java2ws工具的使用 4.
986 0
|
Web App开发 安全 Shell
通向架构师的道路(第十四天)Axis2 Web Service安全之rampart
一、加密保护我们的web service传输 在上一天的教程中,我们讲了一个简单的基于” security-constraint”的以指定用户名和密码来保护一个Web Service以及如何用https对这个web service的通讯过程进行保护。
1168 0
|
Web App开发 安全 应用服务中间件
通向架构师的道路(第十三天)Axis2 Web Service安全初步
一、WSSecurity简述 安全的Web服务是Web服务成功的必要保证。但大家都知道,Web服务使用XML来进行数据交换,而XML在默认情况下是明文编码的;同时,大部分Web服务使用HTTP协议作为传输协议,同样,HTTP也是使用明文方式来传输数据的。
1164 0
|
安全 Java 网络架构
jax-ws之webservice security(安全)教程第一天
前言: 在前面的“5天学会jaxws-webservice教程”,我们讲了基本的jax-ws的使用。 Jax-ws是业界公认的标准的webservice,它已经成为了一个行业界标准,包括cxf,其实cxf也是调用的jax-ws为标准的基于spring的webservice框架。
1103 0
|
XML 安全 数据安全/隐私保护
jax-ws之webservice security(安全)教程第二天
前言: 第一天里说了如何用jax-ws去结合ssh框架。 在今天的教程中将会向大家详细讲述一个ws-security中的一个传统的”基于handler”来认证客户端传来的用户名密码的webservice. 客户端传过来一对用户名和密码,服务端进行认证。
1067 0
|
7月前
|
缓存 应用服务中间件 数据库
Python Web Service开发及优化
随着互联网的快速发展,Web服务已成为现代技术的核心。Python作为一种功能强大且易于学习的编程语言,在Web服务开发领域占据着重要地位。Python Web服务开发的重要性在于它能够提供高效、可扩展且易于维护的解决方案。本篇博客将探讨如何使用Python的Flask框架、Gunicorn WSGI服务器和Nginx网页服务器来实现高性能的Web服务。