-
-
Notifications
You must be signed in to change notification settings - Fork 10.2k
Portal 实现用户登录功能
以下文档已不再维护,请转至 Portal实现用户登录功能 获取最新文档。
Apollo是配置管理系统,会提供权限管理(Authorization),理论上是不负责用户登录认证功能的实现(Authentication)。
所以Apollo定义了一些SPI用来解耦,Apollo接入登录的关键就是实现这些SPI。
可能很多公司并没有统一的登录认证系统,如果自己实现一套会比较麻烦。Apollo针对这种情况,从0.9.0开始提供了利用Spring Security实现的Http Basic简单认证版本。
使用步骤如下:
如果之前是0.8.0版本,需要导入apolloportaldb-v080-v090.sql
查看ApolloPortalDB,应该已经存在Users
表,并有一条初始记录。初始用户名是apollo,密码是admin。
Id | Username | Password | Enabled | |
---|---|---|---|---|
1 | apollo | $2a$10$7r20uS.BQ9uBpf3Baj3uQOZvMVvB1RN3PYoKE94gtz2.WAOuiiwXS | apollo@acme.com | 1 |
如果是IDE启动的话,确保-Dapollo_profile=github,auth
超级管理员登录系统后打开管理员工具 - 用户管理
即可添加用户。
超级管理员登录系统后打开管理员工具 - 用户管理
,输入用户名和密码后即可修改用户密码,建议同时修改超级管理员apollo的密码。
从1.2.0版本开始,Apollo支持了ldap协议的登录,按照如下方式配置即可。
如果采用helm chart部署方式,建议通过配置方式实现,不用修改镜像,可以参考启用 LDAP 支持
解压apollo-portal-x.x.x-github.zip
后,在config
目录下创建application-ldap.yml
,内容参考如下(样例),相关的内容需要按照具体情况调整:
spring:
ldap:
base: "dc=example,dc=org"
username: "cn=admin,dc=example,dc=org" # 配置管理员账号,用于搜索、匹配用户
password: "password"
searchFilter: "(uid={0})" # 用户过滤器,登录的时候用这个过滤器来搜索用户
urls:
- "ldap://localhost:389"
ldap:
mapping: # 配置 ldap 属性
objectClass: "inetOrgPerson" # ldap 用户 objectClass 配置
loginId: "uid" # ldap 用户惟一 id,用来作为登录的 id
userDisplayName: "cn" # ldap 用户名,用来作为显示名
email: "mail" # ldap 邮箱属性
OpenLDAP开启memberOf特性后,可以配置filter从而缩小用户搜索的范围:
spring:
ldap:
base: "dc=example,dc=org"
username: "cn=admin,dc=example,dc=org" # 配置管理员账号,用于搜索、匹配用户
password: "password"
searchFilter: "(uid={0})" # 用户过滤器,登录的时候用这个过滤器来搜索用户
urls:
- "ldap://localhost:389"
ldap:
mapping: # 配置 ldap 属性
objectClass: "inetOrgPerson" # ldap 用户 objectClass 配置
loginId: "uid" # ldap 用户惟一 id,用来作为登录的 id
userDisplayName: "cn" # ldap 用户名,用来作为显示名
email: "mail" # ldap 邮箱属性
filter: # 配置过滤,目前只支持 memberOf
memberOf: "cn=ServiceDEV,ou=DEV,dc=example,dc=org|cn=WebDEV,ou=DEV,dc=example,dc=org" # 只允许 memberOf 属性为 ServiceDEV 和 WebDEV 的用户访问
从1.3.0版本开始支持基于Group过滤用户,从而可以控制只有特定Group的用户可以登录和使用apollo:
spring:
ldap:
base: "dc=example,dc=org"
username: "cn=admin,dc=example,dc=org" # 配置管理员账号,用于搜索、匹配用户
password: "password"
searchFilter: "(uid={0})" # 用户过滤器,登录的时候用这个过滤器来搜索用户
urls:
- "ldap://localhost:389"
ldap:
mapping: # 配置 ldap 属性
objectClass: "inetOrgPerson" # ldap 用户 objectClass 配置
loginId: "uid" # ldap 用户惟一 id,用来作为登录的 id
rdnKey: "uid" # ldap rdn key
userDisplayName: "cn" # ldap 用户名,用来作为显示名
email: "mail" # ldap 邮箱属性
group: # 启用group search,启用后只有特定group的用户可以登录apollo
objectClass: "posixGroup" # 配置groupClassName
groupBase: "ou=group" # group search base
groupSearch: "(&(cn=dev))" # group filter
groupMembership: "memberUid" # group memberShip eg. member or memberUid
修改scripts/startup.sh
,指定spring.profiles.active
为github,ldap
。
SERVICE_NAME=apollo-portal
## Adjust log dir if necessary
LOG_DIR=/opt/logs/100003173
## Adjust server port if necessary
SERVER_PORT=8070
export JAVA_OPTS="$JAVA_OPTS -Dspring.profiles.active=github,ldap"
解压apollo-portal-x.x.x-github.zip
后,在config
目录下创建application-ldap.yml
,内容参考如下(样例),相关的内容需要按照具体情况调整:
spring:
ldap:
base: "dc=example,dc=com"
username: "admin" # 配置管理员账号,用于搜索、匹配用户
password: "password"
searchFilter: "(sAMAccountName={0})" # 用户过滤器,登录的时候用这个过滤器来搜索用户
urls:
- "ldap://1.1.1.1:389"
ldap:
mapping: # 配置 ldap 属性
objectClass: "user" # ldap 用户 objectClass 配置
loginId: "sAMAccountName" # ldap 用户惟一 id,用来作为登录的 id
userDisplayName: "cn" # ldap 用户名,用来作为显示名
email: "userPrincipalName" # ldap 邮箱属性
filter: # 可选项,配置过滤,目前只支持 memberOf
memberOf: "CN=ServiceDEV,OU=test,DC=example,DC=com|CN=WebDEV,OU=test,DC=example,DC=com" # 只允许 memberOf 属性为 ServiceDEV 和 WebDEV 的用户访问
修改scripts/startup.sh
,指定spring.profiles.active
为github,ldap
。
SERVICE_NAME=apollo-portal
## Adjust log dir if necessary
LOG_DIR=/opt/logs/100003173
## Adjust server port if necessary
SERVER_PORT=8070
export JAVA_OPTS="$JAVA_OPTS -Dspring.profiles.active=github,ldap"
解压apollo-portal-x.x.x-github.zip
后,在config
目录下创建application-ldap.yml
,内容参考如下(样例),相关的内容需要按照具体情况调整:
spring:
ldap:
base: "dc=example,dc=com"
username: "uid=admin,ou=system" # 配置管理员账号,用于搜索、匹配用户
password: "password"
searchFilter: "(uid={0})" # 用户过滤器,登录的时候用这个过滤器来搜索用户
urls:
- "ldap://localhost:10389"
ldap:
mapping: # 配置 ldap 属性
objectClass: "inetOrgPerson" # ldap 用户 objectClass 配置
loginId: "uid" # ldap 用户惟一 id,用来作为登录的 id
userDisplayName: "displayName" # ldap 用户名,用来作为显示名
email: "mail" # ldap 邮箱属性
从1.3.0版本开始支持基于Group过滤用户,从而可以控制只有特定Group的用户可以登录和使用apollo:
spring:
ldap:
base: "dc=example,dc=com"
username: "uid=admin,ou=system" # 配置管理员账号,用于搜索、匹配用户
password: "password"
searchFilter: "(uid={0})" # 用户过滤器,登录的时候用这个过滤器来搜索用户
urls:
- "ldap://localhost:10389"
ldap:
mapping: # 配置 ldap 属性
objectClass: "inetOrgPerson" # ldap 用户 objectClass 配置
loginId: "uid" # ldap 用户惟一 id,用来作为登录的 id
rdnKey: "cn" # ldap rdn key
userDisplayName: "displayName" # ldap 用户名,用来作为显示名
email: "mail" # ldap 邮箱属性
group: # 配置ldap group,启用后只有特定group的用户可以登录apollo
objectClass: "groupOfNames" # 配置groupClassName
groupBase: "ou=group" # group search base
groupSearch: "(&(cn=dev))" # group filter
groupMembership: "member" # group memberShip eg. member or memberUid
修改scripts/startup.sh
,指定spring.profiles.active
为github,ldap
。
SERVICE_NAME=apollo-portal
## Adjust log dir if necessary
LOG_DIR=/opt/logs/100003173
## Adjust server port if necessary
SERVER_PORT=8070
export JAVA_OPTS="$JAVA_OPTS -Dspring.profiles.active=github,ldap"
这种实现方式的前提是公司已经有统一的登录认证系统,最常见的比如SSO、LDAP等。接入时,实现以下SPI。其中UserService和UserInfoHolder是必须要实现的。
接口说明如下:
- UserService(Required):用户服务,用来给Portal提供用户搜索相关功能
- UserInfoHolder(Required):获取当前登录用户信息,SSO一般都是把当前登录用户信息放在线程ThreadLocal上
- LogoutHandler(Optional):用来实现登出功能
- SsoHeartbeatHandler(Optional):Portal页面如果长时间不刷新,登录信息会过期。通过此接口来刷新登录信息
可以参考apollo-portal下的com.ctrip.framework.apollo.portal.spi这个包下面的四个实现:
- defaultimpl:默认实现,全局只有apollo一个账号
- ctrip:ctrip实现,接入了SSO并实现用户搜索、查询接口
- springsecurity: spring security实现,可以新增用户,修改用户密码等
- ldap: @pandalin和codepiano贡献的ldap实现
实现了相关接口后,可以通过com.ctrip.framework.apollo.portal.configuration.AuthConfiguration在运行时替换默认的实现。
接入SSO的思路如下:
- SSO会提供一个jar包,需要配置一个filter
- filter会拦截所有请求,检查是否已经登录
- 如果没有登录,那么就会跳转到SSO的登录页面
- 在SSO登录页面登录成功后,会跳转回apollo的页面,带上认证的信息
- 再次进入SSO的filter,校验认证信息,把用户的信息保存下来,并且把用户凭证写入cookie或分布式session,以免下次还要重新登录
- 进入Apollo的代码,Apollo的代码会调用UserInfoHolder.getUser获取当前登录用户
注意,以上1-5这几步都是SSO的代码,不是Apollo的代码,Apollo的代码只需要你实现第6步。
注:运行时使用不同的实现是通过Profiles实现的,比如你自己的sso实现是在
custom
profile中的话,在打包脚本中可以指定-Dapollo_profile=github,custom。其中github
是Apollo必须的一个profile,用于数据库的配置,custom
是你自己实现的profile。同时需要注意在AuthConfiguration中修改默认实现的条件 ,从@ConditionalOnMissingProfile({"ctrip", "auth", "ldap"})
改为@ConditionalOnMissingProfile({"ctrip", "auth", "ldap", "custom"})
。
-
设计文档
-
部署文档
-
开发文档
-
系统使用文档
-
FAQ
-
其它