iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >Mysql用户认证的原理是什么
  • 510
分享到

Mysql用户认证的原理是什么

2024-04-02 19:04:59 510人浏览 薄情痞子
摘要

Mysql用户认证的原理是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。 一、用户认证原理    &nb

Mysql用户认证的原理是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

一、用户认证原理

      我们在应用程序中实现验证的方式基本上都是创建一张用户表,里面至少包含username和passWord两个字段,

password基本上都是加密后进行存储的。作为数据库,对用户的限制较多,不是像我说的仅仅只有username和password

这么简单了。首先粗略的讲下访问控制。

     信息系统中,访问控制分为自主访问控制(DAC)和强制访问控制(Mac)。具体到DBMS,自主访问控制就是我们所熟悉

的GRANT,REVOKE,大多数数据库都支持自助的访问控制。强制访问控制就是oracle中的LABEL,只有很少的一些系统支持MAC。

严格来说,登录并不属于访问控制机制,而应该属于用户身份识别和认证。在mysql中,将登录和DAC的相关接口都实现在了

sql_acl.cc中(其实说登录是用户拥有的一种权限也未尝不可,正如ORACLE中的CREATE SESSioN,不过登录并不仅仅是一种权

限,还包含很多其他的属性),从文件名大家可以看出来,ACL即ACCESS CONTROL LIST,访问控制列表,这是实现访问控制的

基本方法。下图是Mysql的整个访问控制的流程。

    Mysql中用户管理模块的信息存储在系统表mysql.User中,这个表不仅仅存放了授权用户的基本信息,还存放一些权限

信息。我们首先大概看一下这个表的结构。

+-----------------------+-----------------------------------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+-----------------------+-----------------------------------+------+-----+---------+-------+

| Host | char(60) | NO | PRI | | |

| User | char(16) | NO | PRI | | |

| Password | char(41) | NO | | | |

| Select_priv | enum('N','Y') | NO | | N | |

| Insert_priv | enum('N','Y') | NO | | N | |

| Update_priv | enum('N','Y') | NO | | N | |

| Delete_priv | enum('N','Y') | NO | | N | |

| Create_priv | enum('N','Y') | NO | | N | |

| Drop_priv | enum('N','Y') | NO | | N | |

| Reload_priv | enum('N','Y') | NO | | N | |

| Shutdown_priv | enum('N','Y') | NO | | N | |

| Process_priv | enum('N','Y') | NO | | N | |

| File_priv | enum('N','Y') | NO | | N | |

| Grant_priv | enum('N','Y') | NO | | N | |

| References_priv | enum('N','Y') | NO | | N | |

| Index_priv | enum('N','Y') | NO | | N | |

| Alter_priv | enum('N','Y') | NO | | N | |

| Show_db_priv | enum('N','Y') | NO | | N | |

| Super_priv | enum('N','Y') | NO | | N | |

| Create_tmp_table_priv | enum('N','Y') | NO | | N | |

| Lock_tables_priv | enum('N','Y') | NO | | N | |

| Execute_priv | enum('N','Y') | NO | | N | |

| Repl_slave_priv | enum('N','Y') | NO | | N | |

| Repl_client_priv | enum('N','Y') | NO | | N | |

| Create_view_priv | enum('N','Y') | NO | | N | |

| Show_view_priv | enum('N','Y') | NO | | N | |

| Create_routine_priv | enum('N','Y') | NO | | N | |

| Alter_routine_priv | enum('N','Y') | NO | | N | |

| Create_user_priv | enum('N','Y') | NO | | N | |

| Event_priv | enum('N','Y') | NO | | N | |

| Trigger_priv | enum('N','Y') | NO | | N | |

| ssl_type | enum('','ANY','X509','SPECIFIED') | NO | | | |

| ssl_cipher | blob | NO | | NULL | |

| x509_issuer | blob | NO | | NULL | |

| x509_subject | blob | NO | | NULL | |

| max_questions | int(11) unsigned | NO | | 0 | |

| max_updates | int(11) unsigned | NO | | 0 | |

| max_connections | int(11) unsigned | NO | | 0 | |

| max_user_connections | int(11) unsigned | NO | | 0 | |

+-----------------------+-----------------------------------+------+-----+---------+-------+

39 rows in set (0.01 sec)

   这个表包含了39个字段,对于我们登录来说,应该主要是使用前三个字段,即Host,User,Password。

mysql> select Host,User,Password from user;

+-----------+------+----------+

| Host | User | Password |

+-----------+------+----------+

| localhost | root | |

| 127.0.0.1 | root | |

| localhost | | |

+-----------+------+----------+

3 rows in set (0.00 sec)

    这里比我们预想的只需要用户名和密码的方式有所出入,多了一个Host字段,这个字段起到什么作用呢?!原来Mysql的登录认证不仅需要验证用户名和密码,还需要验证连接的主机地址,这样也是为了提高安全性吧。那如果我想一个用户在任何地址都可以进行登录岂不是要设置很多地址?Mysql提供了通配符,可以设置Host字段为*,这就代表可以匹配任何Host。具体看下这三行的意思,这三行的密码均为空。针对root用户,不需要输入密码,客户端的地址为本机。第三行的用户名为空,Host为localhost,说明本地的任何用户均可以进行登录,即使是个不存在的用户也可以登录成功,但是仅限于登录,没有其他相关的权限,无法进行实际操作。

二、跟踪

       在Connection Manager中提到了login_connection函数用于检查用户名和密码等相关信息,其源码如下(重点的函数代码

会着色):

static bool login_connection(THD *thd)

{

  NET *net= &thd->net;

  int error;

  DBUG_ENTER("login_connection");

  DBUG_PRINT("info", ("login_connection called by thread %lu",

                      thd->thread_id));

 

  my_net_set_read_timeout(net, connect_timeout);

  my_net_set_write_timeout(net, connect_timeout);

error= check_connection(thd); //此处是验证的具体函数

  net_end_statement(thd);

  if (error)

  {                        // Wrong permissions

#ifdef __NT__

    if (vio_type(net->vio) == VIO_TYPE_NAMEDPIPE)

      my_sleep(1000);               

#endif

    statistic_increment(aborted_connects,&LOCK_status);

    DBUG_RETURN(1);

  }

 

  my_net_set_read_timeout(net, thd->variables.net_read_timeout);

  my_net_set_write_timeout(net, thd->variables.net_write_timeout);

  DBUG_RETURN(0);

}

此函数主要是功能是调用函数check_connection进行用户认证,由于函数check_connection过长,对其进行简化,如下所示:

 static int check_connection(THD *thd)

{

  uint connect_errors= 0;

  NET *net= &thd->net;

  ulong pkt_len= 0;

  char *end;

  DBUG_PRINT("info",

             ("New connection received on %s", vio_description(net->vio)));

#ifdef SIGNAL_WITH_VIO_CLOSE

  thd->set_active_vio(net->vio);

#endif

  if (!thd->main_security_ctx.host)         // If tcp/IP connection

  {

    char ip[30];

    if (vio_peer_addr(net->vio, ip, &thd->peer_port))

    {

      my_error(ER_BAD_HOST_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);

      return 1;

    }

    if (!(thd->main_security_ctx.ip= my_strdup(ip,MYF(MY_WME))))

      return 1;

    thd->main_security_ctx.host_or_ip= thd->main_security_ctx.ip;

    vio_in_addr(net->vio,&thd->remote.sin_addr);

    if (!(specialflag & SPECIAL_NO_RESOLVE))

    {

      vio_in_addr(net->vio,&thd->remote.sin_addr);

      thd->main_security_ctx.host=

        ip_to_hostname(&thd->remote.sin_addr, &connect_errors);

     

      if (thd->main_security_ctx.host)

      {

        if (thd->main_security_ctx.host != my_localhost)

          thd->main_security_ctx.host[min(strlen(thd->main_security_ctx.host),

                                          HOSTNAME_LENGTH)]= 0;

        thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;

      }

      if (connect_errors > max_connect_errors)

      {

        my_error(ER_HOST_IS_BLOCKED, MYF(0), thd->main_security_ctx.host_or_ip);

        return 1;

      }

    }

    ...

if (acl_check_host(thd->main_security_ctx.host, thd->main_security_ctx.ip))//此处验证主机名或IP是否存在

    {

      my_error(ER_HOST_NOT_PRIVILEGED, MYF(0),

               thd->main_security_ctx.host_or_ip);

      return 1;

    }

  }

  else

  {

   ...

  }

  vio_keepalive(net->vio, TRUE);

  ...

  char *user= end;

  char *passwd= strend(user)+1;

  uint user_len= passwd - user - 1;

  char *db= passwd;

  char db_buff[NAME_LEN + 1];           // buffer to store db in utf8

  char user_buff[USERNAME_LENGTH + 1];    // buffer to store user in utf8

  uint dummy_errors;

  uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?

    (uchar)(*passwd++) : strlen(passwd);

  db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?

    db + passwd_len + 1 : 0;

  uint db_len= db ? strlen(db) : 0;

  if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len)

  {

    inc_host_errors(&thd->remote.sin_addr);

    my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);

    return 1;

  }

...

 

  if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'')

  {

    user[user_len-1]= 0;

    user++;

    user_len-= 2;

  }

  if (thd->main_security_ctx.user)

    x_free(thd->main_security_ctx.user);

  if (!(thd->main_security_ctx.user= my_strdup(user, MYF(MY_WME))))

    return 1;

  return check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE);//验证用户名和密码

}

上面的源码主要做了如下几件事情:

获取客户端的IP和主机名

acl_check_host函数验证USER表中是否存在相应的IP或HOST,如果不存在直接报错

获取用户名和密码

check_user函数验证用户名和密码(不输入用户名默认为ODBC),如果系统表中不存在匹配的报错返回

获取用户的权限列表,验证用户的相关属性是否合法,如连接数是否超过上限,连接是否超时,操作是否超过限制等信息,如果不合法,则报错返回。

    由于在一个认证的过程中涉及到的东西比较多,各个方面吧,我不能一一跟踪,只能大概了解其中的实现流程,捡重点进行

跟踪,有兴趣的童鞋自己具体跟踪吧

题外话:

    Mysql中权限系统表都是在系统启动时,载入内存的(当然User表也是这样),一般情况下,不需要进行频繁的授权和回收

操作,这中情况下,权限表基本保持不变,将其在系统启动的时候载入内存的好处自然是快速的进行权限判断,减少磁盘的I/O,

你懂的^_^。有好处自然有坏处,就是在频繁进行授权和回收相关操作时,权限表需要重新载入内存,Mysql为了避免这种情况,

在手册中已经说的很清楚了,授权和回收只会反应到磁盘中,内存的数据字典信息是不会改变的,如果想立即生效,需要调用

FLUSH PRIVILEGES系统函数,这个系统函数的工作应该就是对权限系统表的RELOAD。

看完上述内容,你们掌握Mysql用户认证的原理是什么的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注编程网数据库频道,感谢各位的阅读!

您可能感兴趣的文档:

--结束END--

本文标题: Mysql用户认证的原理是什么

本文链接: https://www.lsjlt.com/news/58607.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Mysql用户认证的原理是什么
    Mysql用户认证的原理是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。 一、用户认证原理    &nb...
    99+
    2024-04-02
  • 服务器ssl认证的原理是什么
    服务器 SSL 认证的原理是通过使用公钥和私钥来加密和解密数据。当用户连接到服务器时,服务器会向客户端发送一个公钥,客户端使用该公钥...
    99+
    2023-06-11
    ssl认证 ssl
  • Laravel unit test : 模拟认证的用户是什么
    小编给大家分享一下Laravel unit test : 模拟认证的用户是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Laravel 是什么Laravel ...
    99+
    2023-06-14
  • MySQL密码验证的原理是什么
    这篇文章给大家介绍MySQL密码验证的原理是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。 1.服务器端会随机生成一个random string发送给客户端; ...
    99+
    2024-04-02
  • MongoDB管理用户的认证机制是怎样的
    MongoDB管理用户的认证机制是怎样的,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、MongoDB用户认证机制简介为了认证客户端,你必须...
    99+
    2024-04-02
  • MySQL的默认用户名和密码是什么
    这篇文章主要介绍MySQL的默认用户名和密码是什么,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!MySQL是一种关系数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据...
    99+
    2024-04-02
  • 云服务器新用户认证试用的方法是什么
    云服务器新用户认证试用的方法通常包括以下步骤:1. 注册账号:首先,用户需要在云服务器提供商的官方网站上注册一个新的账号。2. 选择...
    99+
    2023-09-27
    云服务器
  • MySQL如何实现Apache用户认证
    这篇文章主要介绍MySQL如何实现Apache用户认证,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!apache要求DSO方式编译安装,假定apache安装在/usr/local/a...
    99+
    2024-04-02
  • 什么是CA认证
    CA认证是指数字证书认证中心(Certification Authority)的认证。数字证书认证中心是为网络通信提供安全性和信任的...
    99+
    2023-09-20
    CA认证
  • token认证是什么
    这篇文章主要介绍了token认证是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇token认证是什么文章都会有所收获,下面我们一起来看看吧。以前的开发模式是以MVC为主,但是随着互联网行业快速的发展逐渐的演...
    99+
    2023-06-27
  • 什么是Zabbix的LDAP认证
    Zabbix的LDAP认证是指利用LDAP(轻量级目录访问协议)来实现对Zabbix系统的用户认证和授权管理。通过LDAP认证,用户...
    99+
    2024-04-02
  • Git认证失败的原因是什么及怎么解决
    这篇文章主要介绍“Git认证失败的原因是什么及怎么解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Git认证失败的原因是什么及怎么解决”文章能帮助大家解决问题。一、Git认证失败的原因凭证缓存失效...
    99+
    2023-07-05
  • ssl认证的流程是什么
    ssl认证的流程是:1、按照要求把证书配置到网站服务器中;2、客户端会直接向服务器发送一个接入请求;3、服务器接受到请求后,会将证书...
    99+
    2023-02-09
    ssl认证 ssl
  • Kerberos认证原理与使用教程
    Kerberos认证原理与使用教程 一、Kerberos 概述 二、什么是 Kerberos ​ Kerberos 是一种计算机网络认证协议,用来在非安全网络中,对个人通信以安全的手段进行身份认证。这个词又指麻省理工学院为这个协议开发的一套...
    99+
    2023-08-21
    网络 服务器 运维
  • MongoDB的权限管理与用户认证怎么实现
    MongoDB的权限管理和用户认证是通过创建用户和设置角色来实现的。下面是MongoDB权限管理和用户认证的步骤: 创建管理员用...
    99+
    2024-05-07
    MongoDB
  • 网站ssl证书的原理是什么
    SSL证书的原理是通过使用非对称加密算法和数字签名来确保网站与浏览器之间的安全通信。具体原理如下:1. 首先,网站服务器需要生成一个...
    99+
    2023-08-24
    ssl证书
  • 阿里云认证代理公司是什么
    阿里云认证代理公司提供的服务涵盖了多个领域,如云服务器、云数据库、云网络、云安全等。代理公司为用户提供一站式服务,帮助用户轻松实现云服务器部署、运维、管理等工作,降低用户的技术门槛和运维成本。 在选择阿里云认证代理公司时,需要考虑以下几个...
    99+
    2023-10-27
    阿里 公司
  • MySQL中MyISAM默认存储引擎的实现原理是什么
    这篇文章将为大家详细讲解有关MySQL中MyISAM默认存储引擎的实现原理是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。默认MyISAM的表会在磁盘中产生3个文件:...
    99+
    2024-04-02
  • python中ssl认证指的是什么
    这篇文章将为大家详细讲解有关python中ssl认证指的是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。python的数据类型有哪些python的数据类型:1. 数字类型,包括int(整型)、long...
    99+
    2023-06-14
  • Grafana怎么实现用户认证和权限管理
    在Grafana中,用户认证和权限管理可以通过以下步骤实现: 配置数据源:首先,您需要配置Grafana与数据源的连接。可以连接...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作