jira單點登陸

Java代碼實現jira單點登陸java

一             緣由

最近最近剛上一個項目,須要經過jira來跟蹤系統問題,客戶要求實現從他們現有門戶中單點登陸到jira系統。apache

二             分析

Jira是一個款知名度比較高的商業軟件,按理應該有解決方案,因而在網上查找相關方式,發現關於jira的資料 至關少,未找到任務與第三方實現單點登陸的方式。無奈只能經過反編譯瞭解jira用戶登陸驗證的實現方式,從atlassian-seraph*.jar包內的com.atlassian.seraph.auth. DefaultAuthenticator類實現代碼,咱們瞭解jira是經過getUser來獲取用戶信息,獲取用戶信息主要分爲三步,具體以下:api

一、  從sessioncookie

二、  從cookiessession

三、  getUserFromBasicAuthenticationless

 

代碼片斷:測試

    String METHOD = "getUser : ";ui

    boolean dbg = log.isDebugEnabled();this

 

    HttpSession session = httpServletRequest.getSession(false);debug

    if (session != null)

    {

      Principal sessionUser = getUserFromSession(httpServletRequest);

      if (sessionUser != null)

      {

        LoginReason.OK.stampRequestResponse(httpServletRequest, httpServletResponse);

        return sessionUser;

      }

 

    }

 

    if (!LoginReason.OUT.isStamped(httpServletRequest))

    {

      Principal cookieUser = getUserFromCookie(httpServletRequest, httpServletResponse);

      if (cookieUser != null)

      {

        return cookieUser;

      }

    }

 

    if (RedirectUtils.isBasicAuthentication(httpServletRequest, this.basicAuthParameterName))

    {

      Principal basicAuthUser = getUserFromBasicAuthentication(httpServletRequest, httpServletResponse);

      if (basicAuthUser != null)

      {

        return basicAuthUser;

      }

    }

 

    if (dbg)

    {

      log.debug("getUser : User not found in either Session, Cookie or Basic Auth.");

    }

 

    return null;

三             實現方式

經過分析代碼,咱們若是要實現單點登陸只有兩種方式可選

一、 不改變原有代碼,從門戶中寫知足jira的cookie的信息,

二、 經過java代碼實現接口,

a)   實現虛擬類DefaultAuthenticator,重寫getUser方式,在jiraJiraSeraphAuthenticator類的基礎上增長第四從獲取用戶信息的方式,即:別的應用系統寫cookie(必須是採用域名的方式),jira從cookie中獲取用戶。

b)   並修改配置 文件 atlassian-jira/WEB-INF/classes/seraph-config.xml,具體修改以下:

<!--   <authenticator class="com.atlassian.jira.security.login.JiraSeraphAuthenticator"/>-->

<authenticator class="com.atlassian.jira.security.cuslogin.CusJiraSeraphAuthenticator"/>

c)   重啓jira,經測試 ,jira可以從門戶登陸。

四             聯繫方式

QQ:279505686

五             相關代碼

a)       寫cookie的代碼

<%

    String PORTAL_COOKIE_KEY = "JIRA_USER_NAME_KEY";

         Cookie cookie=new Cookie(PORTAL_COOKIE_KEY,"admin");

         cookie.setDomain("ncyc.cbpm");

         cookie.setMaxAge(-1);

         cookie.setPath("/");

         response.addCookie(cookie);

%>

b)      獲取cookie的方式

package com.atlassian.jira.security.cuslogin;

import javax.servlet.http.Cookie;

import javax.servlet.http.HttpServletRequest;

public class SSOnCookie {

         private final String PORTAL_COOKIE_KEY = "JIRA_USER_NAME_KEY";

         private HttpServletRequest request = null;

         public static SSOnCookie getSSOCookie(HttpServletRequest request) {

                   SSOnCookie cookie = new SSOnCookie();

                   cookie.request = request;

                   return cookie;

         }

         public boolean isExpired() {

                   Cookie[] cookies = request.getCookies();

                   System.out.println("cookie"+cookies);

                   if (null == cookies || cookies.length == 0)

                            return true;

                   System.out.println("cookie length:"+cookies.length);

                   for (Cookie cookie : cookies) {

                            System.out.println("cookie name:"+cookie.getName());

                            if (cookie.getName().equals(PORTAL_COOKIE_KEY)) {

                                     return false;

                            }

                   }

                   return true;

         }

         /** Return the username implied by the cookie in the request. */

         public String getLoginId() {

                   Cookie[] cookies = request.getCookies();

                   if (null == cookies || cookies.length == 0)

                            return null;

                   for (Cookie cookie : cookies) {

                            if (cookie.getName().equals(PORTAL_COOKIE_KEY)) {

                                     return cookie.getValue();

                            }

                   }

                   return null;

         }

}

c)       實現單點登陸的代碼

package com.atlassian.jira.security.cuslogin;

import com.atlassian.crowd.embedded.api.CrowdService;

import com.atlassian.crowd.exception.AccountNotFoundException;

import com.atlassian.crowd.exception.FailedAuthenticationException;

import com.atlassian.crowd.exception.runtime.CommunicationException;

import com.atlassian.crowd.exception.runtime.OperationFailedException;

import com.atlassian.jira.component.ComponentAccessor;

import com.atlassian.jira.user.ApplicationUser;

import com.atlassian.jira.user.util.UserManager;

import com.atlassian.seraph.auth.AuthenticationContextAwareAuthenticator;

import com.atlassian.seraph.auth.AuthenticationErrorType;

import com.atlassian.seraph.auth.AuthenticatorException;

import com.atlassian.seraph.auth.DefaultAuthenticator;

import com.atlassian.seraph.auth.LoginReason;

import com.atlassian.seraph.elevatedsecurity.ElevatedSecurityGuard;

import com.atlassian.seraph.util.SecurityUtils;

import com.atlassian.seraph.util.SecurityUtils.UserPassCredentials;

import java.io.IOException;

import java.security.Principal;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

 

import org.apache.log4j.Logger;

 

@AuthenticationContextAwareAuthenticator

public class CusJiraSeraphAuthenticator extends DefaultAuthenticator

{

  private static final Logger log = Logger.getLogger(CusJiraSeraphAuthenticator.class);

 

  protected Principal getUser(String username)

  {

    return getUserManager().getUserByName(username);

  }

 

  protected boolean authenticate(Principal user, String password)

    throws AuthenticatorException

  {

    try

    {

      crowdServiceAuthenticate(user, password);

      return true;

    }

    catch (AccountNotFoundException e)

    {

      log.debug("authenticate : '" + user.getName() + "' does not exist and cannot be authenticated.");

      return false;

    }

    catch (FailedAuthenticationException e)

    {

      return false;

    }

    catch (CommunicationException ex)

    {

      throw new AuthenticatorException(AuthenticationErrorType.CommunicationError);

    }

    catch (OperationFailedException ex)

    {

      log.error("Error occurred while trying to authenticate user '" + user.getName() + "'.", ex);

    }throw new AuthenticatorException(AuthenticationErrorType.UnknownError);

  }

 

  private void crowdServiceAuthenticate(Principal user, String password)

    throws FailedAuthenticationException

  {

    Thread currentThread = Thread.currentThread();

    ClassLoader origCCL = currentThread.getContextClassLoader();

    try

    {

      currentThread.setContextClassLoader(getClass().getClassLoader());

      getCrowdService().authenticate(user.getName(), password);

    }

    finally

    {

      currentThread.setContextClassLoader(origCCL);

    }

  }

 

  protected Principal refreshPrincipalObtainedFromSession(HttpServletRequest httpServletRequest, Principal principal)

  {

    Principal freshPrincipal = principal;

    if ((principal != null) && (principal.getName() != null))

    {

      if ((principal instanceof ApplicationUser))

      {

        freshPrincipal = getUserManager().getUserByKey(((ApplicationUser)principal).getKey());

      }

      else

      {

        freshPrincipal = getUser(principal.getName());

      }

      putPrincipalInSessionContext(httpServletRequest, freshPrincipal);

    }

    return freshPrincipal;

  }

 

  protected Principal getUserFromBasicAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)

  {

    String METHOD = "getUserFromSession : ";

    boolean dbg = log.isDebugEnabled();

 

    String header = httpServletRequest.getHeader("Authorization");

    LoginReason reason = LoginReason.OK;

 

    if (SecurityUtils.isBasicAuthorizationHeader(header))

    {

      if (dbg)

      {

        log.debug("getUserFromSession : Looking in Basic Auth headers");

      }

 

      SecurityUtils.UserPassCredentials creds = SecurityUtils.decodeBasicAuthorizationCredentials(header);

      ElevatedSecurityGuard securityGuard = getElevatedSecurityGuard();

      if (!securityGuard.performElevatedSecurityCheck(httpServletRequest, creds.getUsername()))

      {

        if (dbg)

        {

          log.debug("getUserFromSession : '" + creds.getUsername() + "' failed elevated security check");

        }

        reason = LoginReason.AUTHENTICATION_DENIED.stampRequestResponse(httpServletRequest, httpServletResponse);

        securityGuard.onFailedLoginAttempt(httpServletRequest, creds.getUsername());

      }

      else

      {

        if (dbg)

        {

          log.debug("getUserFromSession : '" + creds.getUsername() + "' does not require elevated security check.  Attempting authentication...");

        }

 

        try

        {

          boolean loggedin = login(httpServletRequest, httpServletResponse, creds.getUsername(), creds.getPassword(), false);

 

          if (loggedin)

          {

            reason = LoginReason.OK.stampRequestResponse(httpServletRequest, httpServletResponse);

            securityGuard.onSuccessfulLoginAttempt(httpServletRequest, creds.getUsername());

            if (dbg)

            {

              log.debug("getUserFromSession : Authenticated '" + creds.getUsername() + "' via Basic Auth");

            }

            return getUser(creds.getUsername());

          }

 

          reason = LoginReason.AUTHENTICATED_FAILED.stampRequestResponse(httpServletRequest, httpServletResponse);

          securityGuard.onFailedLoginAttempt(httpServletRequest, creds.getUsername());

        }

        catch (AuthenticatorException e)

        {

          log.warn("getUserFromSession : Exception trying to login '" + creds.getUsername() + "' via Basic Auth:" + e, e);

        }

      }

      try

      {

        httpServletResponse.sendError(401, "Basic Authentication Failure - Reason : " + reason.toString());

      }

      catch (IOException e)

      {

        log.warn("getUserFromSession : Exception trying to send Basic Auth failed error: " + e, e);

      }

      return null;

    }

 

    try

    {

      httpServletResponse.setHeader("WWW-Authenticate", "Basic realm=\"protected-area\"");

      httpServletResponse.sendError(401);

    }

    catch (IOException e)

    {

      log.warn("getUserFromSession : Exception trying to send Basic Auth failed error: " + e, e);

    }

    return null;

  }

 

  private CrowdService getCrowdService()

  {

    return (CrowdService)ComponentAccessor.getComponent(CrowdService.class);

  }

 

  private UserManager getUserManager() {

    return ComponentAccessor.getUserManager();

  }

 

  public Principal getUser(HttpServletRequest request, HttpServletResponse response)

  {

      Principal user = null;

      try

      {

        user=super.getUser(request, response);

          if(user== null)

          {

              SSOnCookie ssoCookie = SSOnCookie.getSSOCookie(request);

              log.info("cus Got SSOnCookie "+ssoCookie);

 

              if (ssoCookie != null && !ssoCookie.isExpired())

              { // Seamless login from intranet

                  log.info("Trying seamless Single Sign-on...");

                  String username = ssoCookie.getLoginId();

                  System.out.println("Got username = " + username);

                  if (username != null)

                  {

                      user = getUser(username);

                      if(null!=user){

                                 log.info("Logged in via SSO, with User "+user);

                                 request.getSession().setAttribute(DefaultAuthenticator.LOGGED_IN_KEY, user);

                                 request.getSession().setAttribute(DefaultAuthenticator.LOGGED_OUT_KEY, null);

                      }else {

                         System.out.println("get not user");

                      }

                  }

              }

              else

              {

                  log.info("SSOCookie is null; redirecting");

                  //user was not found, or not currently valid

                  return null;

              }

          }

      }

      catch (Exception e) // catch class cast exceptions

      {

          log.warn("Exception: " + e, e);

      }

      return user;

  }

}

相關文章
相關標籤/搜索