1. 限制用户访问的方式:
1. 限制访问服务的客户端主机
2. 需要用户名和密码
2. 行为用户验证需要两步:
1. 创建一个包含用户名和密码的文件
2. 服务器上的哪些资源需要保护,哪些用户可以进行访问
3. 创建用户数据库
许多用户名和密码需要创建在一个文件中。出于安全考虑,这个文件不能放在文档目录里。在这个例子里,这个文件创建在/usr/local/etc/httpd目录里,名字叫users。
这个文件包含许多用户名和密码。用户名和密码通过冒号分割,每个用户单独占一行。但是你不能直接在这个文件中直接输入用户名和密码,因为存储在这个文件中的密码是加密的。程序htpasswd可以用来创建该文件,添加或者修改用户。
使用htpasswd创建该文件,添加用户名‘snow’,密码‘snow’的用户到该文件(/usr/local/httpd/user)
1 htpasswd -c /usr/local/etc/httpd/users snow
-c参数告诉htpasswd创建一个新的users文件。当你运行该命令时,将提示输入该用户的密码并确认。你可以添加其它的用户到该文件中,不过必须去掉-c参数。这个命名也可以用来修改密码。当你添加一个用户后,/usr/local/etc/httpd/users文件看起来想这样:
1 snow:$apr1$VmvJWi7o$diZjyiUiHkd8pSmb/8/gE0
第一个列是用户名,第二列是加密过后的密码。
4. 配置服务
为了让server使用在该文件中的用户名和密码,你需要配置一个realm,为了使用.htaccess文件限制一个目录的访问,你首先需要修改apache的配置文件(如何找到apache的配置文件),使目录使用.htaccess的形式限制访问,这个被AuthConfig属性控制,如果你想限制/var/www目录的访问,你修改apache的配置文件:
1 <Directory /var/www/> 2 Options Indexes FollowSymLinks 3 AllowOverride AuthConfig 4 Require all granted 5 </Directory>
然后在/var/www目录中建立一个.htaccess文件,内容如下:
AuthName "restricted stuff" AuthType Basic AuthUserFile /usr/local/etc/httpd/users require valid-user
第一个指令AuthName,为这个资源配置一个realm名字,只要用户输入有效的用户名和密码,相同realm名字的其他资源也可以通过这个用户访问,这样做,主要是为了创建两个区域,使同一个用户可以访问这两个区域。
第二个指令AuthType告诉服务使用哪种协议进行认证,目前来说,仅有Baisc可用。但是出现了Digest,而且已经被标准化啦,只要浏览器实现了它,就可以使用它。digest认证比Basic认证更安全。
第三个指令AuthUserFile告诉服务被htpasswd创建的文件在哪里。
第四个指令require告诉服务该文件中的哪些用户可以访问该文件,valid-user参数是告诉服务该文件中的任何用户都可以访问该资源,你也可以配置特定用户可以访问该资源。例如:
require user snow john
只有snow,john两个用户可以访问该资源,其他用户都会被拒绝。
如果一个用户被允许访问不同的区域,他们仅仅需要输入一次密码,但是如果在不同的区域有不同的realm,用户需要再次输入他的密码。
5. 使用Groups
如果你想要users文件的一些用户访问一个资源,你需要在require行列出所有的用户,如果你有很多用户的话,这种方式是不太好的。有一种方式可以解决这种问题,就是用一个group文件,你可以使用require行限制到特定的group。例如:有一个叫作staff的组,它包含所有访问特定资源的用户。
1 require group staff
多个group也可以使用,用户也可以同时使用,
require group staff admin
require user adminuser
它允许组staff和admin访问资源和用户adminuser访问资源。
group文件的形式:
staff: martin jane
admin: art adminuser
staff和admin是组,martin和jane属于staff组,art和adminuser属于admin组。
AuthGroupFile指令是告诉group文件在哪里。记住,在group文件中一行的最大长度是8000字符(大约8K),如果你有超过行的长度的用户数,你可以再写一行伴随着相同组。
当你添加AuthGroupFIle指令时,遇到如下错误时:/var/www/html/.htaccess: Invalid command 'AuthGroupFile', perhaps misspelled or defined by a module not included in the server configuration。请执行:
1 sudo a2enmod authz_groupfile
6. 伴随着许多用户的问题
使用htpasswd创建用户和以文本的形式管理组相对来说比较简单,但是如果用户增多,服务器要做许多的处理来找响应的组和密码信息,这种处理必须在每个请求中都要做(受保护的区域,尽管用户仅仅输入一次密码,但是在每次请求中,都必须重新认证),如果伴随着很多用户,那是相当慢的,增加服务器负载。比较块的访问是使用DBM格式文件,它允许服务做比较块的搜索,但是管理DBM文件也是比较复杂的。
7. 存储用户信息的其他方式
apache仅能访问在文本文件中的用户信息,但是有各种各样的模块允许用户信息存储到数据库中。除了有DBM格式(mod_auth_dbm module),用户信息和组信息也可以存储以DB的格式文件(mod_auth_db),或者各种各样的数据库也可以使用。例如mSQL(mod_auth_msql),Postgres95(mod_auth_95),或者兼容DBI的数据库(mod_auth_dbi),也可以有一个额外的程序检测用户和密码是否有效(主要是用接口来检测数据库或者认证服务)。modules也可以用来检测系统密码文件或者使用Kerberos系统。
8. 限制不同的方法
在上面的例子中,require指令并没有包含在<Limit>指令中,这样意味着它应用到所有的请求方法,但是在一些应用中,需要将其放入<Limit>部分,例如:
1 <Limit GET POST PUT> 2 require valid-user 3 </Limit>
在Apache中,最好忽略<Limit>标签,是为了确保保护应用到所有的方法中。但是,这种格式主要用来限制特定的方法。例如:仅仅限制POST方法。
AuthName "restrict posting" AuthType Basic AuthUserFile /usr/local/etc/httpd/users <Limit POST> require group staff </Limit>
仅仅组staff的成员可以访问POST方法,其他的用户(未认证的)可以使用其它的方法。例如:GET方法。这样做,主要是为了CGI程序让任何人可以访问。但是仅仅授权的用户可以请求POST方法。
9. 被主机或者用户限制
apache很有可能同时使用用户和主机限制,正常情况下,apache需要两个条件同时满足,那即是,来自允许的主机或者域名的用户必须输入有效的用户名和密码才能进行资源访问。但是Satisfy any指令被使用在.htaccess文件或者<Directory>,<Location>,<Files>部分,当这个指令被使用的时候,来自允许的主机或者域名不需要输入用户名和密码就能进行访问,来自不允许的主机或者域名必须输入有效的用户名和密码。
10. WWW认证如何进行工作?
在HTTP中用户认证的方法相当简单,因为HTTP是无状态的协议。只要一个请求完成,服务器并不会记得关于那个请求的任何信息。浏览器需要在每次请求中重新发送用户名和密码。这就是他的工作原理。
当第一次访问需要认证的资源时,服务器返回401状态(未授权)和包含一个WWW-Authenticate响应头,这个包含认证策略(目前仅有Basic允许)和realm名字。浏览器然后询问用户名和密码。然后再次请求相同的资源。这一次包含Authorization头,它包含策略名字(Basic)和用户名和密码。
服务器检测用户名和密码,如果他们有效,就返回页面,如果密码无效或者用户并不允许,服务器返回401状态,浏览器将会继续询问用户名和密码。
假如用户名和密码有效,用户将会继续请求另一个保护的资源,在这种情况下,服务器继续返回401状态,浏览器伴随着用户名和密码继续请求该资源,但是,这种将会很慢的。所以浏览器在接下来的请求中发送Authorization头,浏览器必须保证发送用户名和密码到相同的服务器上。(如果用户信息发送到不同的服务器,将会不安全的)
浏览器需要记住用户名和密码。所以它可以发送用户名和密码信息在接下来的请求中。但是在测试认证的时候,将会引起问题,因为浏览器第一次已经记住用户名和密码信息,强制浏览器再次询问用户名和密码将会很困难的。
11. 安全和数字认证
认证允许资源被访问,是针对特定的用户。但是存在着一些潜在的安全问题。
- 确保资源被限制在所有的方法中,例如:如果使用<Limit GET>,将会使其他的请求方法不被保护。
- 用户名和密码放在文本文件中,虽然密码是加密的,但是并不是绝对安全的。该文件不能被系统中的其他用户访问,更不能放在文档目录。(该目录可以被来自于网络的用户访问)
- 用户名和密码应该要绝对安全。用户不应该告诉其他人他们的密码。
- Basic认证策略在网络中传递密码是以非加密的方式传递的。所以他们可以被拦截。数字认证主要用来解决这个问题。
数字认证的方式将会使在网络中密码的方式更安全,在发送之前,密码会被加密,然后服务器会解密它。数字认证工作的方式和Basic认证的方式一样,数字认证的使用主要依赖于浏览器提供商是否写入他们的产品。Apache已经做了数字认证,被mod_digest模块所编译。