- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个网站和 API,使用我们公司的 ADFS 支持的 token 服务进行保护。我需要使用 C# 控制台应用程序访问 API 上的端点。我发现缺少使用 C# 代码访问 STS 安全网站的资源。它使用 ADFS 3.0。
当我使用 HttpClient
(或类似的)访问端点时,我会收到一个 HTML 表单作为返回。
我的代码:
Uri baseAddress = new Uri("http://localhost:64022");
using (HttpClient client = new HttpClient() { BaseAddress = baseAddress })
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "#");
HttpResponseMessage response = client.SendAsync(request).Result;
var encoding = ASCIIEncoding.ASCII;
using (var reader = new System.IO.StreamReader(response.Content.ReadAsStreamAsync().Result, encoding))
{
string responseText = reader.ReadToEnd();
}
}
我在我的应用程序的 web.config 文件中的设置是:
<system.identityModel.services>
<federationConfiguration>
<cookieHandler requireSsl="false" persistentSessionLifetime="1.0:0:0" />
<wsFederation persistentCookiesOnPassiveRedirects="true" passiveRedirectEnabled="true" issuer="https://sts.company.com/adfs/ls/" realm="http://myapp.company.com/" requireHttps="false" />
</federationConfiguration>
</system.identityModel.services>
<system.identityModel>
<identityConfiguration>
<audienceUris>
<add value="http://myapp.company.com/" />
</audienceUris>
<issuerNameRegistry>
<trustedIssuers>
<add thumbprint="0000000000000000000000000000000000000000" name="https://sts.company.com/adfs/services/trust" />
</trustedIssuers>
</issuerNameRegistry>
</identityConfiguration>
</system.identityModel>
我不确定各种术语是什么。我的远程地址是什么?我的客户编号?什么是指纹?
最佳答案
我想出了如何做到这一点。我不能肯定地说这是否是可能的最佳实现方式,但它对我有用。
类 ADFS token 提供者
public class ADFSUsernameMixedTokenProvider
{
private readonly Uri adfsUserNameMixedEndpoint;
/// <summary>
/// Initializes a new instance of the <see cref="ADFSUsernameMixedTokenProvider"/> class
/// </summary>
/// <param name="adfsUserNameMixedEndpoint">i.e. https://adfs.mycompany.com/adfs/services/trust/13/usernamemixed </param>
public ADFSUsernameMixedTokenProvider(Uri adfsUserNameMixedEndpoint)
{
this.adfsUserNameMixedEndpoint = adfsUserNameMixedEndpoint;
}
/// <summary>
/// Requests a security token from the ADFS server
/// </summary>
/// <param name="username">The username</param>
/// <param name="password">The password</param>
/// <param name="endpoint">The ADFS endpoint</param>
/// <returns></returns>
public GenericXmlSecurityToken RequestToken(string username, SecureString password, string endpoint)
{
WSTrustChannelFactory factory = new WSTrustChannelFactory(
new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
new EndpointAddress(adfsUserNameMixedEndpoint));
factory.TrustVersion = TrustVersion.WSTrust13;
factory.Credentials.UserName.UserName = username;
factory.Credentials.UserName.Password = new System.Net.NetworkCredential(string.Empty, password).Password;
RequestSecurityToken token = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
AppliesTo = new EndpointReference(endpoint),
KeyType = KeyTypes.Bearer
};
IWSTrustChannelContract channel = factory.CreateChannel();
return channel.Issue(token) as GenericXmlSecurityToken;
}
}
类认证
public class Authentication
{
private GenericXmlSecurityToken token;
private string site = "https://my.site.com"
private string appliesTo = "http://my.site.com"
private string authUsernameEndpoint = "https://sts-prod.site.com/adfs/services/trust/13/usernamemixed";
public Authentication(PSCredential credential)
{
ADFSUsernameMixedTokenProvider tokenProvider = new ADFSUsernameMixedTokenProvider(new Uri(authUsernameEndpoint));
token = tokenProvider.RequestToken(credential.UserName, credential.Password, appliesTo);
}
public CookieContainer GetFedAuthCookies()
{
string prepareToken = WrapInSoapMessage(token, appliesTo);
string samlServer = site.EndsWith("/") ? site : site + "/";
string stringData = $"wa=wsignin1.0&wresult={HttpUtility.UrlEncode(prepareToken)}&wctx={HttpUtility.UrlEncode("rm=1&id=passive&ru=%2f")}";
CookieContainer cookies = new CookieContainer();
HttpWebRequest request = WebRequest.Create(samlServer) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.CookieContainer = cookies;
request.AllowAutoRedirect = false;
byte[] data = Encoding.UTF8.GetBytes(stringData);
request.ContentLength = data.Length;
using (Stream stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
using (Stream stream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(stream))
{
string responseFromServer = reader.ReadToEnd();
}
}
}
return cookies;
}
private string WrapInSoapMessage(GenericXmlSecurityToken token, string site)
{
string validFrom = token.ValidFrom.ToString("o");
string validTo = token.ValidTo.ToString("o");
string securityToken = token.TokenXml.OuterXml;
string soapTemplate = @"<t:RequestSecurityTokenResponse xmlns:t=""http://schemas.xmlsoap.org/ws/2005/02/trust""><t:Lifetime><wsu:Created xmlns:wsu=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"">{0}</wsu:Created><wsu:Expires xmlns:wsu=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"">{1}</wsu:Expires></t:Lifetime><wsp:AppliesTo xmlns:wsp=""http://schemas.xmlsoap.org/ws/2004/09/policy""><wsa:EndpointReference xmlns:wsa=""http://www.w3.org/2005/08/addressing""><wsa:Address>{2}</wsa:Address></wsa:EndpointReference></wsp:AppliesTo><t:RequestedSecurityToken>{3}</t:RequestedSecurityToken><t:TokenType>urn:oasis:names:tc:SAML:1.0:assertion</t:TokenType><t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType><t:KeyType>http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey</t:KeyType></t:RequestSecurityTokenResponse>";
return string.Format(soapTemplate, validFrom, validTo, site, securityToken);
}
}
用法
Authentication auth = new Authentication(credential);
CookieContainer container = auth.GetFedAuthCookies();
HttpWebRequest request = WebRequest.Create("https://api.my.site.com/") as HttpWebRequest;
request.Method = method;
request.ContentType = "application/json";
request.CookieContainer = cookieContainer;
request.AllowAutoRedirect = false;
using (WebResponse response = request.GetResponse())
{
using (Stream dataStream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(dataStream))
{
return JsonConvert.DeserializeObject<dynamic>(reader.ReadToEnd());
}
}
}
我将其与 PowerShell cmdlet 一起使用,这是 PSCredential 对象的来源。我希望这对想要从 C# 控制台应用程序使用 ADFS 3.0 进行身份验证的人有所帮助 - 我花了比我愿意承认的时间更长的时间。
关于c# - 使用控制台应用程序进行 ADFS STS 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39261413/
在 JSF2 应用程序中遇到验证属性的问题时,有两种主要方法。 使用 Annotation 在 ManagedBean 上定义验证 @ManagedBean public class MyBean {
我想实现一个不常见的功能,我认为 jquery 验证插件将是最好的方法(如果您在没有插件的情况下建议和回答,我们也会欢迎)。我想在用户在输入字段中输入正确的单词后立即隐藏表单。我试过这个: $("
我有几个下拉菜单(类名为month_dropdown),并且下拉菜单的数量不是恒定的。我怎样才能为它们实现 NotEqual 验证。我正在使用 jQuery 验证插件。 这就是我写的 - jQuery
我设法制作了这个网址验证代码并且它起作用了。但我面临着一个问题。我认为 stackoverflow 是获得解决方案的最佳场所。 function url_followers(){ var url=do
我目前正在使用后端服务,该服务允许用户在客户端应用程序上使用 Google Games 库登录。 用户可以通过他们的 gplay ID 向我们发送信息,以便登录或恢复旧帐户。用户向我们发送以下内容,包
我正在尝试验证输入以查看它是否是有效的 IP 地址(可能是部分地址)。 可接受的输入:172、172.112、172.112.113、172.112.113.114 Not Acceptable 输入
我从 Mongoose 验证中得到这条消息: 'Validator failed for path phone with value ``' 这不应该发生,因为不需要电话。 这是我的模型架构: var
我一直在尝试使用Python-LDAP (版本 2.4.19)在 MacOS X 10.9.5 和 Python 2.7.9 下 我想在调用 .start_tls_s() 后验证与给定 LDAP 服务
我正在处理一个仅与 IE6 兼容的旧 javascript 项目(抱歉...),我想仅在 VS 2017 中禁用此项目的 ESLint/CSLint/Javascript 验证/CSS 验证。 我知道
我正在寻找一种方法来验证 Spring 命令 bean 中的 java.lang.Double 字段的最大值和最小值(一个值必须位于给定的值范围之间),例如, public final class W
我正在尝试在 springfuse(JavaEE 6 + Spring Framework (针对 Jetty、Tomcat、JBoss 等)) 和 maven 的帮助下构建我的 webapps 工作
我试图在我们的项目中使用 scalaz 验证,但遇到了以下情况: def rate(username: String, params: Map[String, String]): Validation
我有一个像这样的 Yaml 文件 name: hhh_aaa_bbb arguments: - !argument name: inputsss des
我有一个表单,人们可以单击并向表单添加字段,并且我需要让它在单击时验证这些字段中的值。 假设我单击它两次并获取 2 个独立的字段集,我需要旋转 % 以确保它在保存时等于 100。 我已放入此函数以使其
在我的页面中有一个选项可以创建新的日期字段输入框。用户可以根据需要创建尽可能多的“截止日期”和“起始日期”框。就像, 日期_to1 || date_from1 日期到2 ||日期_from2 date
我有一个像这样的 Yaml 文件 name: hhh_aaa_bbb arguments: - !argument name: inputsss des
有没有办法在动态字段上使用 jquery 验证表单。 我想将其设置为必填字段 我正在使用 Jsp 动态创建表单字段。 喜欢 等等...... 我想使用必需的表单字段验证此表单字段。 最佳答
嗨,任何人都可以通过提供 JavaScript 代码来帮助我验证用户名文本框不应包含数字,它只能包含一个字符。 最佳答案 使用正则表达式: (\d)+ 如果找到匹配项,则字符串中就有一个数字。 关于J
我有两个输入字段holidayDate和Description(id=tags) $(document).ready(function() {
我遇到了这个问题,这些验证从电子邮件验证部分开始就停止工作。 我只是不明白为什么即使经过几天的观察,只是想知道是否有人可以在这里指出我的错误? Javascript部分: function valid
我是一名优秀的程序员,十分优秀!