Validate a kerberos service token with keytab - kerberos

A similar question has been asked before on this forum, but the accepted answer hasn't been helpful to me. My server has a Kerberos keytab file that I'd like to use to validate a service ticket sent by a client.
Following Sun's documentation and sample code scattered elsewhere this is what I currently have:
Client requests a service ticket from the KDC for MYSPN
Client sends the file to the Service Server to request access to the service.
Server grants access after validating service ticket with keytab for MYSPN it already has.
I'm having trouble getting #3 to work. The specific error I get is:
GSSException: No valid credentials provided (Mechanism level: Attempt to obtain new ACCEPT credentials failed!)
at sun.security.jgss.krb5.Krb5AcceptCredential.getInstance(Krb5AcceptCredential.java:100)
at sun.security.jgss.krb5.Krb5MechFactory.getCredentialElement(Krb5MechFactory.java:128)
at sun.security.jgss.krb5.Krb5MechFactory.getMechanismContext(Krb5MechFactory.java:200)
at sun.security.jgss.GSSManagerImpl.getMechanismContext(GSSManagerImpl.java:231)
at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:319)
at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:285)
at cms.gssapi.Server$1.run(Server.java:188)
at cms.gssapi.Server$1.run(Server.java:1)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:357)
at cms.gssapi.Server.acceptSecurityContext(Server.java:182)
at cms.gssapi.Server.main(Server.java:59)
Caused by: javax.security.auth.login.LoginException: Unable to obtain Princpal Name for authentication
at com.sun.security.auth.module.Krb5LoginModule.promptForName(Krb5LoginModule.java:750)
at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:646)
at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:559)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:784)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:203)
at javax.security.auth.login.LoginContext$5.run(LoginContext.java:721)
at javax.security.auth.login.LoginContext$5.run(LoginContext.java:719)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokeCreatorPriv(LoginContext.java:718)
at javax.security.auth.login.LoginContext.login(LoginContext.java:590)
at sun.security.jgss.GSSUtil.login(GSSUtil.java:264)
at sun.security.jgss.krb5.Krb5Util.getKeys(Krb5Util.java:202)
at sun.security.jgss.krb5.Krb5AcceptCredential$1.run(Krb5AcceptCredential.java:95)
at sun.security.jgss.krb5.Krb5AcceptCredential$1.run(Krb5AcceptCredential.java:93)
at java.security.AccessController.doPrivileged(Native Method)
at sun.security.jgss.krb5.Krb5AcceptCredential.getInstance(Krb5AcceptCredential.java:92)
... 11 more
This is a snippet of the server code that tries to validate the client's service ticket using keytab:
public static void main( String[] args) {
Properties props = new Properties();
props.load( new FileInputStream( "server.properties"));
System.setProperty( "sun.security.krb5.debug", "true");
System.setProperty( "java.security.krb5.realm", props.getProperty( "realm"));
System.setProperty( "java.security.krb5.kdc", props.getProperty( "kdc"));
System.setProperty( "java.security.auth.login.config", "./jaas.conf");
System.setProperty( "javax.security.auth.useSubjectCredsOnly", "false");
krb5Oid = new Oid( "1.2.840.113554.1.2.2");
Server server = new Server();
server.login();
byte serviceTicket[] = readClientTicketFromFile();
String clientName = server.acceptSecurityContext(serviceTicket);
}
private static byte[] readClientTicketFromFile() throws IOException {
BufferedReader in = new BufferedReader( new FileReader( "serviceticket.token"));
String str;
StringBuffer buffer = new StringBuffer();
while ((str = in.readLine()) != null) {
buffer.append( str + "\n");
}
in.close();
BASE64Decoder decoder = new BASE64Decoder();
return decoder.decodeBuffer( buffer.toString());
}
private static Oid krb5Oid;
private Subject login() throws LoginException {
LoginContext loginCtx = null;
loginCtx = new LoginContext( "Server", new LoginCallbackHandler(null,null));
System.out.println("Attempting to do Login...");
loginCtx.login();
Subject ret_sub = loginCtx.getSubject();
return ret_sub;
}
private String acceptSecurityContext( final byte[] serviceTicket)
throws GSSException {
krb5Oid = new Oid( "1.2.840.113554.1.2.2");
return Subject.doAs( subject, new PrivilegedAction<String>() {
public String run() {
try {
GSSManager manager = GSSManager.getInstance();
GSSContext context = manager.createContext( (GSSCredential) null);
context.acceptSecContext( serviceTicket, 0, serviceTicket.length);
return context.getSrcName().toString();
}
catch ( Exception e) {
e.printStackTrace();
return null;
}
}
});
}
Here is my server.properties
realm=MYREALM
kdc=192.168.1.1
and jaas.conf file
Client {
com.sun.security.auth.module.Krb5LoginModule required
useTicketCache=false
useKeyTab=false
storeKey=false
isInitiator=true
debug=true
;
};
Server {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
doNotPrompt=true
isInitiator=false
keyTab="/etc/krb5.keytab"
principal="MYSPN/host.domain.com#MYREALM"
debug=true
;
};
I'm sure the service ticket is valid because the server can authenticate if I provide password for the service account, but I want to use a keytab file instead of password.

Related

"WSSecurityException: Cannot find key for alias" of a digital certificate in WS-Security SOAP client with Spring Boot

I am trying to make a client to a SOAP with Spring Boot. The requests must have a digital certificate (public key) in the header, but when I try to add it to the secuityInterceptor.
I'm deploying the client on a WildFly server, I thought maybe I would have to add the certificate to the server somehow but I don't know for sure. In principle it is in the resources folder of the project and when generating the war it is still there.
Config:
private static final Resource KEYSTORE_LOCATION = new ClassPathResource("client-keystore.jks");
private static final String KEYSTORE_PASSWORD = "password";
private static final String KEY_ALIAS = "alias";
#Bean
TrustManagersFactoryBean trustManagers() throws Exception {
TrustManagersFactoryBean factoryBean = new TrustManagersFactoryBean();
factoryBean.setKeyStore(keyStore().getObject());
return factoryBean;
}
#Bean
HttpsUrlConnectionMessageSender messageSender() throws Exception {
HttpsUrlConnectionMessageSender sender = new HttpsUrlConnectionMessageSender();
KeyManagersFactoryBean keyManagersFactoryBean = new KeyManagersFactoryBean();
keyManagersFactoryBean.setKeyStore(keyStore().getObject());
keyManagersFactoryBean.setPassword(KEYSTORE_PASSWORD);
keyManagersFactoryBean.afterPropertiesSet();
sender.setKeyManagers(keyManagersFactoryBean.getObject());
sender.setTrustManagers(trustManagers().getObject());
return sender;
}
#Bean
KeyStoreFactoryBean keyStore() throws GeneralSecurityException, IOException {
KeyStoreFactoryBean factoryBean = new KeyStoreFactoryBean();
factoryBean.setLocation(KEYSTORE_LOCATION);
factoryBean.setPassword(KEYSTORE_PASSWORD);
return factoryBean;
}
#Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("contextpath");
return marshaller;
}
#Bean
Wss4jSecurityInterceptor securityInterceptor() throws Exception {
Wss4jSecurityInterceptor securityInterceptor = new Wss4jSecurityInterceptor();
securityInterceptor.setSecurementActions("Signature");
securityInterceptor.setSecurementUsername(KEY_ALIAS);
securityInterceptor.setSecurementPassword(KEYSTORE_PASSWORD);
securityInterceptor.setSecurementSignatureCrypto(cryptoFactoryBean().getObject());
return securityInterceptor;
}
#Bean
SOAPConnector client() throws Exception {
SOAPConnector client = new SOAPConnector();
System.out.println("client(): ");
client.setInterceptors(new ClientInterceptor[] { securityInterceptor() });
client.setMessageSender(messageSender());
client.setMarshaller(marshaller());
client.setUnmarshaller(marshaller());
client.afterPropertiesSet();
return client;
}
Error:
Caused by: org.apache.wss4j.common.ext.WSSecurityException: Error during Signature:
Original Exception was org.apache.wss4j.common.ext.WSSecurityException: Cannot find key for alias: [certificado]
Original Exception was org.apache.wss4j.common.ext.WSSecurityException: Cannot find key for alias: [certificado]
at org.apache.wss4j.dom.action.SignatureAction.execute(SignatureAction.java:174)
at org.apache.wss4j.dom.handler.WSHandler.doSenderAction(WSHandler.java:238)
at org.springframework.ws.soap.security.wss4j2.Wss4jHandler.doSenderAction(Wss4jHandler.java:58)
at org.springframework.ws.soap.security.wss4j2.Wss4jSecurityInterceptor.secureMessage(Wss4jSecurityInterceptor.java:609)
... 80 more
Caused by: org.apache.wss4j.common.ext.WSSecurityException: Cannot find key for alias: [certificado]
Original Exception was org.apache.wss4j.common.ext.WSSecurityException: Cannot find key for alias: [certificado]
at org.apache.wss4j.dom.message.WSSecSignature.computeSignature(WSSecSignature.java:615)
at org.apache.wss4j.dom.action.SignatureAction.execute(SignatureAction.java:166)
... 83 more
Caused by: org.apache.wss4j.common.ext.WSSecurityException: Cannot find key for alias: [certificado]
at org.apache.wss4j.common.crypto.Merlin.getPrivateKey(Merlin.java:696)
at org.apache.wss4j.dom.message.WSSecSignature.computeSignature(WSSecSignature.java:558)
In case it is useful, I am basing myself on this repository to make the client
I think the error is that the functions I'm using are to add certificates with a private key but I try to do it with a public one, in that case I don't know how to add the public one
this is the sing of the setSecurementUsername method:
public void setSecurementUsername(String securementUsername)
Sets the username for securement username token or/and the alias of the private key for securement signature

WSO2IS JWT access token

I am trying get a JWT access token from WSO2 IS. I followed instructions from msf4j Oauth2 Security Sample, and managed to get a JWT acces token by resource owner password grant type.
but I have problem authenticating the token externally.
it seems that the token had not been signed by the default "wso2carbon.jks".
also, my claim configurations in the "service providers" was not reflected in jwt content
so my questions: how to config the JWT signing certificate in WSO2IS?
and also:
How to manipulate the claims in the JWT?
I do not want to turn to the "introspect" endpoint out of performance concern, and my strategy is to just trust the IS, only to make sure(locally) of the authenticity of the JWT token
please advise
thanks
You can follow [1] to get JWT Access Tokens(Self contained access tokens) using WSO2 Identity Server
[1] https://medium.com/#hasinthaindrajee/self-contained-access-tokens-with-wso2-identity-server-82111631d5b6
well, it seems to be my own fault.
I had been using the jose4j JWT package, and kept getting verification failed message.
after further checking into the msf4j implementation, I switched over to nimbus-jose-jwt JWT package, and got it done,
below are my implementation.
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.crypto.RSASSAVerifier;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
public class JwtParser {
private static final String KEYSTORE = System.getProperty("javax.net.ssl.trustStore");
private static final String KEYSTORE_PASSWORD = System.getProperty("javax.net.ssl.trustStorePassword");
private static Map<String, JWSVerifier> verifiers = getVerifiers();
public static JWTClaimsSet verify(String jwt) throws Exception {
SignedJWT signedJWT = SignedJWT.parse(jwt);
if (!new Date().before(signedJWT.getJWTClaimsSet().getExpirationTime())) {
new Exception("token has expired");
}
boolean notYet = true;
for(Iterator<JWSVerifier> it = verifiers.values().iterator(); notYet && it.hasNext();){
JWSVerifier verifier = it.next();
notYet = !signedJWT.verify(verifier);
}
if(notYet){
throw new Exception("token verification failed");
}
JWTClaimsSet claims = signedJWT.getJWTClaimsSet();
if (claims == null) {
// Do something with claims
throw new Exception("non valid payload in token, failed");
}
return claims;
}
private static Map<String, JWSVerifier> getVerifiers(){
Map<String, JWSVerifier> verifiers = new HashMap<>();
try (InputStream inputStream = new FileInputStream(KEYSTORE)) {
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(inputStream, KEYSTORE_PASSWORD.toCharArray());
Enumeration<String> aliases = keystore.aliases();
while(aliases.hasMoreElements()){
String alias = aliases.nextElement();
if(!keystore.isCertificateEntry(alias)){
continue;
}
Certificate cert = keystore.getCertificate(alias);
if(cert == null){
continue;
}
PublicKey key = cert.getPublicKey();
verifiers.put(alias, new RSASSAVerifier((RSAPublicKey)key));
}
}catch(KeyStoreException | CertificateException | NoSuchAlgorithmException | IOException e){
//TODO: report the exception
}
return verifiers;
}
}

Connection between Bluemix's Liberty for Java and Cloudant throw RuntimeError everyday

I create an application by using Bluemix's Liberty for Java to connect Cloudant. I found RuntimeException everyday while connecting to my RESTful API. However, I have to restart my application everyday to solve this problem.
An error is shown as follow:
Exception thrown by application class 'org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage:116'
java.lang.RuntimeException: org.apache.cxf.interceptor.Fault: Error retrieving server response
at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:116)
at [internal classes]
Caused by: org.apache.cxf.interceptor.Fault: Error retrieving server response
at org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:163)
... 1 more
Caused by: com.cloudant.client.org.lightcouch.CouchDbException: Error retrieving server response
at com.cloudant.client.org.lightcouch.CouchDbClient.execute(CouchDbClient.java:501)
at com.cloudant.client.org.lightcouch.CouchDbClient.executeToInputStream(CouchDbClient.java:515)
at com.cloudant.client.api.Database.findByIndex(Database.java:361)
at com.cloudant.client.api.Database.findByIndex(Database.java:321)
at th.co.gosoft.rest.TopicService.getHotTopicList(TopicService.java:82)
at sun.reflect.GeneratedMethodAccessor34.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.ibm.ws.jaxrs20.server.LibertyJaxRsServerFactoryBean.performInvocation(LibertyJaxRsServerFactoryBean.java:636)
... 1 more
Caused by: java.net.ProtocolException: Server rejected operation
at sun.net.www.protocol.http.HttpURLConnection.expect100Continue(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
at com.ibm.net.ssl.www2.protocol.https.b.getOutputStream(Unknown Source)
at com.cloudant.http.HttpConnection.execute(HttpConnection.java:231)
at com.cloudant.client.org.lightcouch.CouchDbClient.execute(CouchDbClient.java:466)
... 9 more
I use this CloudantClientMgr as follow:
package th.co.gosoft.util;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map.Entry;
import java.util.Set;
import com.cloudant.client.api.ClientBuilder;
import com.cloudant.client.api.CloudantClient;
import com.cloudant.client.api.Database;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class CloudantClientMgr {
private static CloudantClient cloudant = null;
private static Database db = null;
private static String databaseName = "go10_db";
private static String url = "https://xxxxxxxxxx-bluemix.cloudant.com";
private static String user = "xxxxxxxxxx-bluemix";
private static String password = "password";
private static void initClient() {
if (cloudant == null) {
synchronized (CloudantClientMgr.class) {
if (cloudant != null) {
return;
}
try {
cloudant = createClient();
} catch (MalformedURLException e) {
throw new RuntimeException(e.getMessage(), e);
}
System.out.println("cloudant : " + cloudant.serverVersion());
}
}
}
private static CloudantClient createClient() throws MalformedURLException {
String VCAP_SERVICES = System.getenv("VCAP_SERVICES");
String serviceName = null;
CloudantClient client;
if (VCAP_SERVICES != null) {
System.out.println("VCAP_SERVICE");
JsonObject obj = (JsonObject) new JsonParser().parse(VCAP_SERVICES);
Entry<String, JsonElement> dbEntry = null;
Set<Entry<String, JsonElement>> entries = obj.entrySet();
for (Entry<String, JsonElement> eachEntry : entries) {
if (eachEntry.getKey().toLowerCase().contains("cloudant")) {
dbEntry = eachEntry;
break;
}
}
if (dbEntry == null) {
throw new RuntimeException("Could not find cloudantNoSQLDB key in VCAP_SERVICES env variable");
}
obj = (JsonObject) ((JsonArray) dbEntry.getValue()).get(0);
serviceName = (String) dbEntry.getKey();
System.out.println("Service Name - " + serviceName);
obj = (JsonObject) obj.get("credentials");
user = obj.get("username").getAsString();
password = obj.get("password").getAsString();
client = ClientBuilder.account(user)
.username(user)
.password(password)
.build();
} else {
System.out.println("LOCAL");
client = ClientBuilder.url(new URL(url))
.username(user)
.password(password)
.build();
}
return client;
}
public static Database getDB() {
if (cloudant == null) {
initClient();
}
if (db == null) {
try {
db = cloudant.database(databaseName, true);
} catch (Exception e) {
throw new RuntimeException("DB Not found", e);
}
}
return db;
}
private CloudantClientMgr() {
}
}
I use this code to connect CloudantClientMgr as follow:
#Path("topic")
public class TopicService {
#POST
#Path("/post")
#Consumes(MediaType.APPLICATION_JSON + ";charset=utf-8")
public Response createTopic(TopicModel topicModel) {
Database db = CloudantClientMgr.getDB();
com.cloudant.client.api.model.Response response = db.save(topicModel);
String result = response.getId();
return Response.status(201).entity(result).build();
}
}
The Cloudant version is 2.4.2
<dependency>
<groupId>com.cloudant</groupId>
<artifactId>cloudant-client</artifactId>
<version>2.4.2</version>
</dependency>
If anyone used to found this problem, please let me know the better solution than I have to restart my application every day.
The problem you describe sounds identical to one that was resolved in version 2.4.1.
I would check to make sure you don't have multiple versions of the cloudant-client included in your application or classpath and that your application is really using version 2.4.2. The line numbers in the stack trace you provide do not match with the source for 2.4.2.

JBoss-A-MQ encountered an UnknownHostException in JMS messaging application

I have a sample JMS messaging application as shown in below snippet. When I executing the program (specifically when starting the connection) I get an UnknowHostException.
The reason for the exception is clientid property get's null.
Application:
public class MessagingTestApp {
private static final String MY_JMS_CONNECTION_FACTORY_NAME = "myJmsFactory";
private static final String EXCHANGE_NAME = "topicExchange";
private static final String JNDI_PROPERTIES_FILE_NAME = "jndi.properties";
private static final String COULD_NOT_LOAD_JNDI_PROPERTIES_MESSAGE = "Could not load JNDI properties....";
private static final boolean NON_TRANSACTED = false;
private static final Logger LOG = Logger.getLogger(MessagingTestApp.class);
public MessagingTestApp() {}
public static void main(String[] args) {
MessagingTestApp messagingTestApp = new MessagingTestApp();
messagingTestApp.runTest();
}
private void runTest() {
try {
Properties properties = new Properties();
properties.load(loadPropertiesFile());
Context context = new InitialContext(properties);
ConnectionFactory connectionFactory = (ConnectionFactory) context.lookup(MY_JMS_CONNECTION_FACTORY_NAME);
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(NON_TRANSACTED, Session.AUTO_ACKNOWLEDGE);
Destination destination = (Destination) context.lookup(EXCHANGE_NAME);
MessageProducer messageProducer = session.createProducer(destination);
MessageConsumer messageConsumer = session.createConsumer(destination);
TextMessage message = session.createTextMessage("Hello JMS!");
messageProducer.send(message);
message = (TextMessage) messageConsumer.receive();
System.out.println(message.getText());
connection.close();
context.close();
} catch (Exception e) {
LOG.error(e);
e.printStackTrace();
}
}
private InputStream loadPropertiesFile() {
Thread currentThread = Thread.currentThread();
ClassLoader contextClassLoader = currentThread.getContextClassLoader();
InputStream propertiesStream = contextClassLoader.getResourceAsStream(JNDI_PROPERTIES_FILE_NAME);
if (propertiesStream != null) {
return propertiesStream;
} else {
System.out.println(COULD_NOT_LOAD_JNDI_PROPERTIES_MESSAGE);
return null;
}
}
}
JNDI properties file:
java.naming.factory.initial = org.apache.qpid.amqp_1_0.jms.jndi.PropertiesFileInitialContextFactory
java.naming.provider.url = src/main/resources/jndi.properties
connectionfactory.myJmsFactory = amqp://admin:admin#clientid/test?
brokerlist = 'tcp://localhost:5672'
destination.topicExchange = amq.topic
Stack-trace:
javax.jms.JMSException: java.net.UnknownHostException: clientid
at org.apache.qpid.amqp_1_0.jms.impl.ConnectionImpl.connect(ConnectionImpl.java:112)
at org.apache.qpid.amqp_1_0.jms.impl.ConnectionImpl.start(ConnectionImpl.java:266)
at com.adc.efg.MessagingTestApp.runTest(MessagingTestApp.java:39)
at com.adc.efg.MessagingTestApp.main(MessagingTestApp.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: org.apache.qpid.amqp_1_0.client.ConnectionException: java.net.UnknownHostException: clientid
at org.apache.qpid.amqp_1_0.client.Connection.<init>(Connection.java:271)
at org.apache.qpid.amqp_1_0.client.Connection.<init>(Connection.java:135)
at org.apache.qpid.amqp_1_0.jms.impl.ConnectionImpl.connect(ConnectionImpl.java:105)
... 8 more
Caused by: java.net.UnknownHostException: clientid
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:178)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:579)
at java.net.Socket.connect(Socket.java:528)
at java.net.Socket.<init>(Socket.java:425)
at java.net.Socket.<init>(Socket.java:208)
at org.apache.qpid.amqp_1_0.client.Connection.<init>(Connection.java:159)
... 10 more
I'm new to both JBoss-AMQ and JMS. Much appreciated if anyone can point me out where did I go wrong.
Problem was in JNDI properties file. It should be like below,
java.naming.factory.initial = org.apache.qpid.amqp_1_0.jms.jndi.PropertiesFileInitialContextFactory
java.naming.provider.url = src/main/resources/jndi.properties
connectionfactory.myJmsFactory = amqp://admin:admin#localhost/test?
brokerlist = 'tcp://localhost:5672'
destination.topicExchange = amq.topic

Generating random session id whenever user uses login() in web services

Am new to web services. Am trying to generate unique session id for every login that a user does, in web services.
What I thought of doing is,
Write a java file which has the login and logout method.
Generate WSDL file for it.
Then generate web service client(using Eclipse IDE), with the WSDl file which I generate.
Use the generated package(client stub) and call the methods.
Please let me know if there are any flaws in my way of implementation.
1. Java file with the needed methods
public String login(String userID, String password) {
if (userID.equalsIgnoreCase("sadmin")
&& password.equalsIgnoreCase("sadmin")) {
System.out.println("Valid user");
sid = generateUUID(userID);
} else {
System.out.println("Auth failed");
}
return sid;
}
private String generateUUID(String userID) {
UUID uuID = UUID.randomUUID();
sid = uuID.toString();
userSessionHashMap = new HashMap<String, String>();
userSessionHashMap.put(userID, sid);
return sid;
}
public void logout(String userID) {
Set<String> userIDSet = userSessionHashMap.keySet();
Iterator<String> iterator = userIDSet.iterator();
if (iterator.equals(userID)) {
userSessionHashMap.remove(userID);
}
}
2. Generated WSDL file
Developed the web service client from the wsdl.
4. Using the developed client stub.
public static void main(String[] args) throws Exception {
ClientWebServiceLogin objClientWebServiceLogin = new ClientWebServiceLogin();
objClientWebServiceLogin.invokeLogin();
}
public void invokeLogin() throws Exception {
String endpoint = "http://schemas.xmlsoap.org/wsdl/";
String username = "sadmin";
String password = "sadmin";
String targetNamespace = "http://WebServiceLogin";
try {
WebServiceLoginLocator objWebServiceLoginLocator = new WebServiceLoginLocator();
java.net.URL url = new java.net.URL(endpoint);
Iterator ports = objWebServiceLoginLocator.getPorts();
while (ports.hasNext())
System.out.println("ports Iterator size-->" + ports.next());
WebServiceLoginPortType objWebServiceLoginPortType = objWebServiceLoginLocator
.getWebServiceLoginHttpSoap11Endpoint();
String sid = objWebServiceLoginPortType.login(username, password);
System.out.println("sid--->" + sid);
} catch (Exception exception) {
System.out.println("AxisFault at creating objWebServiceLoginStub"
+ exception);
exception.printStackTrace();
}
}
On running the this file, I get the following error.
AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: java.net.ConnectException: Connection refused: connect
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:java.net.ConnectException: Connection refused: connect
Can anyone suggest an alternate way of handling this task ? And what could probably be the reason for this error.
Web services are supposed to be stateless, so having "login" and "logout" web service methods doesn't make much sense.
If you want to secure web services calls unfortunately you have to code security into every call. In your case, this means passing the userId and password to every method.
Or consider adding a custom handler for security. Read more about handlers here.