加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

基于Xfire SOAP Header的WebService安全验证(xfire服务端,jax-

发布时间:2020-12-17 00:09:00 所属栏目:安全 来源:网络整理
导读:WebSerice是一种开放的web服务,任何人都可以访问,但我们有时候需要考虑只有付费用户才能使用WS,所以,我们就需要对WS加入安全验证机制,当然,可以利用防火墙的IP过滤,web应用的配置从最外层去隔离非法用户,但在内层,我们也可以使用SOAP Header的方式,

WebSerice是一种开放的web服务,任何人都可以访问,但我们有时候需要考虑只有付费用户才能使用WS,所以,我们就需要对WS加入安全验证机制,当然,可以利用防火墙的IP过滤,web应用的配置从最外层去隔离非法用户,但在内层,我们也可以使用SOAP Header的方式,由客户端发送验证数据,服务端验通过后基WS访问权限

首先根据我的这篇Blog

配置WS Server和WS Client,其中Client端的测试代码类名由Client改为ClientTest,因为我们要用到Xfire的一个名为Client的类?

?

首先我们编写服务端验证类继承AbstractHandler

?

package ?test;


import ?org.codehaus.xfire.MessageContext;

import ?org.codehaus.xfire.handler.AbstractHandler;

import ?org.jdom.Element;


public ? class ?AuthenticationHandler? extends ?AbstractHandler? {


????
public?void?invoke(MessageContext?cfx)?throws?Exception?{

???????????
if(cfx.getInMessage().getHeader()?==?null)

???????????
{

???????????????
throw?new?org.codehaus.xfire.fault.XFireFault("请求必须包含验证信息",org.codehaus.xfire.fault.XFireFault.SENDER);

???????????}

???????????Element?token
=cfx.getInMessage().getHeader().getChild("AuthenticationToken");

???????????
if?(token?==?null)?

???????????
{?

????????????
throw?new?org.codehaus.xfire.fault.XFireFault("请求必须包含身份验证信息",?org.codehaus.xfire.fault.XFireFault.SENDER);?

???????????}
?


??????????????String?username?
=?token.getChild("Username").getValue();?

??????????????String?password?
=?token.getChild("Password").getValue();?

??????????????
try?

??????????????
{?

??????????????????
//进行身份验证?,只有abcd@1234的用户为授权用户

?????????????????if(username.equals("abcd")?&&?password.equals("1234"))

??????????????????
//这语句不显示

??????????????????System.out.println("身份验证通过");

?????????????????
else?throw?new?Exception();

??????????????}
?

??????????????
catch?(Exception?e)?

??????????????
{?

??????????????????
throw?new???org.codehaus.xfire.fault.XFireFault("非法的用户名和密码",???org.codehaus.xfire.fault.XFireFault.SENDER);?

??????????????}
?


??????????}
?




}

?

xfire客户端实现身份

?

package ?test;


import ?org.codehaus.xfire.MessageContext;

import ?org.codehaus.xfire.handler.AbstractHandler;

import ?org.jdom.Element;


public ? class ?ClientAuthenticationHandler? extends ?AbstractHandler? {


?????
private?String?username?=?null;?


?????
private?String?password?=?null;?


?????
public?ClientAuthenticationHandler()?{?


?????}
?


?????
public?ClientAuthenticationHandler(String?username,String?password)?{?


?????????
this.username?=?username;?


?????????
this.password?=?password;?

?????}
?


?????
public?void?setUsername(String?username)?{?


?????????
this.username?=?username;?


?????}
?


?????
public?void?setPassword(String?password)?{?


?????????
this.password?=?password;?


?????}
?


?????
public?void?invoke(MessageContext?context)?throws?Exception?{?


?????????
//为SOAP?Header构造验证信息

?????????Element?el?=?new?Element("header");?

?????????context.getOutMessage().setHeader(el);?

?????????Element?auth?
=?new?Element("AuthenticationToken");?

?????????Element?username_el?
=?new?Element("Username");?

?????????username_el.addContent(username);?

?????????Element?password_el?
=?new?Element("Password");?

?????????password_el.addContent(password);?

?????????auth.addContent(username_el);?

?????????auth.addContent(password_el);?

?????????el.addContent(auth);?

?????}
?




}

为ClientTest.java加入以下代码

???????public static void main(String[] args) {
?? ??? ?WebsiteAuthentClient Website = new WebsiteAuthentClient();
?? ???? WebsiteAuthentPortType service = Website.getWebsiteAuthentHttpPort();
?? ????XFireProxy proxy = (XFireProxy)Proxy.getInvocationHandler(service);
????? Client client = proxy.getClient();
????? client.addOutHandler(new ClientAuthenticationHandler("abcd1","1234"));

?? ??? ?service.test("sdf");
?? ?}


等等,还没有完,修改Services.xm为WS绑定Handler

??

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



< beans >

< service? xmlns ="http://xfire.codehaus.org/config/1.0" >

< name > HelloService </ name >

< namespace > http://test/HelloService </ namespace >

< serviceClass > test.IHelloService </ serviceClass >

< implementationClass > test.HelloServiceImpl </ implementationClass >

?
< inHandlers > ?

?
< handler?? handlerClass? ="test.AuthenticationHandler" ? ></ handler? > ?

?
</ inHandlers >

</ service >

</ beans >


这样我们就完成了编码,下面启动tomcat,运行客户端代码,本文为abcd@1234位授权用户,使用abcd@1234,可以正常访问WS,如果用错误帐号,则会有以下异常

?

Exception?in?thread?"main"?org.codehaus.xfire.XFireRuntimeException:?Could?not?invoke?service..?Nested?exception?is?org.codehaus.xfire.fault.XFireFault:?非法的用户名和密码

org.codehaus.xfire.fault.XFireFault:?非法的用户名和密码

????at?org.codehaus.xfire.fault.Soap11FaultSerializer.readMessage(Soap11FaultSerializer.java:31)

????at?org.codehaus.xfire.fault.SoapFaultSerializer.readMessage(SoapFaultSerializer.java:28)

????at?org.codehaus.xfire.soap.handler.ReadHeadersHandler.checkForFault(ReadHeadersHandler.java:111)

????at?org.codehaus.xfire.soap.handler.ReadHeadersHandler.invoke(ReadHeadersHandler.java:67)

????at?org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131)

????at?org.codehaus.xfire.client.Client.onReceive(Client.java:406)

????at?org.codehaus.xfire.transport.http.HttpChannel.sendViaClient(HttpChannel.java:139)

????at?org.codehaus.xfire.transport.http.HttpChannel.send(HttpChannel.java:48)

????at?org.codehaus.xfire.handler.OutMessageSender.invoke(OutMessageSender.java:26)

????at?org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131)

????at?org.codehaus.xfire.client.Invocation.invoke(Invocation.java:79)

????at?org.codehaus.xfire.client.Invocation.invoke(Invocation.java:114)

????at?org.codehaus.xfire.client.Client.invoke(Client.java:336)

????at?org.codehaus.xfire.client.XFireProxy.handleRequest(XFireProxy.java:77)

????at?org.codehaus.xfire.client.XFireProxy.invoke(XFireProxy.java:57)

????at?$Proxy0.getUser(Unknown?Source)

????at?test.ClientTest.main(ClientTest.java:39)

?

如果不在CientTest加以下增加Heade则会有以下异常

?XFireProxy proxy = (XFireProxy)Proxy.getInvocationHandler(service);
Client client = proxy.getClient();
?client.addOutHandler(new ClientAuthenticationHandler("abcd1","1234"));


Exception?in?thread?"main"?org.codehaus.xfire.XFireRuntimeException:?Could?not?invoke?service..?Nested?exception?is?org.codehaus.xfire.fault.XFireFault:?请求必须包含验证信息

org.codehaus.xfire.fault.XFireFault:?请求必须包含验证信息

????at?org.codehaus.xfire.fault.Soap11FaultSerializer.readMessage(Soap11FaultSerializer.java:31)

????at?org.codehaus.xfire.fault.SoapFaultSerializer.readMessage(SoapFaultSerializer.java:28)

????at?org.codehaus.xfire.soap.handler.ReadHeadersHandler.checkForFault(ReadHeadersHandler.java:111)

????at?org.codehaus.xfire.soap.handler.ReadHeadersHandler.invoke(ReadHeadersHandler.java:67)

????at?org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131)

????at?org.codehaus.xfire.client.Client.onReceive(Client.java:406)

????at?org.codehaus.xfire.transport.http.HttpChannel.sendViaClient(HttpChannel.java:139)

????at?org.codehaus.xfire.transport.http.HttpChannel.send(HttpChannel.java:48)

????at?org.codehaus.xfire.handler.OutMessageSender.invoke(OutMessageSender.java:26)

????at?org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131)

????at?org.codehaus.xfire.client.Invocation.invoke(Invocation.java:79)

????at?org.codehaus.xfire.client.Invocation.invoke(Invocation.java:114)

????at?org.codehaus.xfire.client.Client.invoke(Client.java:336)

????at?org.codehaus.xfire.client.XFireProxy.handleRequest(XFireProxy.java:77)

????at?org.codehaus.xfire.client.XFireProxy.invoke(XFireProxy.java:57)

????at?$Proxy0.getUser(Unknown?Source)

????at?test.ClientTest.main(ClientTest.java:35)



jax-ws客户端实现身份

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.HandlerResolver;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.PortInfo;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

public class ClientMain {

	@SuppressWarnings("unchecked")
	public static void main(String[] args) {
		WebsiteAuthent wa = new WebsiteAuthent();
                wa .setHandlerResolver(new HandlerResolver() {
			public List<Handler> getHandlerChain(PortInfo portInfo) {
				List<Handler> list = new ArrayList<Handler>();
				list.add(new MySOAPHandler());
				return list;
			}
		});
		WebsiteAuthentPortType service = wa.getWebsiteAuthentHttpPort();
		System.out.println(service.test("sdf"));
	}
}

class MySOAPHandler implements SOAPHandler<SOAPMessageContext> {public Set<QName> getHeaders() { return null;}public void close(MessageContext context) {}public boolean handleFault(SOAPMessageContext context) {throw new UnsupportedOperationException("Not supported yet.");}public boolean handleMessage(SOAPMessageContext context) {Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);if (outboundProperty.booleanValue()) {SOAPMessage message = context.getMessage();try {SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();SOAPFactory factory = SOAPFactory.newInstance();SOAPElement authenticationToken = factory.createElement("AuthenticationToken");SOAPElement userName = factory.createElement("userName");userName.setValue("abcd");SOAPElement password = factory.createElement("password");password.setValue("1234");authenticationToken.addChildElement(userName);authenticationToken.addChildElement(password);SOAPHeader header = envelope.addHeader();header.addChildElement(authenticationToken);} catch (SOAPException e) {e.printStackTrace();}}return true;}}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读