Openfire source code explanation-user logon and openfire source code

Source: Internet
Author: User

Openfire source code explanation-user logon and openfire source code

Based on xmpp protocol

Client sending:

<Auth xmlns = 'urn: ietf: params: xml: ns: xmpp-sasl 'mechanic = 'plain'> XXXXXXXXXXXXXXXXXXXXX = </auth>

Xmlns is the namespace, and mechanic is the encryption method of the user name and password. The text content of the auth tag is the string encrypted by the user name and password in PLAIN mode.

Received by the server:

Received through the messageReceived method of the ConnectionHandler class, Processed in process

     else if ("auth".equals(tag)) {            // User is trying to authenticate using SASL            startedSASL = true;            // Process authentication stanza            saslStatus = SASLAuthentication.handle(session, doc);        }

Logon verification is performed when the xml tag is auth.

The following describes how SASLAuthentication is handled.

First, determine the encryption method and decrypt it. Use the following method to verify logon.

final byte[] challenge = saslServer.evaluateResponse( decoded ); // Either a challenge or success data.

The verification method varies depending on the encryption method. PLAIN encryption, it depends on how SaslServerPlainImpl is implemented.

NameCallback ncb = new NameCallback("PLAIN authentication ID: ",principal);VerifyPasswordCallback vpcb = new VerifyPasswordCallback(password.toCharArray());cbh.handle(new Callback[]{ncb,vpcb});if (vpcb.getVerified()) {vpcb.clearPassword();AuthorizeCallback acb = new AuthorizeCallback(principal,username);cbh.handle(new Callback[]{acb});if(acb.isAuthorized()) {username = acb.getAuthorizedID();completed = true;} else {completed = true;username = null;throw new SaslException("PLAIN: user not authorized: "+principal);}} else {throw new SaslException("PLAIN: user not authorized: "+principal);}

We can see that openfire is verified through callback, and two layers of verification are also performed. The first is to verify the user name and password, and the second is to load user information

(If you need to modify the source code, you can optimize it here. You can obtain the user information during the first step of login verification. You do not need to query it again ).

Callback is implemented through XMPPCallbackHandler.

for (Callback callback : callbacks) {            if (callback instanceof RealmCallback) {                ((RealmCallback) callback).setText( XMPPServer.getInstance().getServerInfo().getXMPPDomain() );            }            else if (callback instanceof NameCallback) {                name = ((NameCallback) callback).getName();                if (name == null) {                    name = ((NameCallback) callback).getDefaultName();                }                //Log.debug("XMPPCallbackHandler: NameCallback: " + name);            }            else if (callback instanceof PasswordCallback) {                try {                    // Get the password from the UserProvider. Some UserProviders may not support                    // this operation                    ((PasswordCallback) callback)                            .setPassword(AuthFactory.getPassword(name).toCharArray());                    //Log.debug("XMPPCallbackHandler: PasswordCallback");                }                catch (UserNotFoundException | UnsupportedOperationException e) {                    throw new IOException(e.toString());                }            }            else if (callback instanceof VerifyPasswordCallback) {                //Log.debug("XMPPCallbackHandler: VerifyPasswordCallback");                VerifyPasswordCallback vpcb = (VerifyPasswordCallback) callback;                try {                    AuthToken at = AuthFactory.authenticate(name, new String(vpcb.getPassword()));                    vpcb.setVerified((at != null));                }                catch (Exception e) {                    vpcb.setVerified(false);                }            }            else if (callback instanceof AuthorizeCallback) {                //Log.debug("XMPPCallbackHandler: AuthorizeCallback");                AuthorizeCallback authCallback = ((AuthorizeCallback) callback);                // Principal that authenticated                String principal = authCallback.getAuthenticationID();                // Username requested (not full JID)                String username = authCallback.getAuthorizationID();                // Remove any REALM from the username. This is optional in the spec and it may cause                // a lot of users to fail to log in if their clients is sending an incorrect value                if (username != null && username.contains("@")) {                    username = username.substring(0, username.lastIndexOf("@"));                }                if (principal.equals(username)) {                    //client perhaps made no request, get default username                    username = AuthorizationManager.map(principal);                    if (Log.isDebugEnabled()) {                        //Log.debug("XMPPCallbackHandler: no username requested, using " + username);                    }                }                if (AuthorizationManager.authorize(username, principal)) {                    if (Log.isDebugEnabled()) {                        //Log.debug("XMPPCallbackHandler: " + principal + " authorized to " + username);                    }                    authCallback.setAuthorized(true);                    authCallback.setAuthorizedID(username);                }                else {                    if (Log.isDebugEnabled()) {                        //Log.debug("XMPPCallbackHandler: " + principal + " not authorized to " + username);                    }                    authCallback.setAuthorized(false);                }            }

The username and password are verified by AuthToken at = AuthFactory. authenticate (name, new String (vpcb. getPassword ().

Perform logon Verification Based on the class of provider. auth. className configured in the database.

Second VerificationAuthorizationManager. authorize (username, principal) loads user information.
After two verification passes, the client <success xmlns = 'urn: ietf: params: xml: ns: xmpp-sasl '/> is returned, indicating that the logon is successful.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.