转:http://blog.csdn.net/coding_me/article/details/39524137
SASL  的认证方式包括:
    1. PLAIN:plain是最简单的机制,但同时也是最危险的机制,因为身份证书(登录名称与密码)是以base64字符串格式通过网络,没有任何加密保护措施。因此,使用plain机制时,你可能会想要结合tls。
     

2.DIGEST-MD5:使用这种机制时,client与server共享同一个隐性密码,而且此密码不通过网络传输。验证过程是从服务器先提出challenge(质询)开始, 客户端使用此challenge与隐性密码计算出一个response(应答)。不同的challenge,不可能计算出相同的response;任何拥 有secret password的一方,都可以用相同的challenge算出相同的response。因此,服务器只要比较客户端返回的response是否与自己算 出的response相同,就可以知道客户端所拥有的密码是否正确。由于真正的密码并没有通过网络,所以不怕网络监测。

      3. anonymous:  anonymous机制对smtp没有意义,因为smtp验证的用意在于限制转发服务的使用对象,而不是为了形成open relay,sasl之所以提供这种机制,主要是为了支持其他协议。
 
     PLAIN 方式的认证流程:
         由于是在SASL的认证方式,所以客户端必须要打开SASL认证的模式。
          config.setSecurityMode(SecurityMode.enabled);
 
    config.setSASLAuthenticationEnabled( true);
 
  并且在客户端要声明,客户端必须支持PLAIN模式:
   
    SASLAuthentication.supportSASLMechanism("PLAIN");
 
   这样再客户端接下的来的认证过程中就会传输:
    <auth mechanism="PLAIN" xmlns="urn:ietf:params:xml:ns:xmpp-sasl">c3lzYWRtaW4Ac3lzYWRtaW4AMTIz</auth> 数据包,接下来服务器端就会对这个数据包进贤处理。
 
   我的服务器端是结合中Openfire进行开发的,当数据包到达时,服务器端会进行如下处理:
   if ("auth" .equals(tag)) {
               // User is trying to authenticate using SASL
               startedSASL = true;
               // Process authentication stanza
               saslStatus = SASLAuthentication.handle(session, doc);
 
  在服务器端接下来的处理过程中,就是通过SaslServer 来进行客户端用户名和密码的认证。SaslServer进行java.sercurity 中的类。
  
 
       SaslServer ss = Sasl.createSaslServer(mechanism,
                                       "xmpp", session.getServerName(), props,
                                       new XMPPCallbackHandler());
 
   这里主要使用SaslServer 创建SASL服务器端。
   制创建一个 SaslServer。 此方法使用 JCA Security Provider Framework(在 "Java Cryptography Architecture API Specification & Reference" 中所有描述)来查找和选择 SaslServer 实现。 首先,它从 "SaslServerFactory" 服务的已注册安全提供者和指定的 SASL 机制中获得 SaslServerFactory 实例的有序列表。然后它在列表中的每个工厂实例上调用 createSaslServer(),直到某个调用生成一个非 null 的 SaslServer 实例为止。此方法返回非 null 的 SaslServer 实例,如果搜索无法生成非 null 的SaslServer 实例,则返回 null。
 
   在这里在Openfire中的:org.jivesoftware.openfire.sasl 中的SaslServerFactoryImpl 类实现了,javax.security.sasl.SaslServerFactory,这样在创建SaslServer的时候,就会调用这个具体的实现来进行创建。
     在这里在SASLAuthentication 的初始化过程中,在initMechanisms 方法中,就初始化了SaslServerFactory 的类的路径。
  在程序运行过程中,就会根据客户端发送的PLAIN 模式,创建SaslServer,并进行处理。
  在SaslServerPlainImpl 类中,可以获得客户端发送过来的用户名和密码,这里都是明文进行了传输,可以获得客户端发送的数据。这样   在XMPPCallbackHandler 中就可以获得客户端发送的用户名和密码,然后接下来就是对用户的用户名和密码进行认证。
 
 
  

DIGEST-MD5 :

    当服务器端支持  DIGEST-MD5 时,如果客户端不明确声明支持的认证方式,默认会使用 DIGEST-MD5 来进行客户端的认证。
    在认证过程中客户端发送:<auth mechanism="DIGEST-MD5" xmlns="urn:ietf:params:xml:ns:xmpp-sasl"></auth>
  服务器端,接收到消息后进行处理:
    if (mechanisms .contains(mechanism)) {
                         // 被选的SASL的机制,需要服务器发送一个 challenge
 
                        System. out.println( "password------------call---back----"
                                  + mechanism);
                         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", 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()) {
                                  System. out.println( "ss------------------has---complete--------" );
                                   authenticationSuccessful(session,
                                           ss.getAuthorizationID(), challenge);
                                  status = Status.authenticated;
                             } else {
                                  System. out.println( "ss----------not--------has---complete--------" );
                                   // Send the challenge
                                   sendChallenge(session, challenge);
                                  status = Status.needResponse;
                             }
                             session.setSessionData( "SaslServer", ss);
 在这里服务器端接收客户端发送的数据信息,并且创建SaslServer ,在创建 SaslServer server的时候,会在  java.security.Provider 中查询,服务器端设置的进行对认证方式实例化的类,,在这里继承的 java.security.Provider 的类中,没有定义对  DIGEST-MD5 的具体实现,就采用系统默认的方式来实例化 SaslServer。接下来的过程就是服务器端向客户端发送 challenge 数据包,
     <challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">cmVhbG09InNtYXJ0Y29vbCIsbm9uY2U9Ind2aGNoTTFsS0dudXY0dFpOUDZxWlp3dG5WUENkTHRDUDdBNkVLcWoiLHFvcD0iYXV0aCIsY2hhcnNldD11dGYtOCxhbGdvcml0aG09bWQ1LXNlc3M=</challenge>
 
然后客户端发送,response 数据包进行匹配:
    <response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">dXNlcm5hbWU9InN5c2FkbWluIixyZWFsbT0ic21hcnRjb29sIixjbm9uY2U9IjM3ZjJmNWUwMTQ3MWQ4ZWNkOWFmZWE1MjQyYWIyODMyMjE3MWNjOWNmNzU3MzczNTA1MGY2MjU1MjE2NTUzOTUiLG5jPTAwMDAwMDAxLHFvcD1hdXRoLGRpZ2VzdC11cmk9InhtcHAvc21hcnRjb29sIixyZXNwb25zZT04ODBlMGU5YmYxZDYyMzI4Mjg5Nzg5MDYwNzAyNTQ5ZCxjaGFyc2V0PXV0Zi04LG5vbmNlPSJ3dmhjaE0xbEtHbnV2NHRaTlA2cVpad3RuVlBDZEx0Q1A3QTZFS3FqIg==</response>
 
  然后也会调用对应的 NameCallBack 和 PasswordCallBack 来验证登录用户的用户名和密码。
 
  当认证成功后,服务端发送:
     <success xmlns="urn:ietf:params:xml:ns:xmpp-sasl">cnNwYXV0aD1iNWI4YmQ5Y2NjYjAyYjNiMDcxMDgzNzA5NDJiZDA4Yg==</success>
  这样客户端和服务器就认证成功了。
 
  3.anonymous 匿名登录:
       客户端在登录时,指明登录的方式,connection.loginAnonymously();
    客户端在认证时,发送数据包:<auth mechanism="ANONYMOUS" xmlns="urn:ietf:params:xml:ns:xmpp-sasl"></auth> 指明认证的方式为:ANONYMOUS。
     
      服务器端接收数据后,进行处理:
      
 
        在处理时:
  
         
     直接向客户端发送认证成功的数据包:

(转)Openfire 中SASL的认证方式之:PLAIN,DIGEST-MD5,anonymous的更多相关文章

  1. http协议Authorization认证方式在Android开发中的使用

    我们都知道,http协议是一种无状态协议,在Web开发中,由于Session和Cookie的使用,使得服务端可以知道客户端的连接状态,即用户只需要在浏览器上登录一次,只要浏览器没有关闭,后续所有的请求 ...

  2. 批量检测GoAhead系列服务器中Digest认证方式的服务器弱口令

    最近在学习用python写爬虫工具,某天偶然发现GoAhead系列服务器的登录方式跟大多数网站不一样,不是采用POST等方法,通过查找资料发现GoAhead是一个开源(商业许可).简单.轻巧.功能强大 ...

  3. 在Openfire中使用自己的数据表之修改配置文件

    目前我使用的Openfire版本是3.10.3,以下使用说明也是在这个版本上做的修改. Openfire提供了两种方式使用用户数据表.一种是安装完成之后默认实现的org.jivesoftware.op ...

  4. Linux中Postfix邮件认证配置(五)

    Postfix+Dovecot+Sasl工作原理 1.A用户使用MUA客户端借助smtp协议登陆smtpd服务器,需要先进行用户和密码认证,而SMTPD服务器端支持sasl认证,例如有一个sasl客户 ...

  5. ASP.NET Core 中的那些认证中间件及一些重要知识点

    前言 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系列(一,二,三)奠定一下基础. 有关于 Authentication 的知识太广,所以本篇介绍几个在 A ...

  6. [转]ASP.NET Core 中的那些认证中间件及一些重要知识点

    本文转自:http://www.qingruanit.net/c_all/article_6645.html 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系 ...

  7. ZeroMQ接口函数之 :zmq_curve – 安全的认证方式和保密方式

    ZeroMQ 官方地址 :http://api.zeromq.org/4-0:zmq_curve zmq_curve(7) ØMQ Manual - ØMQ/4.1.0 Name zmq_curve  ...

  8. 在asp.net WebAPI 中 使用Forms认证和ModelValidata(模型验证)

    一.Forms认证 1.在webapi项目中启用Forms认证 Why:为什么要在WebAPI中使用Forms认证?因为其它项目使用的是Forms认证. What:什么是Forms认证?它在WebAP ...

  9. C#开发中Windows域认证登录2(扩展吉日嘎拉GPM系统)

    原文地址:http://www.cuiwenyuan.com/shanghai/post/Windows-AD-Logon-Intergrated-into-Jirigala-GPM-DotNet-B ...

随机推荐

  1. 【Flutter学习】事件处理与通知之通知(Notification)

    一,概述 Notification是Flutter中一个重要的机制,在Widget树中,每一个节点都可以分发通知,通知会沿着当前节点(context)向上传递,所有父节点都可以通过Notificati ...

  2. jdbc 事物

    package transaction; import jdbc.utils.*; import java.sql.Connection; import java.sql.PreparedStatem ...

  3. appium-Android的驱动程序

    Appium Android Driver是Android设备的测试自动化工具.Appium Android驱动程序自动化原生的,混合的和移动的Web应用程序,在模拟器,仿真器和真实设备上进行测试.A ...

  4. Angular项目中迭代生成的树,激活选中的节点,并将节点数据发送到父节点

    从后台返回的数据,还有多层子节点,需要一个生成树的组件,如果直接在页面上写循环来拼接感觉会很麻烦,因为数据的层级结构不固定. 参考网上其他人的方法,整理如下: 1. 创建一个用于循环迭代的组件,在父组 ...

  5. error LNK2005: __get_invalid_parameter_handler 已经在 LIBCMTD.lib(invarg.obj) 中定义

    转自VC错误http://www.vcerror.com/?p=166 问题描述: 在用vs2012编译程序的时候,release版本正常编译通过,但Debug版本提示下面的很多错误; 1>LI ...

  6. 人物-IT-周鸿祎:百科

    ylbtech-人物-IT-周鸿祎:百科 周鸿祎(zhōu hóng yī),1970年10月4日生于湖北省黄冈市蕲春县.360公司创始人.董事长兼CEO.奇酷CEO.九三学社中央委员.九三学社中央科 ...

  7. oracle 中和mysql的group_concat有同样作用的写法

    所有版本的oracle都可以使用select wm_concat(name) as name from user;但如果是oracle11g,使用select listagg(name, ',') w ...

  8. java多线程学习笔记(四)

    上一节讲到Synchronized关键字,synchronized上锁的区域:对象锁=方法锁/类锁 本节补充介绍一下synchronized锁重入: 关键字synchronized拥有锁重入的功能,也 ...

  9. 14.Jmeter聚合报告各项含义

    Aggregate Report 是 JMeter 常用的一个 Listener,中文为“聚合报告” Label:每个 JMeter 的 element(例如 HTTP Request)都有一个 Na ...

  10. 03、python的基础-->str字符串的使用

    1.字符串首字母大写 s = "aksjdjjhfhdhjaGGGGkkk" s1 = s.capitalize() print(s1) 2.字符串全部字母大写 s = " ...