背景介绍

整合LDAP

修改sonar配置文件sonar.properties

$ vi /usr/local/sonarqube-7.4/conf/sonar.properties

找到下面的部分修改LDAP配置

#--------------------------------------------------------------------------------------------------
# LDAP CONFIGURATION

# Enable the LDAP feature
# sonar.security.realm=LDAP

# Set to true when connecting to a LDAP server using a case-insensitive setup.
# sonar.authenticator.downcase=true

# URL of the LDAP server. Note that if you are using ldaps, then you should install the server certificate into the Java truststore.
# ldap.url=ldap://localhost:10389

# Bind DN is the username of an LDAP user to connect (or bind) with. Leave this blank for anonymous access to the LDAP directory (optional)
# ldap.bindDn=cn=sonar,ou=users,o=mycompany

# Bind Password is the password of the user to connect with. Leave this blank for anonymous access to the LDAP directory (optional)
# ldap.bindPassword=secret

# Possible values: simple | CRAM-MD5 | DIGEST-MD5 | GSSAPI See http://java.sun.com/products/jndi/tutorial/ldap/security/auth.html (default: simple)
# ldap.authentication=simple

修改如下(请将具体信息按照自己的LDAP服务器信息进行修改):

#--------------------------------------------------------------------------------------------------
# LDAP CONFIGURATION

# Enable the LDAP feature
sonar.security.realm=LDAP

# Set to true when connecting to a LDAP server using a case-insensitive setup.
# sonar.authenticator.downcase=true

# URL of the LDAP server. Note that if you are using ldaps, then you should install the server certificate into the Java truststore.
ldap.url=ldap://devops.iamzhl.top:389

# Bind DN is the username of an LDAP user to connect (or bind) with. Leave this blank for anonymous access to the LDAP directory (optional)
ldap.bindDn=cn=Manager,dc=iamzhl,dc=top

# Bind Password is the password of the user to connect with. Leave this blank for anonymous access to the LDAP directory (optional)
ldap.bindPassword=passwd

# Possible values: simple | CRAM-MD5 | DIGEST-MD5 | GSSAPI See http://java.sun.com/products/jndi/tutorial/ldap/security/auth.html (default: simple)
ldap.authentication=simple

# See :
#   * http://java.sun.com/products/jndi/tutorial/ldap/security/digest.html
#   * http://java.sun.com/products/jndi/tutorial/ldap/security/crammd5.html
# (optional)
# ldap.realm=example.org

# Context factory class (optional)
# ldap.contextFactoryClass=com.sun.jndi.ldap.LdapCtxFactory

# Enable usage of StartTLS (default : false)
# ldap.StartTLS=true

# Follow or not referrals. See http://docs.oracle.com/javase/jndi/tutorial/ldap/referral/jndi.html (default: true)
# ldap.followReferrals=false

# USER MAPPING

# Distinguished Name (DN) of the root node in LDAP from which to search for users (mandatory)
ldap.user.baseDn=ou=People,dc=iamzhl,dc=top

# LDAP user request. (default: (&(objectClass=inetOrgPerson)(uid={login})) )
# ldap.user.request=(&(objectClass=user)(sAMAccountName={login}))
ldap.user.request=(&(objectClass=inetOrgPerson)(uid={login}))

# Attribute in LDAP defining the user’s real name. (default: cn)
# ldap.user.realNameAttribute=name
ldap.user.realNameAttribute=cn

# Attribute in LDAP defining the user’s email. (default: mail)
# ldap.user.emailAttribute=email
ldap.user.emailAttribute=mail

# GROUP MAPPING

# Distinguished Name (DN) of the root node in LDAP from which to search for groups. (optional, default: empty)
# ldap.group.baseDn=cn=groups,dc=example,dc=org
ldap.group.baseDn=ou=People,dc=iamzhl,dc=top

# LDAP group request (default: (&(objectClass=groupOfUniqueNames)(uniqueMember={dn})) )
# ldap.group.request=(&(objectClass=group)(member={dn}))
ldap.group.request=(&(objectClass=posixGroup)(memberUid={uid}))

# Property used to specifiy the attribute to be used for returning the list of user groups in the compatibility mode. (default: cn)
# ldap.group.idAttribute=sAMAccountName

修改完成后,重启sonar

$ sonar restart

打开sonar网址,输入LDAP中的用户名和密码后点击登录

登陆成功后,正常获取用户名

至此,SonarQube整合LDAP完成

整合CAS单点登录

介绍

SonarQube提供了一种SSO机制,可以用来作为单点登录的实现方式,就是使用HTTP header的方式,而CAS也提供了一种用于apache服务的认证方式,这就是mod_auth_cas,思路很简单,我们利用apache反向代理,做一个端口用于虚拟主机来转发SonarQube服务,然后在这个虚拟主机内部加入mod_auth_cas提供的认证拦截,同时在里面指定一个HTTP header用于发送认证后的请求到SonarQube,然后,SonarQube接收到这个请求后,发现正是自己设定的HTTP header,于是予以通过认证。这就是整个认证流程,下面开始介绍整合方法。

SonarQube修改

$ vi /usr/local/sonarqube-7.4/conf/sonar.properties

修改如下部分(就是将SSO AUTHENTICATION部分的参数取消注释,令其生效)

#--------------------------------------------------------------------------------------------------
# SSO AUTHENTICATION

# Enable authentication using HTTP headers
sonar.web.sso.enable=true

# Name of the header to get the user login.
# Only alphanumeric, '.' and '@' characters are allowed
sonar.web.sso.loginHeader=X-Forwarded-Login

# Name of the header to get the user name
sonar.web.sso.nameHeader=X-Forwarded-Name

# Name of the header to get the user email (optional)
sonar.web.sso.emailHeader=X-Forwarded-Email

# Name of the header to get the list of user groups, separated by comma (optional).
# If the sonar.sso.groupsHeader is set, the user will belong to those groups if groups exist in SonarQube.
# If none of the provided groups exists in SonarQube, the user will only belong to the default group.
# Note that the default group will always be set.
sonar.web.sso.groupsHeader=X-Forwarded-Groups

# Interval used to know when to refresh name, email and groups.
# During this interval, if for instance the name of the user is changed in the header, it will only be updated after X minutes.
sonar.web.sso.refreshIntervalInMinutes=5

修改app.d5dba530.chunk.js,解决登出问题,不同的版本不同,7.2.1的在main开头的一个js文件中。

# vi /usr/local/sonarqube-7.4/web/js/app.d5dba530.chunk.js

修改如下

t.handleLogout = function(e) {
    // e.preventDefault(), t.context.router.push("/sessions/logout") 
    t.context.router.push("/sessions/logout")  //去掉e.preventDefault()方法
}
r.createElement("li", null, r.createElement("a", {
    //href: "#",
    href: "http://192.168.6.99:8080/cas/logout",  //将此注销按钮的href改为CAS服务器的登出页面
    onClick: this.handleLogout
}

mod_auth_cas修改

然后安装mod_auth_cas

# yum -y install mod_auth_cas

配置mod_auth_cas

# vi /etc/httpd/conf.d/auth_cas.conf

修改CASCookie存储位置以及登录地址和验证地址等参数如下

LogLevel Debug
CASDebug On
CASVersion 2
CASTimeout 1740
CASIdleTimeout 1740
CASSSOEnabled On
CASCookiePath /var/cache/httpd/mod_auth_cas/
CASLoginURL http://devops.iamzhl.top:8080/cas/login
CASValidateURL http://devops.iamzhl.top:8080/cas/serviceValidate

apache修改

# vi /etc/httpd/conf/httpd.conf

添加虚拟主机

# 添加一个监听端口 83 用作 SonarQube 的代理主机
Listen 83

# 加载 mod_auth_cas 模块,如果已经加载请忽略
LoadModule auth_cas_module modules/mod_auth_cas.so

# 设置 SonarQube 的虚拟主机
<VirtualHost *:83>
        ServerName devops.iamzhl.top
        ServerAdmin 15563836030@163.com

        CASRootProxiedAs http://devops.iamzhl.top:83

        ProxyPreserveHost On

        ProxyPass / http://devops.iamzhl.top:9000/
        ProxyPassReverse / http://devops.iamzhl.top:9000/
        ProxyPass /sessions/logout http://devops.iamzhl.top:8080/cas/logout
        ProxyPassReverse /sessions/logout http://devops.iamzhl.top:8080/cas/logout
        ProxyPass /api/authentication/logout http://devops.iamzhl.top:8080/cas/logout
        ProxyPassReverse /api/authentication/logout http://devops.iamzhl.top:8080/cas/logout

        ErrorLog /var/log/sonar/error.log
        CustomLog /var/log/sonar/access.log common

        <Location />
                AuthName "Welcome to devops sonar"
                CASAuthNHeader X-Forwarded-Login
                Authtype CAS
                require valid-user
        </Location>

        <Proxy *>
                Order deny,allow
                Allow from all
        </Proxy>
</VirtualHost>

重启服务

# mkdir /var/log/sonar
# chown -R apache:apache /var/log/sonar
# su sonar
$ sonar restart
# su 
# systemctl restart httpd

测试

打开网址http://devops.iamzhl.top:83,发现自动跳转到了CAS的登录界面,网址是http://devops.iamzhl.top:8080/cas/login?service=http%3a%2f%2fdevops.iamzhl.top%3a83%2f

输入用户名密码后点击登录

如图所示,登陆成功,地址是http://devops.iamzhl.top:83/projects

如上图所示,点击注销,就会登出并跳转至CAS的登出界面

至此,SonarQube整合CAS单点登录完成。