how can I access a webservice through a basic http authentification? I am using the netbeans built in webservice client features. But when I try to access the webservice, I get an exception with a 401 auth failed error message.
How can I pass the right username and password?
Thank you!
You could use BindingProvider or WSBindingProvider class to access a Web Service through a basic http authentification.
The code is as follows.
XxxService service = new XxxService();
Xxx port = service.getXxxPort();
Map<String, Object> reqContext = ((BindingProvider)port).getRequestContext();
reqContext.put(BindingProvider.USERNAME_PROPERTY, "username");
reqContext.put(BindingProvider.PASSWORD_PROPERTY, "password");
You can also provide your own Authenticator. That way it will work even if the WDSL itself is protected by basic HTTP authentication.
#WebServiceRef(wsdlLocation = "https://laka/sito?wsdl")
static XxxService service;
public static void main(String[] args) {
Authenticator.setDefault(new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("user", "password".toCharArray());
}
});
service = new XxxService();
Xxx port = service.getXxxPort();
// invoke webservice and print response
XxxResponse resp = port.foo();
System.out.println(resp.toString());
}
Related
I want to add Authorization header for basic Authorization to my jetty-client request.
I am running two instances on same browser one is server one is client ,Java-8 is being used as a technology, No DB No Spring etc. using org.eclipse.jetty,jetty-websocket,version-8.1.15.v20140411.
I had a websocketEndPointManager class which contains the initialization method for both Server(dedicated class is CSWebsocket) and client(Cpwebsocket).
How can I achieve basic auth in my scenario where server maintains username and password is to matched in current session after its instance is ready, currently my setup able to perform upgrade to websocket but not basic
Snippet of client websocket start method where handshake occur :
private void startCPWebSocket() throws Exception{
String uri ="";
try {
HandlerRegistry.register(this);
WebSocketClientFactory factory = new WebSocketClientFactory();
Configuration configuration = TestSession.getConfiguration();
uri = configuration.getSystemUnderTestEndpoint();
TestSession.getConfiguration().setToolURL("NA");
TestSession.getConfiguration().setSystemUnderTestEndpoint(uri);
factory.start();
WebSocketClient client = factory.newWebSocketClient();
client.setMaxIdleTime(24*60*60*1000);
client.open(new URI(uri.trim()),new CPWebSocket()).get(24*60*60,
TimeUnit.SECONDS);
LogUtils.logInfo("WebSocket URL : "+uri,true);
}
catch (ExecutionException e) {
LogUtils.logError(e.getMessage(), e,false);
LogUtils.logWarn("Could not establish websocket connection.",true);
//System.exit(0);
TestSession.setTerminated(true);
throw e;
How to publish a web service class with #WebServiceProvider?What is the endpoint URL in this case?
Could we generate wsdl with #WebServiceProvider as in the case with
#WebService?What does the "wsdlLocation" attribute mean in #WebServiceProvider?
For instance
#ServiceMode(value = Service.Mode.MESSAGE)
#WebServiceProvider(portName = "ProviderPort",serviceName = "ProviderService",
targetNamespace = "http://bean/")
public class WebServiceProviderImpl implements Provider<SOAPMessage>
Simplest way is-
package server;
import javax.xml.ws.Endpoint;
public class Server {
protected Server() throws Exception {
System.out.println("Starting Server");
System.out.println("Starting SoapService1");
Object implementor = new WebServiceProviderImpl();
String address = "http://localhost:8123/SoapContext/SoapPort1";
Endpoint.publish(address, implementor);
}
public static void main(String args[]) throws Exception {
new Server();
System.out.println("Server ready...");
Thread.sleep(5 * 60 * 1000);
System.out.println("Server exiting");
System.exit(0);
}
The URL is "address". As far as I understand you can specify it as you like, as long as the port is free.
Alternatively, you could use JAXWsServerFactoryBean which is a part of CXF.
You would do the same thing as you would with an SEI.
And yes, it does generate a WSDL for you.
You can create your client stubs from it using wsimport just like an SEI
I have a WCF Service Application which server to different type of clients. While calling the service methods I want to send some spesific information within the service header.
While using a newer version of .NET Framework I can handle the situation using MessageHeader. Since the consumer can see the service as WCF Service there is no problem.
[DataContract]
public class AuthToken
{
[DataMember]
public string Username { get; set; }
[DataMember]
public string Password { get; set; }
}
Client-side:
AuthWCFSvc.Service1Client client = new AuthWCFSvc.Service1Client();
using (OperationContextScope scope = new OperationContextScope(client.InnerChannel))
{
SvcAuthClient.AuthWCFSvc.AuthToken token = new AuthWCFSvc.AuthToken();
token.Username = "wcfuser";
token.Password = "wcfpass";
MessageHeader<SvcAuthClient.AuthWCFSvc.AuthToken> header = new MessageHeader<SvcAuthClient.AuthWCFSvc.AuthToken>(token);
var untyped = header.GetUntypedHeader("Identity", "http://www.my-website.com");
OperationContext.Current.OutgoingMessageHeaders.Add(untyped);
client.TestHeader();
}
Server-side :
MessageHeaders headers = OperationContext.Current.IncomingMessageHeaders;
AuthToken token = headers.GetHeader<AuthToken>("Identity", "http://www.my-website.com");
But there are Windows Mobile 6 devices with .NET Framework 3.5 Compact Edition, using these services as well. Due to technological restrictions, they only can process the WCF services as Web Services.
If a client is consuming a WCF service as Web Service how can add spesific header information and resolve the header information at the service method?
As you know, on .NET CF 3.5 you can only use WCF as standard webservice on SOAP way. Therefore, you can't use any of WCF native security resources.
I figured out how to use Basic Http Authentication, configuring client and server sides and I can explain it as follows:
Client Side
On client side (on your device with .Net CF 3.5), its easy. Just inform your credentials configuring your clientServiceProxy by using:
var service = new YourServiceNamespace.YourService();
service.Credentials = new NetworkCredential("login", "12345");
service.PreAuthenticate = true;
This will make your client deal with the "WWW-Authenticate" header from the server response and pass your credentials automatically via the response header "Authorization: Basic".
Server Side
On the WCF configuration on your web.config, you should configure security just for Transport, and use HTTPS (this is enough to protect your message from sniffers).
<basicHttpBinding>
<binding>
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
Now, as WCF doesn't has native support for Basic Http Authentication, we have to use a custom HTTP module to deal with it.
public class BasicHttpAuthentication : IHttpModule
{
public delegate bool AuthenticateDelegate( string username, string password );
public static AuthenticateDelegate AuthenticateMethod;
public void Dispose() { }
public void Init( HttpApplication application )
{
application.AuthenticateRequest += this.OnAuthenticateRequest;
application.EndRequest += this.OnEndRequest;
}
private void DenyAccess( HttpApplication app )
{
app.Response.StatusCode = 401;
app.Response.StatusDescription = "Access Denied";
// Write to response stream as well, to give user visual
// indication of error during development
app.Response.Write( "401 Access Denied" );
app.CompleteRequest();
}
private void OnAuthenticateRequest( object source, EventArgs eventArgs )
{
if ( AuthenticateMethod == null )
return;
var app = ( HttpApplication )source;
//the Authorization header is checked if present
string authHeader = app.Request.Headers["Authorization"];
if ( !string.IsNullOrEmpty( authHeader ) )
{
string authStr = app.Request.Headers["Authorization"];
if ( string.IsNullOrEmpty( authStr ) )
return; // No credentials; anonymous request
authStr = authStr.Trim();
if ( authStr.IndexOf( "Basic", 0 ) != 0 )
// header is not correct...we'll pass it along and
// assume someone else will handle it
return;
authStr = authStr.Trim();
string encodedCredentials = authStr.Substring( 6 );
byte[] decodedBytes = Convert.FromBase64String( encodedCredentials );
string s = new ASCIIEncoding().GetString( decodedBytes );
string[] userPass = s.Split( new[] { ':' } );
string username = userPass[0];
string password = userPass[1];
if ( !AuthenticateMethod( username, password ) )
this.DenyAccess( app );
}
else
{
app.Response.StatusCode = 401;
app.Response.End();
}
}
private void OnEndRequest( object source, EventArgs eventArgs )
{
//the authorization header is not present
//the status of response is set to 401 and it ended
//the end request will check if it is 401 and add
//the authentication header so the client knows
//it needs to send credentials to authenticate
if ( HttpContext.Current.Response.StatusCode == 401 )
{
HttpContext context = HttpContext.Current;
context.Response.StatusCode = 401;
context.Response.AddHeader( "WWW-Authenticate", "Basic Realm=\"Please inform your credentials\"" );
}
}
}
To enable the HTTP module, add the following to your web.config file in the system.webServer section:
<system.webServer>
<modules>
<add name="BasicHttpAuthentication"
type="BasicHttpAuthentication, YourAssemblyName"/>
</modules>
Now you have to inform to the module a Function to use for validating the credentials from the client. You can see that there's a static delegate inside the module called "AuthenticateMethod", so you can inform a function on your Application_Start of your global.asax:
BasicHttpAuthentication.AuthenticateMethod = ( username, password ) => username == "login" && password == "12345";
Hi i am creating client from my webservice. Client is generated successfully but when I call that from java code It throws following error:
Exception in thread "main" javax.xml.ws.WebServiceException: Failed to access the WSDL at: https://ebs-uat.corp.chartercom.com/csg_cter/2.06/orderdetailservice.asmx?wsdl. It failed with:
Server returned HTTP response code: 401 for URL: https://ebs-uat.corp.chartercom.com/csg_cter/2.06/orderdetailservice.asmx?wsdl.
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex(RuntimeWSDLParser.java:151)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:133)
at com.sun.xml.internal.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:254)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:217)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:165)
at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:93)
at javax.xml.ws.Service.<init>(Service.java:56)
at com.charter.enterprise.billing.csg.orderdetails.OrderDetailServicePort.<init>(OrderDetailServicePort.java:68)
at com.charter.enterprise.billing.csg.orderdetails.OrderDetailServiceClient.main(OrderDetailServiceClient.java:18)
Caused by: java.io.IOException: Server returned HTTP response code: 401 for URL: https://ebs-uat.corp.chartercom.com/csg_cter/2.06/orderdetailservice.asmx?wsdl
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1436)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)
at java.net.URL.openStream(URL.java:1010)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.createReader(RuntimeWSDLParser.java:793)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.resolveWSDL(RuntimeWSDLParser.java:251)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:118)
... 7 more
It throws exception in first line when creating webservice port
DataServicePort dataServicePort = new DataServicePort();
My complete client class is:
public class OrderDetailServiceClient {
#WebServiceRef
private static OrderDetailServicePort orderDetailServicePort;
private static OrderDetailService orderDetailService;
public static void main(String[] args) {
orderDetailServicePort = new OrderDetailServicePort();
orderDetailService = orderDetailServicePort.getOrderDetailService();
// Add your code to call the desired methods.
System.out.println("Before calling method!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
verifyOrderDetail();
}
private static void verifyOrderDetail() {
BindingProvider prov = (BindingProvider) orderDetailService;
prov.getRequestContext().put(BindingProvider.USERNAME_PROPERTY,
"CHTR\tst_aopebstest");
prov.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY,
"T$t_#0p3B$t#sT");
orderDetailService = (OrderDetailService) prov;
VerifyOrderDetailRequest verifyOrderDetailRequest = new VerifyOrderDetailRequest();
VerifyOrderDetailResponse verifyOrderDetailResponse = orderDetailService
.verifyOrderDetail(verifyOrderDetailRequest, null);
}
}
I can hit in my browser. And it is also working in SoapUI. Where am I going wrong?
Any suggestion will be appreciated.
Thanks in advance.
It looks like you can't access that web service, have you tried accessing that web service through a web browser?
I have to call SharePoint 2010 Lists service from a Java client.
I used NetBeans to generate the JAX-WS classes from the WSDL.
And extended java.net.Authenticator to manage the authentication to SharePoint :
static final String user = "XXXXXXXX\\Administrateur"; // your account name
static final String pass = "mypassw"; // your password for the account
static class MyAuthenticator extends Authenticator {
public PasswordAuthentication getPasswordAuthentication() {
System.out.println("Feeding username and password for " + getRequestingScheme());
return (new PasswordAuthentication(user, pass.toCharArray()));
}
}
Calling the web service with JAX-WS :
Authenticator.setDefault(new MyAuthenticator());
com.nm.Lists service = new com.nm.Lists();
com.nm.ListsSoap port = service.getListsSoap12();
String pageUrl = "http://xxxxxxx/testPushFile.txt";
String comment = "no comment";
String checkinType = "1";
boolean result = port.checkInFile(pageUrl, comment, checkinType);
I am still getting the error :
Exception in thread "main" javax.xml.ws.WebServiceException: java.io.IOException: Authentication failure
at com.sun.xml.internal.ws.transport.http.client.HttpClientTransport.readResponseCodeAndMessage(HttpClientTransport.java:201)
Because it isn't working I tried :
to set the user without the domain
to set the domain as a system property : System.setProperty("http.auth.ntlm.domain", "XXXXXXXX");
to authenticate "old-fashioned way" :
((BindingProvider) port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, user);
((BindingProvider) port).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, pass);
Any ideas what's the problem with authentication ?
Thanks
I am coming back to give the solution. Here is what I have done to make the Web Service authentication work :
I enabled Basic Authentication in IIS Manager for my SharePoint Site,
I used a user credentials that was registred in Windows Domain