rally - 如何使用Rally.RestApi.dll进行SSO?

标签 rally

到目前为止,我已经了解到Rally RestAPI不支持SSO登录。我相信从2014年1月起,这种情况将不再成立。支持SSO登录的Excel Rally加载项使用了相同的API(此处是Rally Add-in for Excel的链接)。我可以获取Rally Excel加载项的源代码还是至少有人可以提供使用Rally RestAPI的SSO示例?

我想做与Excel插件导出功能完全相同的事情,但想在纯.net应用程序中做。

最佳答案

我在C#Rest Api中添加了一个howto,它解释了如何像Rally在Excel插件中那样进行SSO身份验证。我在这里粘贴是为了方便。

谢谢,斯科特

简短的Rally SSO入门

Rally Web服务API(WSAPI)本机仅支持基本身份验证。使用基本身份验证,必须使用用户名和密码启动WSAPI会话,该用户名和密码根据直接存储在Rally中的用户名和密码列表进行验证。在客户开始使用单一登录(SSO)之前,此方法可以正常工作。 SSO允许客户端使用单个企业范围的身份验证机制(例如LDAP或Active Directory)来管理用户凭据和密码。到目前为止,使用启用了SSO的WSAPI要求客户端为所有希望使用Rally WSAPI的用户在Rally中维护一个重复的用户列表(“白”列表)。现在,对Rally的最新更改允许WSAPI用户使用他们的SSO凭据访问Rally,并减轻了将这些用户保持在“白名单”中的需求。

注意:Rally当前的SSO实现基于SAML规范,该规范要求用​​户与浏览器进行交互以完成身份验证。因此,此技术需要用户与浏览器进行交互,因此与无头WSAPI客户端(例如将Rally与VCS和错误跟踪工具同步的WSAPI客户端)不兼容。

启动SSO连接时,用户提供一个URL,该URL与Rally的服务提供商(SP)开始SSO握手,此后涉及客户端的身份提供商(IdP),并以Rally以代表有效的已验证会话的cookie响应结束。如果该经过身份验证的会话cookie包含在任何后续的WSAPI调用中,则Rally会将那些调用与经过身份验证的用户相关联,并且WSAPI调用将得到认证。为了使成功进行SAML SSO身份验证之后的WSAPI调用易于访问已认证的会话cookie,Rally寻找添加到初始SSO URL的参数,如果存在,它将返回一个特殊的包含会话cookie的特殊网页。文本作为SSO握手的最终产品。用户可以使用该数据来构造cookie,以在随后的WSAPI调用中使用。

注意:以下示例URL(可能)特定于Rally的内部SSO实现。由于使用SSO允许客户使用自己的SSO基础结构(至少是IdP部分)提供自己的身份验证,因此SSO URL将是客户特定的。请与您的Rally TAM或Rally支持人员联系以获取有关SSO URL的帮助。

原始SSO URL如下所示:

 https://sso.rallydev.com/sp/startSSO.ping?PartnerIdpId=pingidp.f4tech.com-29577

特殊参数是:
 TargetResource=https://us1.rallydev.com/slm/j_sso_security_check?noRedirect=true

注意:此名称/值对使用PingIdentity作为SSO提供程序在Rally的特定SSO实现中设置SSO中继状态。其他SSO提供程序可能具有用于设置RelayState的不同参数名称。例如,某些SSO提供程序使用RelayState作为参数名称。无论如何,该值始终是相同的(即“https://us1.rallydev.com/slm/j_sso_security_check?noRedirect=true”)

因此,完整的URL如下所示:
 https://sso.rallydev.com/sp/startSSO.ping?PartnerIdpId=pingidp.f4tech.com-29577&TargetResource=https://us1.rallydev.com/slm/j_sso_security_check?noRedirect=true

如果用户导航到此修改后的SSO URL,则在身份验证后,将向他们显示一个包含以下内容的网页:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
    <head>
        <title>SSO Token</title>
    </head>
    <body>
        <form>
            <input type="hidden" name="authCookieName" value="ZSESSIONID"/>
            <input type="hidden" name="authCookieValue" value="khkjhkhkhkhkjhh"/>
        </form>
    </body>
</html>

如果用户基于此页面中包含的数据创建cookie,并将该cookie及其后续的WSAPI调用传递给该cookie,则这些调用将被成功认证。请注意,必须根据IETF规范对Cookie进行调用才能推断出可选的Cookie数据(例如安全和路径),以获取该Cookie。

因此,出于发出WSAPI调用的目的,从GUI界面登录Rally的基本过程(同样,这对于无头环境不起作用)如下:
  • 使用上述特殊参数从用户收集SSO URL。
  • 启动指向该URL的浏览器。
  • 导航完成后,从返回的HTML页面中抓取cookie值。
  • 关闭浏览器。
  • 从cookie值构造一个cookie。
  • 存储该cookie以供以后使用。
  • 发送该cookie和所有随后的WSAPI调用。

  • 如果WSAPI调用使用此cookie进行身份验证失败,请重复此过程。请记住,这些cookie会过期,并且您应该准备在重新认证后重试失败的呼叫,以创建流畅的用户体验。

    Rally C#ReST API

    Rally C#Rest API的连接框架中集成了一种机制,可简化针对不同GUI客户端的此过程,包括在会话超时后自动重新认证。这包括将令牌页面解析为有效cookie的方法。该库的调用者可以实现其他功能,例如推断可选的cookie数据(例如域,路径,安全性和主机端口),以解决Rally不返回完整cookie数据的情况(例如测试环境)。

    使用C#ReST API连接到Rally意味着构造RallyRestApi的实例。有两个传统的构造方法采用基本身份验证,并在其他参数中采用用户名和密码。使用这些构造函数之一构造RallyRestApi将始终使用基本身份验证,并且永远不会使用SSO。

    第三个构造函数仅采用IConnectionInfo对象。这是获取RallyRestApi的首选方法。使用IConnectionInfo对象构造RallyRestApi,允许调用者在一个对象中指定所有连接信息,该对象可用于多个RallyRestApi实例之间的SSO回调和身份验证共享。

    IConnectionInfo和ConnectionInfo

    为了促进SSO身份验证,C#ReST API引入了IConnectionInfo接口和ConnectionInfo类。这些类表示持有连接首选项的对象,可以在请求时启动和完成基于浏览器的SSO身份验证会话。 ConnectionInfo类实现所有连接首选项,并具有将Rally SSO登陆页面解析为可用Cookie的方法。如果仅需要基本身份验证,则可以按原样使用此类。如果呼叫者不想扩展或以其他方式使用ConnectionInfo,则IConnectionInfo具有灵活性。

    使用IConnectionInfo进行基本身份验证时,只需创建一个新的ConnectionInfo并设置适当的公共可访问字段。用它来构造一个RallyRestApi。任何身份验证错误都将引发异常。
    Example:
    
    var cInfo = new ConnectionInfo();
    cInfo.UserName = "myName";
    cInfo.Password = "pass";
    cInfo.Server = new Uri("https://host.com");
    cInfo.AuthType = Rally.RestApi.AuthorizationType.Basic;
    
    var conn = new RallyRestApi(cInfo);
    

    将IConnectionInfo用于SSO时,调用者必须实现DoSSOAuth()。以下是带注释的示例。
    public class MyConnectionInfo : Rally.RestApi.ConnectionInfo
    {
        public override void doSSOAuth()
        {
            // Launch a browser to the this.server URI.
            // The browser will close automatically if it successfully reaches the SSO landing page 
            // Users can cancel the SSO handshake
            // Abort if the handshake is successful, but didn't arrive at the SSO landing page
            var ssoDialog = new SSOAuthDialog(server);
            DialogResult result = ssoDialog.ShowDialog();
            if (result == DialogResult.Cancel)
                throw new Exception("SSO authorization canceled");
            else if (result == DialogResult.Abort)
                throw new Exception(ssoDialog.abortReason);
    
            // Parse the SSO landing page into a Cookie and save it
            AuthCookie = parseSSOLandingPage(ssoDialog.getBrowser().DocumentText);
    
            // Infer Cookie values from SO Landing Page URL if not set
            if (String.IsNullOrWhiteSpace(authCookie.Domain) || authCookie.Domain == "null")
                authCookie.Domain = ssoDialog.getBrowser().Url.Host;
            AuthCookie.Secure = String.Equals(ssoDialog.getBrowser().Url.Scheme,"https",StringComparison.InvariantCultureIgnoreCase);
    
            // Set a specific port port if the SSO Landing Page URL has one
            if (!ssoDialog.getBrowser().Url.IsDefaultPort)
                Port = ssoDialog.getBrowser().Url.Port;
        }
    } 
    

    本示例使用带有浏览器组件的WinForms对话框向用户展示SSO握手。请记住,您可以使用要实现此部分的任何显示技术。这是一个带注释的示例:
    public partial class SSOAuthDialog : Form
    {
        public String abortReason;
    
        public SSOAuthDialog(Uri url)
        {
            InitializeComponent();
            webBrowser.Url = url;
        }
    
        private void documentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            // We have found the SSO Landing Page.
            if (webBrowser.DocumentText.Contains("authCookieName") && webBrowser.DocumentText.Contains("authCookieValue"))
            {
                Trace.TraceInformation("Found SSO authentication token on page: {0}", e.Url.AbsolutePath);
                DialogResult = DialogResult.OK;
                Close();
            }
    
            // We have landed on the Rally ALM page
            // This is usually caused by a bad URL 
            else if (webBrowser.DocumentText.Contains("window.FEATURE_TOGGLES"))
            {
                abortReason = String.Format("The SSO handshake was successful, but the 'RelayState' was not correctly set. Contact your administrator to obtain the correct URL parameter to set the SSO handshake 'RelayState' to: https://rally1.rallydev.com/slm/j_sso_security_check?noRedirect=true");
                Trace.TraceError(abortReason);
                DialogResult = DialogResult.Abort;
                Close();
            }
        }
    
        public WebBrowser getBrowser()
        {
            return webBrowser;
        }
    }
    
    SSO Example:
    
    var cInfo = new MyConnectionInfo();
    cInfo.Server = new Uri("https://host");
    cInfo.AuthType = Rally.RestApi.AuthorizationType.SSO;
    
    // This will cause an SSO authentication event
    var conn = new RallyRestApi(cInfo);
    // This will not b/c it will just use the auth Cookie already in cInfo
    var conn2 = new RallyRestApi(cInfo);
    

    将IConnectionInfo用于SSO时,重要的是缓存发送来构造RallyRestApi的IConnectionInfo对象。成功进行SSO握手后,生成的auth Cookie将存储在IConnectionInfo对象中,并将用于该RallyRestApi对象进行的所有后续WSAPI调用。如果您需要通过以前成功的SSO登录使用相同的auth Cookie创建另一个RallyRestApi对象,只需使用相同的IConnectionInfo对象构造一个新的RallyRestApi对象,并且如果存在一个auth Cookie,则将使用它。

    重试

    授权Cookie可能会过期。 C#ReST Api将检测到过期的SSO Cookie,并将根据需要启动新的SSO登录会话以获取新的有效Cookie。

    这里的所有都是它的。

    关于rally - 如何使用Rally.RestApi.dll进行SSO?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21055043/

    相关文章:

    javascript - 想要将 Rally 故事从一个项目复制到另一个项目

    javascript - 是否可以将旧的 Rally 任务板转换为新的 Cardboard

    javascript - Extjs网格单元格编辑器跳离单元格

    java - 如何使用 Rally Rest API 和 Java 将更多测试用例附加到测试集

    rally - 使用 Rally REST API,如何获取用户故事的非 API(网站)URL?

    python - 使用 python(使用 pyral)连接到 Rally 时出现警告 "InsecurePlatformWarning"

    rally - 你可以使用集会 API 发送电子邮件通知吗?

    javascript - 向图表添加数据

    javascript - 未为新功能记录生成 FormattedID

    javascript - Rally SDK 2 标签选择器是否有必填字段?对象没有方法 'getContextPath'