653 lines
30 KiB
Markdown
653 lines
30 KiB
Markdown
|
## GeoServer Security
|
|||
|
|
|||
|
> GeoServer中的Security子系统是基于Spring Security的。这里介绍的是通过GeoServer的Web管理界面来如何配置Security。
|
|||
|
|
|||
|
### 1. Security 设置
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
### 密码
|
|||
|
|
|||
|
> 密码是任何安全系统的核心部分。
|
|||
|
|
|||
|
`GeoServer`配置存储两种类型的密码:
|
|||
|
|
|||
|
- 访问`GeoServer`资源的用户帐号密码;
|
|||
|
- 内部用于访问外部服务(如数据库`postgis`和关联`OGC`服务)的密码。
|
|||
|
|
|||
|
由于这些密码通常存储在磁盘上,因此强烈建议对它们进行加密,而不是存储为可读的明文文本。`GeoServer`安全提供了四种密码加密方案:
|
|||
|
|
|||
|
1. **空密码**:该方案是不可逆转的。任何密码都被编码为空字符串,因此无法重新计算纯文本密码。该方案用于用户/组服务,并结合使用后端系统的身份验证机制。例如,针对`LDAP`服务器或`JDBC`数据库的用户名/密码身份验证。在这些场景中,将密码本地存储到`GeoServer`是没有意义的。
|
|||
|
2. **明文密码**:纯文本密码根本不提供加密。在这种情况下,任何可以访问文件系统的人都可以读取密码。由于显而易见的原因,除了最基本的测试服务器之外,不建议使用这种方法。
|
|||
|
3. **摘要密码(可加盐)**:摘要加密是不可逆转的。它通过迭代过程对密码应用`SHA-256`加密散列函数10万次。该方案是“单向的”,因为实际上不可能从其散列表示中反转和获取原始密码。为了防止已知的攻击,在生成密钥时将一个称为salt的随机值添加到密码中。对于每次消化,使用一种单独的随机盐。对相同密码进行两次摘要处理会得到不同的散列表示。
|
|||
|
4. **`PBE`密码**:[Password-based encryption](http://www.javamex.com/tutorials/cryptography/password_based_encryption.shtml)基于密码的加密(`PBE`)通常使用用户提供的密码来生成加密密钥。这个方案是可逆的。
|
|||
|
|
|||
|
密码加密方案是全局设置的,会影响外部资源密码加密的,同时也指定为每个`user/group`服务的加密方案。
|
|||
|
|
|||
|
外部资源的加密方案必须是可逆的,而用户/组服务可以使用任何方案。
|
|||
|
|
|||
|
#### Password-based encryption
|
|||
|
|
|||
|
`GeoServer`支持两种`PBE`:
|
|||
|
|
|||
|
- `Weak PBE`:弱`PBE` (`GeoServer`默认值)使用一种相对容易破解的基本加密方法。加密密钥使用`MD5`迭代1000次从密码中获得。加密算法本身是DES (Data encryption Standard)。DES的有效密钥长度为56位,这对于当今的计算机系统来说并不是一个真正的挑战。
|
|||
|
- `Strong PBE`:`强PBE`使用更强大的加密方法,基于`AES 256`位算法和`CBC`。密钥长度为256位,使用`SHA-256`而不是`MD5`导出。强烈建议使用`Strong PBE`。
|
|||
|
|
|||
|
以“`geoserver`”密码加密为“`crypt1:KWhO7jrTz/Gi0oTQRKsVeCmWIZY5VZaD`”为例:
|
|||
|
|
|||
|
> 密文和盐是64进制编码的。
|
|||
|
|
|||
|
- `crypt1`表示`弱PBE`的使用情况。
|
|||
|
- `强PBE`的前缀是`crypt2`。
|
|||
|
|
|||
|
#### 可逆加密
|
|||
|
|
|||
|
密码加密方法可以是可逆的,这意味着有可能(也是可取的)从其加密版本获得明文密码。可逆密码对于数据库连接或外部`OGC`服务(如级联`WMS`和级联`WFS`)是必需的,因为`GeoServer`必须能够解码加密的密码并将其传递给外部服务。明文密码和`PBE`密码是可逆的。
|
|||
|
|
|||
|
不可逆转的密码提供了最高级别的安全性,因此应该用于用户帐户和其他任何可能的地方。强烈建议使用密码摘要,不需要安装不受限制的策略文件。
|
|||
|
|
|||
|
#### 密钥和密钥库
|
|||
|
|
|||
|
要使可逆密码提供有意义的安全级别,必须以某种方式限制对密码的访问。
|
|||
|
|
|||
|
在`GeoServer`中,密码的加密和解密涉及到秘密共享和密钥生成,这些密钥存储在典型的Java密钥库中。`GeoServer`使用自己的密钥存储库,名为`GeoServer.jceks`,它位于`GeoServer`数据目录下的security目录中。该文件以`JCEKS`格式存储,而不是默认的`JKS`格式。`JKS`不支持存储共享密钥。
|
|||
|
|
|||
|
还可以为`GeoServer`设置密钥存储库密码。这个密码有两个用途:
|
|||
|
|
|||
|
- 保护对密钥存储库的访问
|
|||
|
- 保护对`GeoServer Root`帐户的访问权限
|
|||
|
|
|||
|
默认情况下,使用纯文本生成`keystore`密码并将其存储在名为`security/masterpw.info`的文件中。
|
|||
|
|
|||
|
从现有的`GeoServer`数据目录(2.1版本及以下),则该算法尝试找出角色为`ROLE_ADMINISTRATOR`的用户的密码。如果发现该密码,且密码长度至少为8个字符,则`GeoServer`使用该密码作为`keystore`密码。同样,所选用户的名称可以在`security/masterpw.info`中找到。
|
|||
|
|
|||
|

|
|||
|
|
|||
|
> `GeoServer`,读取该文件并验证密钥存储库密码。成功后,该文件将被删除。
|
|||
|
>
|
|||
|
> 如果删除security文件夹,用户的密码和`postgis`的密码都会被删除,所以谨慎处理。
|
|||
|
|
|||
|
设置一个Active keystore password provider:
|
|||
|
|
|||
|
1. 
|
|||
|
2. 
|
|||
|
3. Changing the keystore password,密码策略要求最少要8个字符
|
|||
|
4. 
|
|||
|
5. 更改完成后,摘要密码`masterpw.digest`会更新,同时`security/masterpw/default/passwd`也会更新。
|
|||
|
|
|||
|
默认情况下,禁用使用“`Keystore Password`”登录`Admin GUI`和`REST api`。为了启用它,您需要手动更改密钥库密码提供程序`config.xml`,通常位于`security/masterpw/default/config.xml`中,通过添加以下语句:
|
|||
|
|
|||
|
```xml
|
|||
|
<loginEnabled>true</loginEnabled>
|
|||
|
```
|
|||
|
|
|||
|
#### 密码策略
|
|||
|
|
|||
|
密码策略定义了对密码的约束,如密码长度、大小写和所需的字符类组合。密码策略在添加用户/组业务时指定,用于创建新用户和修改现有用户密码时对密码进行约束。
|
|||
|
|
|||
|
#### 参数化的密码
|
|||
|
|
|||
|
|
|||
|
|
|||
|
### 角色系统
|
|||
|
|
|||
|
GeoServer中的安全性是基于**角色**的系统,其中创建了用于服务特定功能的角色。具有特定功能的角色的示例包括访问Web Feature Service (WFS)、管理Web管理接口和读取特定层的角色。
|
|||
|
|
|||
|
角色分配给用户和用户组,并确定允许这些用户或组执行哪些操作。
|
|||
|
|
|||
|
通过认证方式对用户进行授权。
|
|||
|
|
|||
|
#### 用户与组
|
|||
|
|
|||
|
GeoServer用户的定义与大多数安全系统类似。虽然正确的Java术语是**principal**主体(主体是指人、计算机、软件系统等),但在整个GeoServer文档中都采用了用户一词。为每个用户维护以下信息:
|
|||
|
|
|||
|
- 用户名
|
|||
|
- 密码
|
|||
|
- 指示用户是否启用的标志(这是默认值)。禁用的用户被禁止登录。现有用户会话不受影响。
|
|||
|
- 键/值对的集合
|
|||
|
|
|||
|
键/值对是特定于实现的,可以由用户或组所属的用户/组服务配置。例如,维护用户信息(如姓名、电子邮件地址等)的用户/组服务可能希望将这些属性与用户对象关联起来
|
|||
|
|
|||
|
一个GeoServer组 **group** 就是一组用户。对于每一组,保持以下信息:
|
|||
|
|
|||
|
- Group name
|
|||
|
- 指示组是否启用的标志(这是默认值)。禁用的组不参与该组中包含的所有用户的角色计算。
|
|||
|
- 属于该组的用户列表
|
|||
|
|
|||
|
#### 用户/组服务
|
|||
|
|
|||
|
用户/组服务为用户/组提供以下信息:
|
|||
|
|
|||
|
- 用户列表
|
|||
|
- 组列表,包括与每个组关联的用户
|
|||
|
- 用户密码
|
|||
|
|
|||
|
许多身份验证提供者将使用用户/组服务来执行身份验证。在这种情况下,用户/组服务将是对用户和密码进行身份验证的数据库。根据[Authentication chain](https://docs.geoserver.org/latest/en/user/security/auth/chain.html#security-auth-chain) 身份验证链的配置方式,在任何给定时间可能有零个、一个或多个活跃的用户/组服务。
|
|||
|
|
|||
|
用户/组服务可能是只读的,提供对用户信息的访问,但不允许添加或修改新的用户和组。如果将用户/组服务配置为将用户和组数据库委托给外部服务,则可能发生这种情况。外部LDAP服务器就是一个例子。
|
|||
|
|
|||
|
默认情况下,GeoServer支持三种类型的用户/组服务:
|
|||
|
|
|||
|
- [XML](https://docs.geoserver.org/latest/en/user/security/usergrouprole/usergroupservices.html#security-rolesystem-usergroupxml)—*(Default)* User/group service persisted as XML
|
|||
|
- User/group service persisted in database via JDBC
|
|||
|
- [LDAP](https://docs.geoserver.org/latest/en/user/security/usergrouprole/usergroupservices.html#security-rolesystem-usergroupldap)—User/group service obtained from an LDAP repository
|
|||
|
|
|||
|
还可以向GeoServer添加其他服务,例如 [AuthKey](https://docs.geoserver.org/latest/en/user/extensions/authkey/index.html#authkey) 扩展提供的服务。
|
|||
|
|
|||
|
**XML user/group service**
|
|||
|
|
|||
|
XML用户/组服务将用户/组数据库保存在XML文件中。这是GeoServer的默认行为。
|
|||
|
|
|||
|
该服务将用户数据库表示为XML,并与此XML schema模式相对应。
|
|||
|
|
|||
|
> XML用户/组文件users.xml位于GeoServer数据目录security/usergroup/<name>/users.xml中,其中<name>是用户/组服务的名称。
|
|||
|
|
|||
|

|
|||
|
|
|||
|
以下是默认GeoServer配置附带的users.xml的内容:
|
|||
|
|
|||
|
```xml
|
|||
|
<?xml version="1.0" encoding="UTF-8"?>
|
|||
|
<userRegistry version="1.0" xmlns="http://www.geoserver.org/security/users">
|
|||
|
<users>
|
|||
|
<user enabled="true" name="admin" password="digest1:D9miJH/hVgfxZJscMafEtbtliG0ROxhLfsznyWfG38X2pda2JOSV4POi55PQI4tw"/>
|
|||
|
</users>
|
|||
|
<groups/>
|
|||
|
</userRegistry>
|
|||
|
```
|
|||
|
|
|||
|
**JDBC user/group service**
|
|||
|
|
|||
|
JDBC user/group service 通过JDBC调用数据库,持久化用户/组数据,管理多个表中的用户信息。用户/组数据库模式如下:
|
|||
|
|
|||
|
用户表:`users`
|
|||
|
|
|||
|
| Field | Type | Null | Key |
|
|||
|
| :------- | :----------- | :--- | :--- |
|
|||
|
| name | varchar(128) | NO | PRI |
|
|||
|
| password | varchar(254) | YES | |
|
|||
|
| enabled | char(1) | NO | |
|
|||
|
|
|||
|
用户属性表:`user_props`
|
|||
|
|
|||
|
| Field | Type | Null | Key |
|
|||
|
| :-------- | :------------ | :--- | :--- |
|
|||
|
| username | varchar(128) | NO | PRI |
|
|||
|
| propname | varchar(64) | NO | PRI |
|
|||
|
| propvalue | varchar(2048) | YES | |
|
|||
|
|
|||
|
用户组信息表:`groups`
|
|||
|
|
|||
|
| Field | Type | Null | Key |
|
|||
|
| :------ | :----------- | :--- | :--- |
|
|||
|
| name | varchar(128) | NO | PRI |
|
|||
|
| enabled | char(1) | NO | |
|
|||
|
|
|||
|
用户组成员表:`group_members`
|
|||
|
|
|||
|
| Field | Type | Null | Key |
|
|||
|
| :-------- | :----------- | :--- | :--- |
|
|||
|
| groupname | varchar(128) | NO | PRI |
|
|||
|
| username | varchar(128) | NO | PRI |
|
|||
|
|
|||
|
`users`表是主表,包含带有关联密码的用户列表;
|
|||
|
|
|||
|
`user_props`表将附加属性映射到用户;
|
|||
|
|
|||
|
`groups`表列出了所有可用的组;
|
|||
|
|
|||
|
`group_members`表映射了哪些用户属于哪些组。
|
|||
|
|
|||
|
> 默认的GeoServer安全配置中上述四张表都是空的
|
|||
|
|
|||
|
**LDAP user/group service**
|
|||
|
|
|||
|
LDAP用户/组服务是一个**只读**用户/组服务,它将用户和组从LDAP存储库映射到GeoServer用户和组。
|
|||
|
|
|||
|
用户从特定的LDAP节点中提取,配置为Users搜索库。组是从特定的LDAP节点中提取的,并配置为Groups搜索基。每个匹配的用户对应一个用户映射,每个匹配的组对应一个组映射。
|
|||
|
|
|||
|
> LDAP(Light Directory Access Portocol),它是基于X.500标准的轻量级目录访问协议。目录是一个为查询、浏览和搜索而优化的数据库,它成树状结构组织数据,类似文件目录一样。
|
|||
|
>
|
|||
|
> LDAP目录服务是由目录数据库和一套访问协议组成的系统。
|
|||
|
|
|||
|
可以指定包含组名(如cn)、用户名(如uid)以及两者之间的成员关系(如member)的属性。但是,也可以指定特定的过滤器来搜索所有用户/组(例如cn=*),按名称查找用户/组(例如cn={0})并将用户映射到组(例如member={0})。这些过滤器也可以从属性名中自动派生出来。另外,如果提供了过滤器,属性名也可以保留为空。
|
|||
|
|
|||
|
对于用户,可以通过提供一个逗号分隔的属性名列表,从LDAP服务器填充其他属性(键/值对,请参阅users和Groups)。
|
|||
|
|
|||
|
检索用户/组信息可以匿名完成,如果LDAP存储库需要,也可以使用给定的用户名/密码。
|
|||
|
|
|||
|
此类型角色服务的配置文件(config.xml)示例如下:
|
|||
|
|
|||
|
```xml
|
|||
|
<userGroupService>
|
|||
|
<id>52857278:13c7ffd66a8:-7ffd</id>
|
|||
|
<name>default</name>
|
|||
|
<className>org.geoserver.security.xml.XMLUserGroupService</className>
|
|||
|
<fileName>users.xml</fileName>
|
|||
|
<checkInterval>10000</checkInterval>
|
|||
|
<validating>true</validating>
|
|||
|
<passwordEncoderName>digestPasswordEncoder</passwordEncoderName>
|
|||
|
<passwordPolicyName>default</passwordPolicyName>
|
|||
|
</userGroupService>
|
|||
|
```
|
|||
|
|
|||
|
#### 角色
|
|||
|
|
|||
|
GeoServer角色是与执行某些任务或访问特定资源相关联的关键。角色被分配给用户`users`和组`groups`,授权他们执行与角色相关的操作。一个GeoServer角色包括以下内容:
|
|||
|
|
|||
|
- 角色名
|
|||
|
- 父角色
|
|||
|
- 设置键值对
|
|||
|
|
|||
|
GeoServer角色支持继承—子角色继承授予父角色的所有访问权限。
|
|||
|
|
|||
|
键/值对是特定于实现的,可以由用户或组所属的角色服务配置。例如,基于员工组织分配角色的角色服务可能希望将其他信息(如Department Name)与角色关联。
|
|||
|
|
|||
|
GeoServer有许多系统角色,这些角色的名称是保留的。不允许添加具有保留名称的新GeoServer角色。
|
|||
|
|
|||
|
- `ROLE_ADMINISTRATOR`:提供对所有操作和资源的访问
|
|||
|
- `ROLE_GROUP_ADMIN`:管理用户组的特殊角色
|
|||
|
- `ROLE_AUTHENTICATED`:分配给每个身份验证成功的用户
|
|||
|
- `ROLE_ANONYMOUS`:启用匿名身份验证且用户未登录时分配
|
|||
|
|
|||
|
#### 角色服务
|
|||
|
|
|||
|
角色服务为角色提供如下信息:
|
|||
|
|
|||
|
- 角色列表
|
|||
|
- 计算给定用户的角色分配
|
|||
|
- 角色到系统角色ROLE_ADMINISTRATOR的映射
|
|||
|
- 角色到系统角色ROLE_GROUP_ADMIN的映射
|
|||
|
|
|||
|
当用户/组服务加载有关用户或组的信息时,它将委托给角色服务来确定应该将哪些角色分配给用户或组。
|
|||
|
|
|||
|
与用户/组服务不同,**在任何给定时间只有一个角色服务是活动的**。在“设置”页面中设置默认角色服务。
|
|||
|
|
|||
|
默认情况下,GeoServer支持两种类型的角色服务:
|
|||
|
|
|||
|
- XML——(默认)角色服务作为XML持久化
|
|||
|
- JDBC——角色服务通过JDBC持久化在数据库中
|
|||
|
|
|||
|
**将角色映射到系统角色**
|
|||
|
|
|||
|
若要将系统角色`ROLE_ADMINISTRATOR`分配给用户或组,则需要创建不同名称的新角色,并将其映射给角色`ROLE_ADMINISTRATOR`。对于系统角色`ROLE_GROUP_ADMIN`也是如此。映射存储在服务的config.xml文件中。
|
|||
|
|
|||
|
```xml
|
|||
|
<roleService>
|
|||
|
<id>52857278:13c7ffd66a8:-7ffc</id>
|
|||
|
<name>default</name>
|
|||
|
<className>org.geoserver.security.xml.XMLRoleService</className>
|
|||
|
<fileName>roles.xml</fileName>
|
|||
|
<checkInterval>10000</checkInterval>
|
|||
|
<validating>true</validating>
|
|||
|
<adminRoleName>ADMIN</adminRoleName>
|
|||
|
<groupAdminRoleName>GROUP_ADMIN</groupAdminRoleName>
|
|||
|
</roleService>
|
|||
|
```
|
|||
|
|
|||
|
在本例中,赋予角色ADMIN的用户或组同时赋予系统角色ROLE_ADMINISTRATOR。对于GROUP_ADMIN和ROLE_GROUP_ADMIN也是如此。
|
|||
|
|
|||
|
**XML角色服务**
|
|||
|
|
|||
|
XML角色服务将角色数据库保存在XML文件中(这是GeoServer的默认角色服务)。该服务将用户数据库表示为XML,并与此XML模式相对应。
|
|||
|
|
|||
|
> XML角色文件roles.xml位于GeoServer数据目录security/role/<name>/roles.xml中,其中<name>是角色服务的名称。
|
|||
|
|
|||
|
配置本地角色“ADMIN”映射到系统角色“ROLE_ADMINISTRATOR”。另外,GROUP_ADMIN映射到ROLE_GROUP_ADMIN。映射存储在每个角色服务的config.xml文件中。
|
|||
|
|
|||
|

|
|||
|
|
|||
|
```xml
|
|||
|
<?xml version="1.0" encoding="UTF-8"?>
|
|||
|
<roleRegistry version="1.0" xmlns="http://www.geoserver.org/security/roles">
|
|||
|
<roleList>
|
|||
|
<role id="ADMIN"/>
|
|||
|
<role id="GROUP_ADMIN"/>
|
|||
|
</roleList>
|
|||
|
<userList>
|
|||
|
<userRoles username="admin">
|
|||
|
<roleRef roleID="ADMIN"/>
|
|||
|
</userRoles>
|
|||
|
</userList>
|
|||
|
<groupList/>
|
|||
|
</roleRegistry>
|
|||
|
```
|
|||
|
|
|||
|
该配置包含ADMIN和GROUP_ADMIN两个角色。角色ADMIN被分配给ADMIN用户。由于ADMIN角色已经映射给系统角色ROLE_ADMINISTRATOR,所以在角色计算中,ADMIN用户被同时赋予了两个角色
|
|||
|
|
|||
|
示例:
|
|||
|
|
|||
|

|
|||
|
|
|||
|

|
|||
|
|
|||
|

|
|||
|
|
|||
|

|
|||
|
|
|||
|
**JDBC角色服务**
|
|||
|
|
|||
|

|
|||
|
|
|||
|
|
|||
|
|
|||
|
JDBC角色服务通过JDBC持久化角色数据库,管理多个表中的角色信息。角色数据库模式如下所示
|
|||
|
|
|||
|
角色表:roles
|
|||
|
|
|||
|
| Field | Type | Null | Key |
|
|||
|
| :----- | :---------- | :--- | :--- |
|
|||
|
| name | varchar(64) | NO | PRI |
|
|||
|
| parent | varchar(64) | YES | |
|
|||
|
|
|||
|
角色属性表:role_props
|
|||
|
|
|||
|
| Field | Type | Null | Key |
|
|||
|
| :-------- | :------------ | :--- | :--- |
|
|||
|
| rolename | varchar(64) | NO | PRI |
|
|||
|
| propname | varchar(64) | NO | PRI |
|
|||
|
| propvalue | varchar(2048) | YES | |
|
|||
|
|
|||
|
用户角色关联表:user_roles
|
|||
|
|
|||
|
| Field | Type | Null | Key |
|
|||
|
| :------- | :----------- | :--- | :--- |
|
|||
|
| username | varchar(128) | NO | PRI |
|
|||
|
| rolename | varchar(64) | NO | PRI |
|
|||
|
|
|||
|
用户组与角色关联表:group_roles
|
|||
|
|
|||
|
| Field | Type | Null | Key |
|
|||
|
| :-------- | :----------- | :--- | :--- |
|
|||
|
| groupname | varchar(128) | NO | PRI |
|
|||
|
| rolename | varchar(64) | NO | PRI |
|
|||
|
|
|||
|
- roles表是主表,包含角色列表。GeoServer中的角色支持继承,所以一个角色可以有一个到父角色的链接。
|
|||
|
- role_props表将其他属性映射到角色。
|
|||
|
- user_roles表将用户映射到分配给他们的角色。
|
|||
|
- group_roles表映射了哪些组被分配了哪些角色。
|
|||
|
|
|||
|

|
|||
|
|
|||
|
GeoServer中上述四张表都为空。
|
|||
|
|
|||
|
添加角色:
|
|||
|
|
|||
|

|
|||
|
|
|||
|
使用:在安全设置中选择刚刚新建的角色服务:
|
|||
|
|
|||
|

|
|||
|
|
|||
|
在去`用户/组`中添加用户:
|
|||
|
|
|||
|
<img src="./images/image-20231215150154974.png" alt="image-20231215150154974" style="zoom: 50%;" />
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
**REST role service**
|
|||
|
|
|||
|
REST角色服务是一个**只读**角色服务,它将组和关联用户映射到远程REST web服务中的角色.
|
|||
|
|
|||
|
REST服务必须支持JSON编码。
|
|||
|
|
|||
|
下面是REST角色服务(基于LDAP角色服务,它同样必须使网络调用工作)提供的重要方法的列表:
|
|||
|
|
|||
|
| Method | Mandatory |
|
|||
|
| :------------------------------ | :----------------------------------------------------------- |
|
|||
|
| *getUserNamesForRole(roleName)* | N (implemented in LDAP, but I don’t see actual users of this method besides a utility method that nobody uses) |
|
|||
|
| *getRolesForUser(user)* | Y |
|
|||
|
| *getRolesForGroup(group)* | N |
|
|||
|
| *getRoles()* | Y (used by the UI) |
|
|||
|
| *getParentRole(role)* | N |
|
|||
|
| *getAdminRole()* | Y |
|
|||
|
| *getGroupAdminRole()* | Y |
|
|||
|
| *getRoleCount()* | Y (does not seem to be used much, we can trivially implement it from getRoles() |
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#### 角色服务与用户/组
|
|||
|
|
|||
|
**计算用户角色**
|
|||
|
|
|||
|
下图说明了用户/组服务和角色服务如何交互以计算用户角色。
|
|||
|
|
|||
|

|
|||
|
|
|||
|
|
|||
|
|
|||
|
在从用户/组服务中获取启用的用户时,必须标识分配给该用户的角色。鉴定程序为:
|
|||
|
|
|||
|
1. 获取该用户`user`的所有已启用组。如果一个组被禁用,它将被丢弃。
|
|||
|
2. 获取与该用户关联的所有角色`role`,并将角色添加到结果集中。
|
|||
|
3. 对于用户所属的每个已启用组,获取与该组关联的所有角色,并将角色添加到结果集中。
|
|||
|
4. 对于结果集中的每个角色,获取所有祖先角色并将这些角色添加到结果集中。
|
|||
|
5. 根据需要个性化结果集中的每个角色。
|
|||
|
6. 如果结果集中存在本地admin角色,则添加角色ROLE_ADMINISTRATOR。
|
|||
|
7. 如果结果集中存在本地组admin角色,则添加角色ROLE_GROUP_ADMIN。
|
|||
|
|
|||
|
**用户凭证的身份验证**
|
|||
|
|
|||
|
用户/组服务主要用于身份验证。身份验证链[Authentication chain](https://docs.geoserver.org/latest/en/user/security/auth/chain.html#security-auth-chain)中的身份验证提供者可以使用`user/group service`对用户凭证进行身份验证。
|
|||
|
|
|||
|

|
|||
|
|
|||
|
**GeoServer默认的安全配置**
|
|||
|
|
|||
|

|
|||
|
|
|||
|
|
|||
|
|
|||
|
### 认证
|
|||
|
|
|||
|
#### [Authentication chain](https://docs.geoserver.org/latest/en/user/security/auth/chain.html)
|
|||
|
|
|||
|
在身份验证中涉及三组GeoServer资源:
|
|||
|
|
|||
|
- web 管理界面
|
|||
|
- OWS服务的认证
|
|||
|
- REST接口服务的认证
|
|||
|
|
|||
|
了解身份验证链有助于解释GeoServer身份验证是如何工作的。身份验证链处理请求并应用某些身份验证机制。认证机制的例子包括:
|
|||
|
|
|||
|
- **Username/password**:通过在外部用户数据库中查找用户信息来执行身份验证
|
|||
|
- **Browser cookie**:通过识别先前发送的浏览器cookie(也称为“Remember Me”)执行身份验证
|
|||
|
- **LDAP**:对LDAP数据库执行身份验证
|
|||
|
- **Anonymous**:本质上不执行身份验证,允许请求在没有任何凭据的情况下继续进行
|
|||
|
|
|||
|
在给定时间,GeoServer中可能有多个身份验证机制处于活动状态。下图说明了通用请求的流程。
|
|||
|
|
|||
|

|
|||
|
|
|||
|
|
|||
|
|
|||
|
在将请求分派给适当的服务或处理程序之前,GeoServer首先通过身份验证链过滤请求。请求按顺序传递给链中的每个机制,每个机制都有机会对请求进行身份验证。如果链中的一个机制能够成功地进行身份验证,则请求转到正常处理。否则,不会进一步路由请求,并向用户返回一个授权错误(通常是HTTP 401)。
|
|||
|
|
|||
|
|
|||
|
|
|||
|
**过滤链和执行链**
|
|||
|
|
|||
|

|
|||
|
|
|||
|
在GeoServer中,身份验证链实际上由两条链组成:
|
|||
|
|
|||
|
1. `filter chain`:它们决定是否需要对请求进行进一步的身份验证;
|
|||
|
2. `provide chain`:它执行实际的身份验证。
|
|||
|
|
|||
|
过滤器链`filter chain`执行各种任务,包括:
|
|||
|
|
|||
|
- 从请求中收集用户凭据 credentials ,例如从基本和摘要身份验证头中;
|
|||
|
- 处理事件,如结束会话(注销),或设置“记住我”浏览器cookie;
|
|||
|
- 执行会话集成,检测现有会话并在必要时创建新会话;
|
|||
|
- 调用身份验证提供程序链来执行实际的身份验证。
|
|||
|
|
|||
|
过滤器链实际上被处理两次,分别在处理请求之前和之后。
|
|||
|
|
|||
|
执行链只关心执行请求的底层身份验证。当过滤器确定需要身份验证时,它由过滤器链调用。
|
|||
|
|
|||
|
|
|||
|
|
|||
|
**请求类型&筛选链**
|
|||
|
|
|||
|
> 不同的过滤器链可以应用于GeoServer中的每种不同类型的请求。
|
|||
|
|
|||
|
这是因为管理员可以配置不同过滤器链的列表,并为每个过滤器链配置匹配规则。只有配置的有序列表的第一个匹配链将应用于任何给定的请求。
|
|||
|
|
|||
|
匹配规则可以应用于:
|
|||
|
|
|||
|
- HTTP Method (GET, POST, etc.)
|
|||
|
- 请求的路径部分的一个或多个ANT模式(例如/wms/**);如果指定了多个模式(以逗号分隔),则其中任何一个都将匹配;
|
|||
|
- 一个可选的正则表达式,用于匹配查询字符串上的一个或多个指定ANT模式的参数;如果路径匹配,也会检查查询字符串是否匹配;正则表达式可以在ANT模式之后使用管道(|)分隔符指定。
|
|||
|
|
|||
|
ANT模式支持以下通配符:
|
|||
|
|
|||
|
- `?`:匹配一个字符
|
|||
|
- `*`:匹配零个或多个字符
|
|||
|
- `**`:匹配路径中的零个或多个'目录'
|
|||
|
|
|||
|
查询字符串正则表达式将匹配完整的查询字符串(^和$终止符会自动追加),因此要只匹配其中的一部分,请记住在表达式的前缀和后缀中加上**`.*`**(例如`.*request=getcapabilities.*`。
|
|||
|
|
|||
|
规则示例(ANT模式和查询字符串正则表达式)
|
|||
|
|
|||
|
| Pattern | Description |
|
|||
|
| :-------------------------------------------------- | :----------------------------------------------------------- |
|
|||
|
| `/wms, /wms/**` | simple ANT pattern |
|
|||
|
| `/wms|.*request=GetMap.*` | ANT pattern and querystring regex to match one parameter |
|
|||
|
| `/wms|(?=.*request=getmap)(?=.*format=image/png).*` | ANT pattern and querystring regex to match two parameters in any order |
|
|||
|
| `/wms|(?=.*request=getmap)(?!.*format=image/png).*` | ANT pattern and querystring regex to match one parameters and be sure another one is not matched |
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#### OWS和REST服务的认证
|
|||
|
|
|||
|
OWS和REST服务是**无状态**的,没有固有的“会话”意识,因此这些服务的身份验证方案要求客户端在**每个请求上提供凭据**。也就是说,支持“会话集成”,这意味着如果服务器上已经存在会话(来自并发认证的web管理会话),它将用于身份验证。**此方案允许GeoServer避免OWS和REST服务创建会话的开销。**
|
|||
|
|
|||
|
默认GeoServer配置附带了对服务的HTTP基本身份验证的支持。
|
|||
|
|
|||
|
典型的认证过程如下:
|
|||
|
|
|||
|
1. 用户在不提供任何凭据的情况下发出服务请求
|
|||
|
|
|||
|
2. 如果用户正在访问不安全的资源,则正常处理请求
|
|||
|
|
|||
|
3. 如果用户正在访问受保护的资源:
|
|||
|
|
|||
|
- 将HTTP 401状态码发送回客户端,通常强制客户端提示输入凭据。
|
|||
|
|
|||
|
- 然后,在包含适当凭据的情况下重复服务请求,通常在HTTP报头中,就像在Basic Authentication中一样。
|
|||
|
- 如果用户有足够的权限访问资源,请求将被正常处理,否则,将向客户端返回一个HTTP 404状态码。
|
|||
|
|
|||
|
4. 后续请求应包括原始用户凭据。
|
|||
|
|
|||
|
OWS服务的认证链如下所示:
|
|||
|
|
|||
|

|
|||
|
|
|||
|
在这个例子中,过滤器链由三个过滤器组成:
|
|||
|
|
|||
|
- **Session**:会话,执行会话集成,识别现有会话(但不创建新会话)
|
|||
|
- **Basic Auth**: 从请求HTTP报头提取基本身份验证凭据
|
|||
|
- **Anonymous**:处理匿名访问
|
|||
|
|
|||
|
提供者链由两个提供者组成:
|
|||
|
|
|||
|
- **Root**—Root帐户有一个特殊的“超级用户”提供者。由于很少使用此帐户,因此很少调用此提供程序。
|
|||
|
- **Username/password**—对用户数据库进行用户名/密码认证
|
|||
|
|
|||
|
示例:
|
|||
|
|
|||
|
1. 匿名请求WMS服务的GetCapabilities
|
|||
|
|
|||
|

|
|||
|
|
|||
|
- 会话筛选器查找现有会话,但没有找到,因此继续处理。
|
|||
|
|
|||
|
- 基本认证筛选器在请求中查找基本授权标头,但由于请求是匿名的,因此筛选器没有找到。
|
|||
|
|
|||
|
- 最后,Anonymous过滤器以匿名方式执行并验证请求。
|
|||
|
|
|||
|
由于GetCapabilities是一个“发现”操作,因此它通常不会被锁定,即使在安全的服务器上也是如此。假设这里是这种情况,则匿名请求成功,并向客户端返回功能响应。不调用提供程序链。
|
|||
|
|
|||
|
2. 安全层的匿名WMS GetMap请求
|
|||
|
|
|||
|
此示例显示了当WMS客户端为安全层发出匿名GetMap请求时调用的过程。
|
|||
|
|
|||
|
该链的执行完全如上所述。
|
|||
|
|
|||
|
- 会话筛选器查找现有会话,但没有找到,因此继续处理。
|
|||
|
- 基本认证筛选器在请求中查找基本授权标头,但由于请求是匿名的,因此筛选器没有找到。
|
|||
|
- 最后,Anonymous过滤器以匿名方式执行并验证请求。
|
|||
|
|
|||
|
然而,在这种情况下,被访问的层是一个受保护的资源,因此GetMap请求的处理失败。服务器返回一个带有HTTP 401状态码的异常,这通常会触发客户端向用户呈现。
|
|||
|
|
|||
|
3. 带有用户提供凭据的WMS GetMap请求
|
|||
|
|
|||
|
此示例显示了WMS客户机从用户收集凭据并重新发出先前的安全层请求时调用的流程。
|
|||
|
|
|||
|

|
|||
|
|
|||
|
- 会话过滤器按照上面描述的方式执行,不执行任何操作。
|
|||
|
|
|||
|
- Basic Auth筛选器在请求中查找授权标头,提取其凭据,然后调用提供者链。
|
|||
|
- 处理转移到执行实际身份验证的Username/password提供程序
|
|||
|
|
|||
|
如果凭据具有访问该层所需的特权,则请求的处理将正常继续,GetMap请求成功,返回映射响应。
|
|||
|
|
|||
|
如果凭据不够,则将提供HTTP 401状态码,这可能再次触发登录对话框0
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#### 认证的提供者
|
|||
|
|
|||
|
在GeoServer中,有下列三种认证方式:
|
|||
|
|
|||
|
- 根据user/group服务的用户密码认证
|
|||
|
- 根据LDAP服务的认证
|
|||
|
- 根据JDBC连接数据库的认证
|
|||
|
|
|||
|
用户名和密码身份验证是默认的身份验证提供程序。
|
|||
|
|
|||
|
提供者简单地从传入请求(例如`Basic Authentication`请求)中获取用户名/密码,然后从用户/组服务加载用户信息并验证凭据。
|
|||
|
|
|||
|
JDBC身份验证提供者通过JDBC连接到数据库进行身份验证。
|
|||
|
|
|||
|
提供者从传入请求中获取用户名/密码,并尝试使用这些凭据创建数据库连接。提供者可以选择使用用户/组服务在成功的身份验证后加载用户信息。在此上下文中,用户/组服务将不用于密码验证,而仅用于角色分配。
|
|||
|
|
|||
|
|
|||
|
|
|||
|
### 服务安全
|
|||
|
|
|||
|
GeoServer支持提供service级别的访问控制,允许锁定服务的操作只有拥有被授权的角色的用户才能操作。在GeoServer中可以将服务大致分为两类:
|
|||
|
|
|||
|
- OWS 服务:例如WMS、WFS等
|
|||
|
- REST 服务
|
|||
|
|
|||
|
OWS服务支持为特定服务或该服务中的特定操作全局设置安全访问约束。一些例子包括:
|
|||
|
|
|||
|
- 保护整个WFS服务,因此只有经过身份验证的用户才能访问所有WFS操作。
|
|||
|
- 允许匿名访问只读WFS操作,如GetCapabilities,但保护写操作,如Transaction。
|
|||
|
- 通过保护所有操作而不向任何用户应用适当的角色来禁用WFS服务。
|
|||
|
|
|||
|
OWS服务安全访问规则在名为services的文件中指定。属性,该属性位于GeoServer数据目录中的security目录中。该文件包含将服务操作映射到已定义角色的规则列表。指定规则的语法如下所示
|
|||
|
|
|||
|

|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
### 1. Key authentication
|
|||
|
|
|||
|
|
|||
|
|
|||
|
### 2. CAS
|
|||
|
|