您的位置:首页 > 编程语言 > Java开发

Invoke WCF service from Java Client with Authentication (X.509 Certificate) Java 客户端调用WCF服务 需要安全验证

2009-03-23 06:12 816 查看
最近很多朋友都在问我怎样从java客户端调用带安全验证的WCF服务。当初我解决这个问题的时候查了很多文献和资料,虽说webservice是号称跨平台的吧,可是真跨起来,有时也挺麻烦。现在我把它总结下来,希望能对大家有所帮助。

因为当时给公司(ParagalloMobileAS)写解决方案的时候就是用的英文,所以还是英文的。同时我配了demo代码,相信大家可以看明白。如果有什么不明白的地方,可以给我留言。

Summary:

WeuseMessage-LevelSecurity
authenticatingwithwsHttpBinding.Andtheuseralsoneedsausername/password.
X.509Certificateisusedhere.
ThisarticletalksabouthowtocallWCF
servicefromthejavaclientwithauthentication.TheserversideuseX.509
certificatetoencrypttheUsernameandPassword.Thejavaclienttoolis
NetbeansandEclipsewithSoapUIplug-ininstalled.

Contents
Invoke
WCFservicefromJavaClientwithAuthentication(X.509Certificate)1
Summary:1
1.PreparetheCertificate:1
1.1.CreateaCertificatetoActasYourRootCertificate
Authority.1
1.2.InstallYourRootCertificateAuthorityCertificate
ontheServerandClientMachines2
1.3.CreateandInstallYourTemporaryService
Certificate.2
2.CreateaDemoWCFService.2
2.1.Newademowcfservice.2
2.2.CreateCustomerValidator2
2.3.theServerconfigfile.3
3.CalltheServiceFromJavaClient4
3.1CreatetheJavaclient,thecontainerisGlassfish.4
3.2CreatetheJavaApplicationclient,thecontaineris
notGlassfish.9
3.3DevelopmenttheJavaclientcodeinEclipse.11
4.DownloadDemos12
Reference.12

1.PreparetheCertificate:

Weneedtocreateaself-signedroot
certificateauthority(CA)thatwillbeplacedintheTrustedRoot
CertificationAuthoritystore(受信任的根证书颁发机构).ThecertificateusedbyWCFisthencreatedfromtheroot
self-signedcertificateandinstalledintheLocalMachinestore.

1.1.CreateaCertificatetoAct
asYourRootCertificateAuthority

Command:
makecert-n
"CN=RootCATest"-r-svRootCATest.pvkRootCATest.cer

In
thiscommand:

-n–SpecifiesthesubjectnamefortherootCA.Theconventionisto
prefixthesubjectnamewith"CN="for"CommonName".
-r–Specifiesthatthecertificatewillbeself-signed.
-sv–Specifiesthefilethatcontainstheprivatekeyofthe
certificate.
RootCATest.cer–Specifiesthenameofthe
filecontainingthepublickeyofthecertificate.

Inthe
CreatePrivateKeyPassword
dialogbox,enterapassword,confirmthe
password,andthenclickOK.Optionally,youcanclickNonewithoutentering
thepassword,butthisisnotrecommendedforsecurityreasons.
Inthe
EnterPrivateKeyPassword
dialogbox,enterthepasswordagainandthen
clickOK.
Thisisthepasswordneededtoaccessthe
privatekeyfileRootCATest.pvkinordertogeneratethefileRootCATest.cer
containingthepublickey.

1.2.InstallYourRootCertificate
AuthorityCertificateontheServerandClientMachines

Inthisstep,youwillinstallthe
certificateintheTrustedRootCertificationAuthorities(受信任的根证书颁发机构)locationonboththe
serverandclientmachines.Allcertificatesthataresignedwiththis
certificatewillbetrustedbytheclientmachine.
Youcandothisbyrunmmccommand,thendoitinMicrosoft
ManagementConsole
.ImporttheCertificatetoTrustedRoot
CertificationAuthorities
(受信任的根证书颁发机构).

1.3.CreateandInstallYour
TemporaryServiceCertificate

Command:makecert-skMyKeyName-ivRootCATest.pvk-n
"CN=tempCert"-icRootCATest.cer-srlocalmachine-ssmy-skyexchange
-petempCert.cer

IntheEnterPrivateKeyPassword
dialogbox,enterthepasswordfortherootCAprivatekeyfilespecifiedinSTEP
1,andthenclickOK.

2.CreateaDemoWCFService

2.1.Newademowcfservice

2.2.CreateCustomerValidator

ClassMyCustomValidatorbyinheritingUserNamePasswordValidator,butthis
shouldbecreatedinanewclasslibraryproject.

usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Text; usingSystem.IdentityModel.Selectors; usingSystem.IdentityModel.Tokens; namespaceServerWcfService.CustomValidators { publicclassMyCustomValidator:UserNamePasswordValidator { publicoverridevoidValidate(stringuserName,stringpassword) { if(string.IsNullOrEmpty(userName)) thrownewArgumentNullException("userName"); if(string.IsNullOrEmpty(password)) thrownewArgumentNullException("password"); if(userName!="xiaozhuang"||password!="123456") thrownewSecurityTokenException("Errorusernameorpassword"); } } }

2.3.theServerconfigfile

<system.serviceModel>
<bindings>

<
wsHttpBinding>

<bindingname="mySecureBinding">
<securitymode="Message">
<messageclientCredentialType="UserName"/>
</security>
</binding>

</
wsHttpBinding>


</
bindings>
<services>
<servicebehaviorConfiguration="ServerWcfService.Services.MySimpleServiceBehavior"name="ServerWcfService.Services.MySimpleService">
<endpointaddress=""binding="wsHttpBinding"contract="ServerWcfService.ServiceContracts.IMySimpleService"bindingConfiguration="mySecureBinding">
<identity>
<dnsvalue="MyServerCert"/>
</identity>
</endpoint>
<endpointaddress="mex"binding="mexHttpBinding"contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behaviorname="ServerWcfService.Services.MySimpleServiceBehavior">
<serviceMetadatahttpGetEnabled="true"/>
<serviceDebugincludeExceptionDetailInFaults="false"/>
<serviceCredentials>
<serviceCertificatefindValue="MyServerCert"x509FindType="FindBySubjectName"storeLocation="LocalMachine"storeName="My"/>
<userNameAuthenticationuserNamePasswordValidationMode="Custom"customUserNamePasswordValidatorType="ServerWcfService.CustomValidators.MyCustomValidator,ServerWcfService"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>

TheconfigfilesettheclientCredentialTypeinthe
<bindings>sectionandsetthebindingConfiguration
in<endpoint>section.WesetserviceCredentials
todoanauthenticationbyCertificateandusernameauthentication.

3.CalltheServiceFromJava
Client

YoucanuseWebServicesInteroperability
Technologies(WSIT)doaccesstheWCFServicefromjavaclient.Andthiswasintegrated
inNetBeansV6.1.

3.1CreatetheJavaclient,the
containerisGlassfish

HeretheIDEisNetbeans,myversionis
6.1.
1
NewaWebproject

2
addanewwebserviceclient.

3
importtheservercerttothestore“TrustStore”

Thisthecommand,youmustinstallJDKif
youwantuseit.
keytool-import-fileMyServer.cer-keystoreTrustStore-aliasserverkey
theimportfileMyServer.ceristheserver'sX.509
certificate,serverkeyisthealiasofthecertificate.Andyouwillneedto
inputakeystorepasswordafteryouexecutethiscommand.Pleaserememberyour
password.Thekeystorefilewillinthecurrentforderwhereyoudothis
command.
keytool-list
-v-keystoreTrustStore
usingthiscommandtoseeiftheimporting
issuccessful.
Note:ifyoudon'tdothis,itwillthrow
anexception“WSS1511:AnErroroccurredwhilelocatingPEEREntitycertificate
inTrustStore.”.
4
EditWebServiceattributes


You
canEdititbyrightclickthewebservice



thenyoucaneditthesecurityattribute,
pleaseclicktheTrustStorebutton:



Youcanchooseyourtruststorewhichyou
importtheserverCertatstep3bybrowse.pleasechangetheFileofTypeto
allfiles.aftethisinputthepasswordofthekeystore.AndtheCert'salias.



Afterthisyouwillgettwoconfigfileinfolder“SourcePackages”ofNetbeans.ThetwofilesareMySimpleService.svc.xmlandwsit-client.xml.PleaseedittheMySimpleService.svc.xml.

Example:

<wsp:Policywsu:Id="WSHttpBinding_IMySimpleServicePolicy">

<wsp:ExactlyOne>

<wsp:All>

<sc:TrustStorewspp:visibility="private"peeralias="mykey"storepass="1302821986"type="JKS"location="C:/DocumentsandSettings/Marvion/TrustStore"/>

</wsp:All>

</wsp:ExactlyOne>

</wsp:Policy>

Note:thetypeis“JKS”.


5.
NewaTestServlet.

Addthefollowingcodetotheservlet.


protectedvoidprocessRequest(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
response.setContentType("text/html;charset=UTF-8");
PrintWriterout=response.getWriter();
org.tempuri.MySimpleServiceclient;
org.tempuri.IMySimpleServiceport;
try{
client=newMySimpleService();
port=client.getWSHttpBindingIMySimpleService();
((BindingProvider)port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY,"xiaozhuang");
((BindingProvider)port).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY,"123456");
Stringtest=port.printMessage("HelloWorld!");
//TODOoutputyourpagehere
out.println("<html>");
out.println("<head>");
out.println("<title>ServletNewServlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>ServletNewServletat"+request.getContextPath()+"</h1>");
out.println("<h1>"+test+"</h1>");
out.println("</body>");
out.println("</html>");
}finally{
out.close();
}
}


Note:theboldcodeistoputtheusername
andpassword.Pleasewritethisbeforeyoucallamethod.

Itestsuccessfully.



3.2CreatetheJavaApplicationclient,
thecontainerisnotGlassfish

It'sverysamelikeaboveconfiguration.
Butifyouarerunningonsomeothercontainerthentheonlywayforyouisto
supplyyourownCallbackHandler:
Theconfigfile:
<wsp:Policy
wsu:Id="WSHttpBinding_IMySimpleServicePolicy">

<wsp:ExactlyOne>

<wsp:All>
<sc:CallbackHandlerConfiguration
xmlns:sc="http://schemas.sun.com/2006/03/wss/client">
<sc:CallbackHandler
name="TrustStoreCallbackHandler"
classname="javaapplication1.TrustStoreCallbackHandler"/>
</sc:CallbackHandlerConfiguration>

</wsp:All>

</wsp:ExactlyOne>

</wsp:Policy>
Theclass-nameisthefullnameofyourown
callbackhandlerclass.

Example:

packagejavaapplication1;
importcom.sun.xml.wss.impl.callback.KeyStoreCallback;
importjava.io.FileInputStream;
importjava.io.IOException;
importjava.io.InputStream;
importjava.security.KeyStore;
importjava.security.KeyStoreException;
importjava.security.NoSuchAlgorithmException;
importjava.security.cert.CertificateException;
importjava.util.Iterator;
importjava.util.Map;
importjava.util.logging.Level;
importjava.util.logging.Logger;
importjavax.security.auth.callback.Callback;
importjavax.security.auth.callback.CallbackHandler;
importjavax.security.auth.callback.UnsupportedCallbackException;
publicclassTrustStoreCallbackHandlerimplementsCallbackHandler{
KeyStorekeyStore=null;
Stringpassword="1302821986";
publicTrustStoreCallbackHandler(){
System.out.println("TruststoreCBH.CTORCalled..........");
InputStreamis=null;
try{
keyStore=KeyStore.getInstance("JKS");
StringkeystoreURL="C://DocumentsandSettings//Marvion//TrustStore";
is=newFileInputStream(keystoreURL);
keyStore.load(is,"1302821986".toCharArray());
}catch(IOExceptionex){
//Logger.getLogger(KeyStoreCallbackHandler.class.getName()).log(Level.SEVERE,null,ex);
thrownewRuntimeException(ex);
}catch(NoSuchAlgorithmExceptionex){
//Logger.getLogger(KeyStoreCallbackHandler.class.getName()).log(Level.SEVERE,null,ex);
thrownewRuntimeException(ex);
}catch(CertificateExceptionex){
//Logger.getLogger(KeyStoreCallbackHandler.class.getName()).log(Level.SEVERE,null,ex);
thrownewRuntimeException(ex);
}catch(KeyStoreExceptionex){
//Logger.getLogger(KeyStoreCallbackHandler.class.getName()).log(Level.SEVERE,null,ex);
thrownewRuntimeException(ex);
}finally{
try{
is.close();
}catch(IOExceptionex){
//Logger.getLogger(KeyStoreCallbackHandler.class.getName()).log(Level.SEVERE,null,ex);
}
}
}
publicvoidhandle(Callback[]callbacks)throwsIOException,UnsupportedCallbackException{
System.out.println("TruststoreCBH.handle()Called..........");
for(inti=0;i<callbacks.length;i++){
if(callbacks[i]instanceofKeyStoreCallback){
KeyStoreCallbackcb=(KeyStoreCallback)callbacks[i];
print(cb.getRuntimeProperties());
cb.setKeystore(keyStore);
}else{
thrownewUnsupportedCallbackException(callbacks[i]);
}
}
}
privatevoidprint(Mapcontext){
Iteratorit=context.keySet().iterator();
while(it.hasNext()){
System.out.println("Prop"+it.next());
}
}
}


Note:youneeddownloadmetro-1_3.jarfromhttps://metro.dev.java.net/1.3/.
Afterinstallthataddthewebservices-rt.jartotheprojectlibraryreference.

3.3DevelopmenttheJavaclient
codeinEclipse.

Well,thereisnoeclipseplug-inforcando
itdirectly.SowhatIdoisdevelopisinNetbeansfirst,thenImovethecode
andconfigurationfilestoEclipse.Itneedstochangesomesourcefolder
directoryhere.seemysamplecode.

4.DownloadDemos

4.1TheServicesidecode.http://download.csdn.net/source/1135380

4.2Webapplicationcodehttp://download.csdn.net/source/1135375

4.3Javaapplicationcodehttp://download.csdn.net/source/1135382
4.4Eclipseclientcodehttp://download.csdn.net/source/11353834.5Theneededjarfile(webservices-rt.jar)itwillgeneratebynetbeanswhenyouaddnewwebserviceclient.

Reference

01
http://msdn2.microsoft.com/en-us/library/ms733813.aspx
02
http://forums.java.net/jive/thread.jspa?messageID=293406
03
http://forums.java.net/jive/message.jspa?messageID=277883
04
http://forums.java.net/jive/thread.jspa?messageID=262600񀇈
05
https://xwss.dev.java.net/articles/security_config.html

06
https://wsit.dev.java.net/issues/show_bug.cgi?id=844
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: