我想做的事情与Excel Addin Export功能完全相同,但想要在纯.net应用程序中执行.
谢谢,斯科特
简短的拉力赛SSO入门
Rally Web服务API(WSAPI)本身仅支持基本身份验证.使用基本身份验证,必须使用用户名和密码启动WSAPI会话,该用户名和密码将根据直接存储在Rally中的用户名和密码列表进行验证.这可以正常工作,直到客户开始使用单点登录(SSO). SSO允许客户端使用单个企业范围的身份验证机制(如LDAP或Active Directory)来管理用户凭据和密码.到目前为止,使用启用了SSO的WSAPI要求客户端在Rally中为希望使用Rally WSAPI的所有用户维护重复的用户列表(“白色”列表).最近对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将是客户特定的.有关SSO URL的帮助,请联系您的Rally TAM或Rally支持.
原始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 RelayState.其他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调用一起传递,则将成功验证这些调用.请注意,必须从根据IETF Cookie规范获取cookie的调用推断出安全和路径等可选cookie数据.
因此,为了发出WSAPI调用,从GUI界面登录Rally的基本过程(再次,这对无头环境不起作用)如下:
>使用上述特殊参数从用户收集SSO URL.
>启动指向该URL的浏览器.
>导航完成后,从返回的HTML页面中抓取cookie值.
>关闭浏览器.
>根据cookie值构造cookie.
>存储该cookie以供以后使用.
>使用所有后续WSAPI调用发送该cookie.
如果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的方法.如果只需要基本身份验证,则可以按原样使用此类. IConnectionInfo在调用者不想扩展或以其他方式使用ConnectionInfo的情况下具有灵活性.
使用IConnectionInfo进行Basic Auth时,只需创建一个新的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时,重要的是缓存您发送的IConnectionInfo对象以构造RallyRestApi.成功进行SSO握手后,生成的auth Cookie将存储在IConnectionInfo对象中,并将用于从该RallyRestApi对象进行的所有后续WSAPI调用.如果您需要使用先前成功的SSO登录中使用相同的auth Cookie创建另一个RallyRestApi对象,只需使用相同的IConnectionInfo对象构造一个新的RallyRestApi对象,如果存在auth Cookie,则将使用它.
重试
授权Cookie可能会过期. C#ReST Api将检测过期的SSO Cookie,并根据需要启动新的SSO登录会话以获取新的有效Cookie.
这里的所有都是它的.