jira集成单点登录
注:jiar版本为7.3.2
-
jira集成单点登录
-
1.jira登录原理
-
2.如何改造
-
3.部署
1.jira登录原理
jiar默认的登录处理类是com.atlassian.seraph.auth.JiraSeraphAuthenticator,此类继承DefaultAuthenticator,DefaultAuthenticator中的getUser()方法就是获取用户信息。
getUser()有三种方式,一种通过sesssion,一种通过cookie,最后是通过用户名密码,代码如下
@Override
public Principal getUser(final HttpServletRequest httpServletRequest, final HttpServletResponse httpServletResponse)
{
final String METHOD = "getUser : ";
final boolean dbg = log.isDebugEnabled();
// Rules
// - Do not create a session if there is not one already
// - If there is a user in the session, return it
// - Do not use a remember me cookie if this request was a logout request (e.g. make no assumption about the existence of a session or the existence of a user in that session - see SER-110, SER-114 and SER-95)
// - If this is NOT a logout request, feel free to check the remember me cookie
final HttpSession session = httpServletRequest.getSession(false);
if (session != null)
{
final Principal sessionUser = getUserFromSession(httpServletRequest);
if (sessionUser != null)
{
OK.stampRequestResponse(httpServletRequest, httpServletResponse);
return sessionUser;
}
}
// Look for remember me cookie, unless the user has logged out on this request (see Rules comment above)
if (!OUT.isStamped(httpServletRequest))
{
final Principal cookieUser = getUserFromCookie(httpServletRequest, httpServletResponse);
if (cookieUser != null)
{
return cookieUser;
}
}
if (RedirectUtils.isBasicAuthentication(httpServletRequest, basicAuthParameterName))
{
final Principal basicAuthUser = getUserFromBasicAuthentication(httpServletRequest, httpServletResponse);
if (basicAuthUser != null)
{
return basicAuthUser;
}
}
if (dbg)
{
log.debug(METHOD + "User not found in either Session, Cookie or Basic Auth.");
}
return null;
}
2.如何改造
首先要保证服务端的有jira的用户信息,我没有深入研究如何同步两边数据,暂时只能手动添加。单点登录原理就不细说了,简单说我们先编写一个过滤器或者拦截器跳转到服务端登录来获取账号并保存到session,然后修改刚刚的getUser()方法,如下所示:
通过session.getAttribute("SSO_MAPPER_ACCOUNT")获取服务端的账号,然后查找用户并保存用户到session。
package com.atlassian.jira.security.login;
import com.atlassian.jira.security.login.JiraSeraphAuthenticator;
import com.atlassian.seraph.auth.AuthenticatorException;
import com.atlassian.seraph.auth.LoginReason;
import com.atlassian.seraph.elevatedsecurity.ElevatedSecurityGuard;
import java.security.Principal;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* sso
*
* @author: luo.guihan
* @date: 2018/11/17
* @version: 1.0
*/
public class LsmySsoJiraSeraphAuthenticator extends JiraSeraphAuthenticator {
private static final Logger log = LoggerFactory.getLogger(LsmySsoJiraSeraphAuthenticator.class);
public Principal getUser(HttpServletRequest request, HttpServletResponse response)
{
Principal existingUser = getUserFromSession(request);
if (existingUser != null) {
log.debug("Session found; user already logged in.");
return existingUser;
}
HttpSession session = request.getSession();
String account = (String)session.getAttribute("SSO_MAPPER_ACCOUNT");
if (account != null)
{
log.debug("LsmySsoJiraSeraphAuthenticator-account:[{}]", account);
System.out.println("LsmySsoJiraSeraphAuthenticator-account:[{}]" + account);
Principal user = getUser(account);
if (user != null)
{
putPrincipalInSessionContext(request, user);
getElevatedSecurityGuard().onSuccessfulLoginAttempt(request, account);
LoginReason.OK.stampRequestResponse(request, response);
log.debug("Logging in [{}] from CAS.", account);
}
else
{
log.debug("Failed logging [{}] from CAS.", account);
getElevatedSecurityGuard().onFailedLoginAttempt(request, account);
}
return user;
}
return null;
}
public boolean logout(HttpServletRequest request, HttpServletResponse response)
throws AuthenticatorException
{
HttpSession session = request.getSession();
Principal p = (Principal)session.getAttribute("seraph_defaultauthenticator_user");
if (p != null) {
log.debug("Logging out [{}] from CAS.", p.getName());
}
removePrincipalFromSessionContext(request);
return true;
}
}
3.部署
3.1修改/jira/atlassian-jira/WEB-INF下的web.xml,添加过滤器,例如我的过滤器
<filter>
<filter-name>LsmySsoFilter</filter-name>
<filter-class>com.atlassian.jira.web.filters.lsmy.LsmySsoFilter</filter-class>
<init-param>
<param-name>lsmySsoLoginUrl</param-name>
<param-value>http://10.10.14.240:9901/sso/</param-value>
</init-param>
<init-param>
<param-name>logoutUrl</param-name>
<param-value>logout</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>LsmySsoFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.2修改/jira/atlassian-jira/WEB-INF/classes下的seraph-config.xml,屏蔽JiraSeraphAuthenticator,替换为我们实现的验证类,如下
<!-- CROWD:START - The authenticator below here will need to be commented out for Crowd SSO integration -->
<!-- <authenticator class="com.atlassian.jira.security.login.JiraSeraphAuthenticator"/> -->
<!-- CROWD:END -->
<!-- lsmy-sso:start -->
<authenticator class="com.atlassian.jira.security.login.LsmySsoJiraSeraphAuthenticator"/>
<!-- lsmy-sso:end -->
3.3替换和添加我们的类到指定位置
/jira/atlassian-jira/WEB-INF/classes/com/atlassian/jira/web/filters下新建的自定义过滤器和/jira/atlassian-jira/WEB-INF/classes/com/atlassian/jira/security/login下的LsmySsoJiraSeraphAuthenticator
3.4新增的jar包放在/jira/atlassian-jira/WEB-INF/lib下,我的项目需要用到fastjson