Could not handle SAML20 mechanism to create SaslServer on openfire 3.9.1, returns SaslServer as null,

I have an xmpp Client which is trying to authenticate by SSO through SAML authentication. But client send request to the openfire server, It could not send challeng

I referred this documentation https://tools.ietf.org/html/rfc6595#section-5.1

I get this out put :

SEND: <stream:stream xmlns:stream=“http://etherx.jabber.org/streams” xmlns=“jabber:client” to=“skovdevof01” version=“1.0” >

RCV: <stream:stream xmlns:stream=“http://etherx.jabber.org/streams” xmlns=“jabber:client” from=“dkodev060” id=“cfc0102d” xml:lang=“en” version=“1.0” >

RCV: <stream:features xmlns:stream=“http://etherx.jabber.org/streams”>

SAML20

EXTERNAL

DIGEST-MD5

ANONYMOUS

CRAM-MD5

</stream:features>

SEND:

RCV:

SEND: <stream:stream xmlns:stream=“http://etherx.jabber.org/streams” xmlns=“jabber:client” to=“skovdevof01” version=“1.0” >

RCV: <stream:stream xmlns:stream=“http://etherx.jabber.org/streams” xmlns=“jabber:client” from=“dkodev060” id=“cfc0102d” xml:lang=“en” version=“1.0” >

RCV: <stream:features xmlns:stream=“http://etherx.jabber.org/streams”>

SAML20

EXTERNAL

DIGEST-MD5

ANONYMOUS

CRAM-MD5

zlib

</stream:features>

SEND: biwsc2tvdmRldm9mMDE=

RCV: </stream:stream>

SEND: </stream:stream>

I am currently using below Java method handle(…) of SASLAuthentication.java class.

public static Status handle(LocalSession session, Element doc) throws UnsupportedEncodingException {

Status status;

String mechanism;

if (doc.getNamespace().asXML().equals(SASL_NAMESPACE)) {

ElementType type = ElementType.valueof(doc.getName());

switch (type) {

case AUTH:

mechanism = doc.attributeValue(“mechanism”);

// Store the requested SASL mechanism by the client

session.setSessionData(“SaslMechanism”, mechanism);

//Log.debug("SASLAuthentication.doHandshake() AUTH entered: "+mechanism);

if (mechanism.equalsIgnoreCase(“ANONYMOUS”) &&

mechanisms.contains(“ANONYMOUS”)) {

status = doAnonymousAuthentication(session);

}

else if (mechanism.equalsIgnoreCase(“EXTERNAL”)) {

status = doExternalAuthentication(session, doc);

}

else if (mechanisms.contains(mechanism)) {

// The selected SASL mechanism requires the server to send a challenge

// to the client

try {

Map<String, String> props = new TreeMap<String, String>();

props.put(Sasl.QOP, “auth”);

if (mechanism.equals(“GSSAPI”)) {

props.put(Sasl.SERVER_AUTH, “TRUE”);

}

SaslServer ss = Sasl.createSaslServer(mechanism, “xmpp”,

JiveGlobals.getProperty(“xmpp.fqdn”, session.getServerName()), props,

new XMPPCallbackHandler());

// evaluateResponse doesn’t like null parameter

byte[] token = new byte[0];

if (doc.getText().length() > 0) {

// If auth request includes a value then validate it

token = StringUtils.decodeBase64(doc.getText().trim());

if (token == null) {

token = new byte[0];

}

}

if (mechanism.equals(“DIGEST-MD5”)) {

// RFC2831 (DIGEST-MD5) says the client MAY provide an initial response on subsequent

// authentication. Java SASL does not (currently) support this and thows an exception

// if we try. This violates the RFC, so we just strip any initial token.

token = new byte[0];

}

byte[] challenge = ss.evaluateResponse(token);

if (ss.isComplete()) {

authenticationSuccessful(session, ss.getAuthorizationID(),

challenge);

status = Status.authenticated;

}

else {

// Send the challenge

sendChallenge(session, challenge);

status = Status.needResponse;

}

session.setSessionData(“SaslServer”, ss);

}

catch (SaslException e) {

Log.info("User Login Failed. " + e.getMessage());

authenticationFailed(session);

status = Status.failed;

}

}

else {

Log.warn(“Client wants to do a MECH we don’t support: '” +

mechanism + “’”);

authenticationFailed(session);

status = Status.failed;

}

break;

case RESPONSE:

// Store the requested SASL mechanism by the client

mechanism = (String) session.getSessionData(“SaslMechanism”);

if (mechanism.equalsIgnoreCase(“EXTERNAL”)) {

status = doExternalAuthentication(session, doc);

}

else if (mechanism.equalsIgnoreCase(“JIVE-SHAREDSECRET”)) {

status = doSharedSecretAuthentication(session, doc);

}

else if (mechanisms.contains(mechanism)) {

SaslServer ss = (SaslServer) session.getSessionData(“SaslServer”);

if (ss != null) {

boolean ssComplete = ss.isComplete();

String response = doc.getTextTrim();

try {

if (ssComplete) {

authenticationSuccessful(session, ss.getAuthorizationID(),

null);

status = Status.authenticated;

}

else {

byte[] data = StringUtils.decodeBase64(response);

if (data == null) {

data = new byte[0];

}

byte[] challenge = ss.evaluateResponse(data);

if (ss.isComplete()) {

authenticationSuccessful(session, ss.getAuthorizationID(),

challenge);

status = Status.authenticated;

}

else {

// Send the challenge

sendChallenge(session, challenge);

status = Status.needResponse;

}

}

}

catch (SaslException e) {

Log.debug(“SASLAuthentication: SaslException”, e);

authenticationFailed(session);

status = Status.failed;

}

}

else {

Log.error(“SaslServer is null, should be valid object instead.”);

authenticationFailed(session);

status = Status.failed;

}

}

else {

Log.warn(

“Client responded to a MECH we don’t support: '” + mechanism + “’”);

authenticationFailed(session);

status = Status.failed;

}

break;

default:

authenticationFailed(session);

status = Status.failed;

// Ignore

break;

}

}

else {

Log.debug("SASLAuthentication: Unknown namespace sent in auth element: " + doc.asXML());

authenticationFailed(session);

status = Status.failed;

}

// Check if SASL authentication has finished so we can clean up temp information

if (status == Status.failed || status == Status.authenticated) {

// Remove the SaslServer from the Session

session.removeSessionData(“SaslServer”);

// Remove the requested SASL mechanism by the client

session.removeSessionData(“SaslMechanism”);

}

return status;

}

Kindly suggest me to resolve this Issue. Thank you