说明:
当前环境的Jira是容器部署的,所以方案中的整个流程是在docker环境下进行分析。且方案为解决思路或者说解决方式的一种,仅供参考,不喜勿喷。当然依然存在个别问题,没能完全优化完,想了解的可以直接看最后。
如果有其它优化方案或者问题欢迎评论区讨论学习。
前置知识: docker、docker-compose
镜像环境说明:
我的Jira镜像版本:atlassian/jira-software:9.4.2-ubuntu-jdk11
如果是其他版本,思路应该大同小异(可以仿照当前文档,从其他版本的容器中拷贝对应的jra包以及配置文件即可,可能有差别,可能都一样)
我会提供所有的代码以及环境依赖和镜像,方便道友们模拟测试
其他:
如果想先看效果,到资料栏中获取资料,将jira-sso-linux.tar解压后,执行:docker-compose up -d创建容器。浏览器访问:ip:8088等待jira启动完毕。创建账号密码时,账号必须是root
、密码必须是dev@msi
。jira启动完毕以后,可以先登录root用户看看是否能成功登录,保证jira正常启动。接着退出root用户,浏览器输入地址:ip:8088/login.html。会发现登录的是张三的用户。
流程图:
思路:
- 为业务系统提供一个login.html页面作为单点登录的地址。业务系统通过访问该地址达到免登录功能。在html中,通过js自动提交请求到Jira本身的login.jsp(没有使用原本的login.jsp页面主要是因为没去研究(也不会 = =)jsp文件反编译以及编译,用html相对简单,并且用html不会影响原本的loign.jsp页面的访问,不排除单独访问Jira应用正常访问)
- 使用在本地编写符合自身业务的的login方法,而不使用原本默认登陆的login方法(核心登录使用原本的逻辑,实现来源于
DefaultAuthenticator类
,在此基础上进行修改)/** * html中form表单提交的action路径(login.jsp)会到Jira以下类中的login方法 * 原本默认请求会到JiraSeraphAuthenticator类中的login方法 * 这里的SSOSeraphAuthenticator是在原本的类中进行修改,名称可自定义,但是要与jira配置文件的名称一致 */ public class SSOSeraphAuthenticator extends DefaultAuthenticator { public boolean login(){} }
- 修改配置文件:配置SSOSeraphAuthenticator类,不然会到默认的JiraSeraphAuthenticator类
- 通过docker-compose更新容器中的配置(曾经不使用编排文件的形式修改时,发现配置文件会在重启时,会恢复成原本默认的配置,导致配置不生效,当然本文提供的这种方式确保有效(手动部署的jira没了解过))。让程序运行时使用本地编译好的SSOSeraphAuthenticator类的class文件,使得登录时执行自己的方法进行认证(
走我们SSOSeraphAuthenticator类中的login,而不走默认JiraSeraphAuthenticator类中的login
)
版本
这里是我的运行环境版本,且docker及docker-compose是必要的
- Jira镜像版本:atlassian/jira-software:9.4.2-ubuntu-jdk11
- jdk:17.0.8
- maven:3.8.3
- docker
- docker-compose
其他说明:
- jdk和maven的版本应该没有过多要求,本地可以正常编译代码即可
- 如果jira版本不同,配置文件、jar包需要自己从对应版本的容器中拷贝到本地(怎么拷贝见倒数第三个菜单栏目)
资料
阿里云盘:jira-sso-资料
文件为exe可执行文件,下载到本地以后双击运行解压获取资料
其中包含:java代码、linux中的镜像资料等
准备
说明:当前目录会说明如何构建好java环境以及docker-compose执行环境
下载提供的资料:含java编译程序、docker-compose编排文件以及镜像文件
java环境准备
- 打开工程,配置好maven、jdk
- 打开
SSOSeraphAuthenticator
类,会提示找不到包。所需的包都放在了工程extlib
目录下(对于不同版本的依赖及配置文件怎么拿看这里)
- 引入依赖
这样编译环境就搭建好了
docker-compose环境准备
将提供的资料jira-sso-linux.tar
解压得到以下文件
lib 映射的目录
image 含jira镜像包
docker-compose.yaml 编排文件
然后将image目录下的jira.tar导入到docker镜像中:docker save -i jiar.tar
解析
说明:
当前目录详细阐述java类中的方法、docker-compose中的目录说明
只提供主要的描述,具体代码自行查看源文件
java
java部分主要介绍资料中提供的SSOSeraphAuthenticator类
,其中的方法都有注释
SSOSeraphAuthenticator
下图是对各类方法的作用说明
在SSOSeraphAuthenticator中主要看login
方法,其中login最终会调用dologin
方法,本文主要针对单点登录对dologin进行了调整。如果想看原本的实现,可以到下个类目提到的AbstractAuthenticator类、DefaultAuthenticator类
。
其中的方法各位道友自行查阅,注释都比较详细。
AbstractAuthenticator类(原本的默认类)
此处说明:为什么要定义SSOSeraphAuthenticator、我的login方法从何而来,其中的逻辑为什么要那样写
在jira的配置文件中,有一处配置了JiraSeraphAuthenticator类
,配置文件的说明栏目会介绍到。也正是因为配置文件默认配置了JiraSeraphAuthenticator类
以及login.jsp
,所以当我们正常登录时,地址栏中的login.jsp可以请求到JiraSeraphAuthenticator类
中的login
方法
JiraSeraphAuthenticator类
又继承了DefaultAuthenticator类
DefaultAuthenticator类(原本的默认类)
该类为JiraSeraphAuthenticator
提供了login、logout等方法的实现
由此,我们可以按照JiraSeraphAuthenticator类
,自定义自己的类实现DefaultAuthenticator类
,那么就能实现原本的登录。最后在配置文件中使用我们自己的类就行了。
login.html也是同理,替换原本login.jsp的配置。html它仅仅作为中转站,其目的一个是通过它的请求能到我们自定义类的login方法,其次是可以携带参数,比如token等等,到了程序里我们再解析token获取用户信息等等,具体携带的参数可以根据业务需求调整。
到这里我们的login方法就准备好了
login.html
定义表单
通过js提交表单
到这里我们就能请求能到login方法了
logout.html
该html供单点退出使用,在login.html的基础上新增了isLogout参数。单纯访问退出地址后会到登录页。正常通过业务系统退出jira的话,get请求获取的响应可以不管,毕竟session状态以及cookei已经清掉了
传递到后端调用logout方法。logout没有提供外部调用的接口
退出访问地址:http://ip:port/logout.html
jira-sso-linux.tar文件说明
介绍资料中提供的jira-sso-linux.tar
解压后的目录结构以及各个目录的内容
- jar:需要引入的jar包
- lib目录下包含classes文件夹、login.html页面、logout.html页面
- classes目录下包含jira的配置文件seraph-config.xml、sso文件夹
- sso文件夹下就是放我们java程序编译后的targe目录下sso目录下的SSOSeraphAuthenticator类的class文件
4.1 例如下图
打开文件目录后可以得到
这两个文件就是需要拷贝到sso目录下的文件
docker-compose编排文件说明
主要介绍下图中的映射目录说明
针对以上映射内容,主要说明容器内的目录
- /var/atlassian/application-data/jira:jira的数据目录
- /opt/atlassian/jira/atlassian-jira/WEB-INF/classes/com/atlassian/jira/security
该目录是我们存放编译后文件的目录。映射关系由上图得知,存在client、sso目录
sso:我们编写SSOSeraphAuthenticator类
的包目录
client:在我提供的java资料中,该目录下没有任何文件,此处配置是为了说明我们后续可以建自己的包,以及类文件,且都建在security目录下。比如在需要的场景下有个service包,那么需要在java的security包下建一个service包,接着在docker-compose中添加一条像client映射关系的配置:./lib/classes/service:/opt/atlassian/jira/atlassian-jira/WEB-INF/classes/com/atlassian/jira/security/service
。那么在执行编排文件后,就可以在我们的类中访问service中的方法
- /opt/atlassian/jira/lib/:该lib目录是存放所需jar的目录,比如这里的hutool.jar
- /opt/atlassian/jira/atlassian-jira/:该目录下存放静态文件,比如这里的login.html、logout.html
- ./lib/classes/seraph-config.xml:/opt/atlassian/jira/atlassian-jira/WEB-INF/classes/seraph-config.xml:ro
该关系为配置文件的映射,无需修改
配置文件
说明:目前只介绍单点登录、登出涉及到修改的部分,其他内容未做研究
位置:容器内所在的目录/opt/atlassian/jira/atlassian-jira/WEB-INF/classes/seraph-config.xml
配置本地的登录认证类
部署:
- 编译java程序得到class文件
- 将class文件拷贝到docker-compose目录下的
/lib/classes/sso/
目录下,如果有其他包下的类,则拷贝到对应目录下,当然全部放在这个目录也行
- 通过docker-compose构建容器:
docker-compose up -d
(class文件变更后重启即可:docker-compose restart
) - 如果是不带参数访问login进行测试,则访问:html://ip:port/login.html,登录进去是代码中默认提供的用户张三,则表示登录成功
不同版本
不同版本如何查找相关运行环境:(都从容器内拷贝出来,且版本号是对应版本所属的版本号)
- 配置文件:
到目录/opt/atlassian/jira/atlassian-jira/WEB-INF/classes
下拷贝:seraph-config.xml
- jar包:
到目录/opt/atlassian/jira/atlassian-jira/WEB-INF/lib
下拷贝以下jar包到本地的exlib目录下:(查找命令:find . -name "*名称*"
)
2.1. spring-core-5.3.19.jar
2.2. jira-api-9.4.2.jar
2.3. atlassian-seraph-4.1.3.jar
2.4. embedded-crowd-api-5.0.0-m02.jar
2.5. javax.servlet-api-4.0.1.jar
bug
管理员删除用户的组且该用户没有任何组的情况下,首次登录进入系统,需要手动刷新一次页面才能正常使用
不足
1. 退出只能通过login方法作为入口,调用logout方法
2. 通过走sso的登录状态没有更新,目前也没去研究