一、环境
1、Jira、nginx
2、jquery+html,iis发布
3、接口测试工具,我这里使用getman
二、要求
在不改变Jira任何代码的情况下,实现单点登陆
三、具体实现
1、ngin配置
配置它是为了让实现单点登陆页面的页面与Jira不跨域,不跨域的前提是域名、端口号一致。
假设Jira地址是a.com,单点登陆页面地址是b.com,nginx服务器地址是c.com。
nginx-1.18.0\conf下的nginx.conf文件,注意listen必须为80端口,且Jira不要带二级路径,只能是location / ,否则路径会不对,单点登陆页面带二级路径,这个路径不要和Jira原有的相同,如下所示:
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://a.com/;
proxy_redirect off;
proxy_send_timeout 300;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /api/ {
proxy_pass http://b.com/;
proxy_redirect off;
proxy_send_timeout 300;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
2、使用getman测试cookies的成功获取
如下图所示,JSESSIONID和atlassian.xsrf.token就是它的cookies,如果X-AUSERNAME显示正确账号,这样就显示成功获取,注意header这里是Authorization: Basic + “用户名:密码”进行BASE64编码。
3、编写页面jira.html
<script type="text/javascript">
$(document).ready(function () {
jira();
});
function jira() {
$.ajax({
type: "POST",
url: "http://c.com/login.jsp",
beforeSend: function (request) {
request.setRequestHeader("Authorization", "Basic "+"用户名:密码进行BASE64编码");
},
success: function (result) {
// alert(result);
location.href = "http://c.com/";
}
});
};</script>
4、访问nginx服务器的地址上的http://c.com/api/jira.html 将直接以你的用户名密码登陆进入
5、后续
这样只实现了当你知道用户密码时的单点登陆,后续可以在Jira.html做一个保存用户密码的弹出框,当POST没有正确返回时,弹出保存用户名密码,而在进入Jira.html前,可获取域账号或者门户系统的账号进行对应,这样下次可以单点登录。
改造jira.html,如下示例是基于用户名密码已经保存在数据库中,增加一个获取用户名密码的get_userpassword(),到后台返回用户名密码
<script type="text/javascript">
$(document).ready(function () {
//$("#user").val(getQueryVariable("user"));
//$("#password").val(decodeURI(getQueryVariable("password")));
get_userpassword();
});
function jira() {
$.ajax({
type: "POST",
url: "http:///login.jsp",
beforeSend: function (request) {
request.setRequestHeader("Authorization", "Basic " + window.btoa($("#user").val() + ":" + $("#password").val()));
},
success: function (result) {
// alert(result);c.com
location.href = "http://c.com/";
}
});
};
function get_userpassword() {
$.ajax({
type: "POST",
url: "Handler1.ashx",
dataType: "text",
data: { command: "get_userpassword", userid: getQueryVariable("user") },
success: function (msg) {
//alert(msg);
var jsonsql = eval('(' + msg + ')');
$("#user").val(jsonsql[0]["userid"]);
$("#password").val(jsonsql[0]["password"]);
jira();
}
});
}
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");
if (pair[0] == variable) { return pair[1]; }
}
return (false);
}
</script>
后端Handler1.ashx代码就比较简单,主要是拼装JSON返回给前端,如:
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
if (context.Request["command"] != null)
{
//
string command = context.Request.Form["command"].ToString();
System.Reflection.MethodInfo method = this.GetType().GetMethod(command);
if (method != null)
{
method.Invoke(this, new object[] { context });
}
}
}
public void get_userpassword(HttpContext context)
{
string sql = "SELECT * FROM [EDC].[dbo].[JiraUser] where userid='" + context.Request.Form["userid"] + "'";
string jsonString = DataTableJson(ExecuteDataSet(sql).Tables[0]);
context.Response.Write(jsonString);
context.Response.ContentType = "text/plain";
context.Response.End();
}