Skip to main content

Web Service requiring a Login

5 replies [Last post]
swpalmer
Offline
Joined: 2003-06-10
Points: 0

Can someone point me to a tutorial or example that shows how I might create a lightweight web service, using the server code that is built-in to Java 6, that requires a simple login before some of the APIs can be used.

In other words I have a simple web service that has some public APIs that anyone can call, and some restricted APIs that should only be callable after logging in (once). E.g. if I had a simple library service, everyone would be allowed to fetch the list of books, but only people with an admin password would be allowed to add more books to the list.

I don't want to have to change all of my APIs to take a password or security token as a parameter (even though I suspect that the solution will have that happen behind the scenes). I want to have the client call a single login(char [] password) API or something similar and then have access to all of the restricted APIs after that.

Thanks in advance,

Scott

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
swpalmer
Offline
Joined: 2003-06-10
Points: 0

After closer inspection I see that the Sample above uses all sorts of proprietary Sun classes. I can't use that in production code. The blogs re:WSIT on Java 6 are extremely hard to follow. I will try to decipher them.

apk2072
Offline
Joined: 2007-08-24
Points: 0

You can use intercept handlers. We are use Axis engine for web services. We wrote class called SoapAuthenticationHandler by extending axis's SimpleAuthenticationHandler. There you can intercept the call and do the login check. Here is piece of code in SoapAuthenticationHandler.

public void invoke(MessageContext messageContext) throws AxisFault
{
try
{
/* Get the username from the message context */
String userName = messageContext.getUsername();

boolean flag = LoginHelper.validateWSUser(userName, messageContext.getPassword());
if(!flag)
{
logger.error("invoke() Username/ Password incorrect.");
throw new Exception("103: Authentication Error: Username/ Password incorrect.");
}
logger.info("Web services user has been successfully authenticated");
}
catch (Exception e)
{
logger.error("invoke() Exception caught: ", e);
/* Construct an Axis fault! */
throw AxisFault.makeFault(e);
}
}

kumarjayanti
Offline
Joined: 2003-12-10
Points: 0

Hi,

If you are willing to use SOAP Message Security with JDK 6 Endpoint and do a Username-Password Login then we do have a Way.

You can download a Sample from here :

https://xwss.dev.java.net/servlets/ProjectDocumentList?folderID=7894&exp...

which does the following :

1.Client Sends a Username and Password
2.Signs and Encrypts the Username and the SOAP Body
(if you want, you can just disable the signature and just send an encrypted UsernameToken,
Alternatively if you have access to the plain-text passwords of the users on the server side then you can abandon the Encryption and just use PasswordDigest Mechanism supported by XWSS 2.0)

Follow the instructions in README.txt and see if you are able to run the sample successfully.

3. Since you want only some API calls to go through the password Login we can do this as well. Please see the sample security policy configuration files, where different security is specified for different methods.

https://xwss.dev.java.net/source/browse/*checkout*/xwss/xwss-ri/wspack-s...
https://xwss.dev.java.net/source/browse/*checkout*/xwss/xwss-ri/wspack-s...

The only thing however is that the username-password would be sent over the wire and the login would happen with each request.

We also support something called as SecureSessions (SecureConversation) with WSIT Security, whereby the username/password login would only happen once and thereafter a session key is used to secure the messages. But WSIT is not offically supported yet with JDK 6 endpoints. You may try this as a option as well.

http://blogs.sun.com/ritzmann/entry/wsit_with_a_j2se_endpoint

http://blogs.sun.com/arungupta/entry/tango_on_javase_6

WSIT naturally suppports the notion of applying security to a selected set of WebService methods. This is done by binding the security-policies to the specific operation (input/output message-parts) in the WSDL.

If all this is not clear, we can try and provide a sample for your use case.

Thanks.

Message was edited by: kumarjayanti

swpalmer
Offline
Joined: 2003-06-10
Points: 0

Thank you!

That was extremely helpful. It sounds like the WSIT method is the way I would ultimately want to go, assuming that I can get it working reliably with a Java 6 "endpoint" - I'm new to the Web Service world and not up on all the terminology, so I think that means the built-in mini server that is included with Java 6. If it means something else please clue me in. :-)

The main thing is that I want to do this in a light-weight manner, built-in to my application and easy to configure, without the need to deploy a full-blown web server like Apache, or Tomcat, or similar.

I now have some reading to do before I can come back with useful questions.

Thanks again.

Scott

swpalmer
Offline
Joined: 2003-06-10
Points: 0

So I am making some progress trying to use WSIT with security using a Java 6 endpoint...

Now I get this exception when I try to publish my endpoint:

11-Sep-2007 2:28:43 PM [com.sun.xml.ws.tx.common.TxMapUpdateProvider] update
INFO: WSTX-COMMON-2005: running in a non Java EE container; disable mapping of Container Managed Transaction EJB to WS-AT Policy assertions due to 'javax/ejb/TransactionManagement'
11-Sep-2007 2:28:44 PM com.sun.xml.wss.jaxws.impl.SecurityPipeBase populateKeystoreProps
SEVERE: WSSPIPE0014: KeyStore URL was obtained as NULL from ConfigAssertion.
11-Sep-2007 2:28:44 PM com.sun.xml.wss.jaxws.impl.SecurityServerPipe
SEVERE: WSSPIPE0028: Error in creating new instance of SecurityServerPipe
java.lang.RuntimeException: WSSPIPE0014: KeyStore URL was obtained as NULL from
ConfigAssertion.
at com.sun.xml.wss.jaxws.impl.SecurityPipeBase.populateKeystoreProps(SecurityPipeBase.java:1226)
at com.sun.xml.wss.jaxws.impl.SecurityPipeBase.populateConfigProperties(SecurityPipeBase.java:1202)
at com.sun.xml.wss.jaxws.impl.SecurityServerPipe.configureServerHandler(SecurityServerPipe.java:692)
at com.sun.xml.wss.jaxws.impl.SecurityServerPipe.(SecurityServerPipe.java:145)
at com.sun.xml.ws.assembler.PipelineAssemblerFactoryImpl$WsitPipelineAssembler.createServer(PipelineAssemblerFactoryImpl.java:330)
at com.sun.xml.ws.api.pipe.TubelineAssemblerFactory$TubelineAssemblerAdapter.createServer(TubelineAssemblerFactory.java:140)
at com.sun.xml.ws.server.WSEndpointImpl.(WSEndpointImpl.java:152)
at com.sun.xml.ws.server.EndpointFactory.createEndpoint(EndpointFactory.
java:217)
at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:467)
at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:486)
at com.sun.xml.ws.transport.http.server.EndpointImpl.createEndpoint(EndpointImpl.java:222)
at com.sun.xml.ws.transport.http.server.EndpointImpl.publish(EndpointImpl.java:152)
at com.sun.xml.ws.spi.ProviderImpl.createAndPublishEndpoint(ProviderImpl.java:113)
at javax.xml.ws.Endpoint.publish(Endpoint.java:170)
at my.product.Main.main(Main.java:147)
java.lang.RuntimeException: WSSPIPE0028: Error in creating new instance of SecurityServerPipe
at com.sun.xml.wss.jaxws.impl.SecurityServerPipe.(SecurityServerPipe.java:150)
at com.sun.xml.ws.assembler.PipelineAssemblerFactoryImpl$WsitPipelineAssembler.createServer(PipelineAssemblerFactoryImpl.java:330)
at com.sun.xml.ws.api.pipe.TubelineAssemblerFactory$TubelineAssemblerAdapter.createServer(TubelineAssemblerFactory.java:140)
at com.sun.xml.ws.server.WSEndpointImpl.(WSEndpointImpl.java:152)
at com.sun.xml.ws.server.EndpointFactory.createEndpoint(EndpointFactory.java:217)
at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:467)
at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:486)
at com.sun.xml.ws.transport.http.server.EndpointImpl.createEndpoint(EndpointImpl.java:222)
at com.sun.xml.ws.transport.http.server.EndpointImpl.publish(EndpointImpl.java:152)
at com.sun.xml.ws.spi.ProviderImpl.createAndPublishEndpoint(ProviderImpl.java:113)
at javax.xml.ws.Endpoint.publish(Endpoint.java:170)
at my.project.main(Main.java:147)
Caused by: java.lang.RuntimeException: WSSPIPE0014: KeyStore URL was obtained as NULL from ConfigAssertion.
at com.sun.xml.wss.jaxws.impl.SecurityPipeBase.populateKeystoreProps(SecurityPipeBase.java:1226)
at com.sun.xml.wss.jaxws.impl.SecurityPipeBase.populateConfigProperties(SecurityPipeBase.java:1202)
at com.sun.xml.wss.jaxws.impl.SecurityServerPipe.configureServerHandler(SecurityServerPipe.java:692)
at com.sun.xml.wss.jaxws.impl.SecurityServerPipe.(SecurityServerPipe.java:145)
... 11 more

The issue appears to be: SEVERE: WSSPIPE0014: KeyStore URL was obtained as NULL from ConfigAssertion.

So I need to specify a keystore, AND I need to know what that keystore is expected to contain. Where do I do this?