根据xmpp协议

客户端发送:

<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>XXXXXXXXXXXXXXXXXXXXX=</auth>

其中,xmlns是命名空间,mechanism是用户名密码的加密方式,auth 标签的text内容为用户名密码通过PLAIN方式加密的字符串。

服务端接收:

  通过ConnectionHandler类的messageReceived方法接收,process中处理

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

  判断xml标签为auth时进行登录验证。

  下面来看SASLAuthentication的处理

  首先判断加密方式,然后解密,通过下面这个方法来验证登录。

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

  根据加密方式不同,验证处理方法不同。PLAIN加密的,那就看SaslServerPlainImpl中是怎么实现的。

 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);}

  可以看到openfire是通过callback来验证的,而且还进行了2层验证。第一次是验证用户名密码,第二次是加载用户信息

(自己有需要修改源码时,这里就可以优化了,第一步登录验证时就可以获取用户信息了,没必要重新查询一次)。

  callback是通过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 authenticatedString 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 valueif (username != null && username.contains("@")) {username = username.substring(0, username.lastIndexOf("@"));}if (principal.equals(username)) {//client perhaps made no request, get default usernameusername = 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);}}

  第一次验证用户名密码是通过 AuthToken at = AuthFactory.authenticate(name, new String(vpcb.getPassword()));验证的

根据数据库配置provider.auth.className的类实现登录验证。

第二次验证AuthorizationManager.authorize(username, principal)会加载用户信息。2次验证通过就会返回客户端 <success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/> 表示登录成功。

转载于:https://www.cnblogs.com/fengIdea/p/6913902.html

openfire源码解读--用户登录相关推荐

  1. FilterSecurityInterceptor源码解读

    FilterSecurityInterceptor源码解读 FilterSecurityInterceptor概念: 获取所配置资源访问的授权信息,根据SecurityContextHolder中存储 ...

  2. Abp 业务异常源码解读

    Abp 业务异常源码解读 最近一直在读代码整洁之道,我在读到第三章函数的3.9 使用异常替代返回错误码,其实在我的开发经历中都是使用返回错误码给到前端,之前在阅读ABP官网文档中就有看到过使用异常替代 ...

  3. xxl-sso源码解读(基于Cookie)

    xxl-sso源码解读 文章目录 xxl-sso源码解读 前言 一.XXL-SSO是什么? 二.搭建步骤 三.系统简述 1.xxl-sso-server 2.xxl-sso-core 3. xxl-s ...

  4. Feflow 源码解读

    Feflow 源码解读 Feflow(Front-end flow)是腾讯IVWEB团队的前端工程化解决方案,致力于改善多类型项目的开发流程中的规范和非业务相关的问题,可以让开发者将绝大部分精力集中在 ...

  5. spring-session源码解读 sesion

    2019独角兽企业重金招聘Python工程师标准>>> spring-session源码解读 sesion 博客分类: java spring 摘要: session通用策略 Ses ...

  6. AFNetworking 3.0 源码解读(一)之 AFNetworkReachabilityManager

    做ios开发,AFNetworking 这个网络框架肯定都非常熟悉,也许我们平时只使用了它的部分功能,而且我们对它的实现原理并不是很清楚,就好像总是有一团迷雾在眼前一样. 接下来我们就非常详细的来读一 ...

  7. Spring5源码 - 05 invokeBeanFactoryPostProcessors 源码解读_2

    文章目录 Pre 源码解读 总体流程 源码分析 细节解析 [初始化对应的集合 & 遍历用户自己手动添加的后置处理器] [调用实现了PriorityOrdered接口的BeanDefinitio ...

  8. IOCP 网络通讯模型源码解读

    From: http://hi.baidu.com/tsingsing/item/1aa5062fa27791fa50fd87b7 以前写服务器的时候用的是iocp,最近偶然发现windows的 网络 ...

  9. LevelDB源码解读

    LevelDB源码解读 提供的功能 read and write Group commit sequence number delete Atomic Updates 同步写Synchronous W ...

  10. php yii框架源码,yii 源码解读

    date: 2017-11-21 18:15:18 title: yii 源码解读 本篇博客阅读指南: php & 代码提示: 工欲善其事必先利其器 yii 源码阅读指南: 整体上全貌上进行了 ...

最新文章

  1. vue虚拟don diff原理
  2. 最短路径(Dijkstra、Bellman-Ford和SPFA算法)
  3. java碳架公路车如何_骑全碳公路车是怎样的体验?
  4. linux(CentOs6)下jdk安装,mysql安装,tomcat安装,及web项目部署
  5. c# emnu 获取注释_C#教程推荐
  6. 无人驾驶、自动驾驶与驾驶辅助的区别
  7. 工具(1)---wireshark抓包
  8. js 清除html页面,如何清除使用JavaScript输入的HTML文件?
  9. 环信 之 注册及创建应用
  10. Java面试中经常被问到的问题有哪些?
  11. Boundary Representations
  12. JAVA的反射机制原理
  13. 简单电脑***《菜鸟级》
  14. html h3标签,网站h1,h2,h3标签的用法和技巧
  15. Mimics三维建模
  16. 计算经纬度、距离、方位角
  17. 小米6显示服务器出错,小米6解锁BL显示未连接手机解决办法以及各种小技巧汇总......
  18. 小米(xiaomi)红米(Redmi)手机一开机就自动重启:find device closed unexpectedly
  19. 创意分析及优化技巧 — 百度推广
  20. UE4天气效果加白天黑夜的平滑过度切换

热门文章

  1. MySQL学习(二、简单查询和多行、单行函数)
  2. Linux 给普通用户分配root权限或给用户分配多个用户组
  3. Oracle 常见错误代码处理 1
  4. ChannelHandler 接口继承关系图
  5. ps cs6导出html,渲染视频使用不了是怎么回事?pscs6ex – 手机爱问
  6. 阶段5 3.微服务项目【学成在线】_day01 搭建环境 CMS服务端开发_10-CMS服务端工程搭建-导入基础工程...
  7. 阶段3 3.SpringMVC·_01.SpringMVC概述及入门案例_04.入门程序之搭建开发环境
  8. 第四阶段 15_Linux tomcat安装与配置
  9. 玉伯的一道课后题题解(关于 IEEE 754 双精度浮点型精度损失)
  10. 高聚合和低耦合的理解