问题描述
解决方案:我工作的解决方案可以在答案或在我的更新两个被发现。
1)现在确保,对本地主机测试,你必须设置窗口的防火墙入站本地主机端口上。路由器上的端口转发,如果你有一个。
2)然后,你需要告诉IIS防爆preSS其没关系,该请求来自outsite本地主机:查找的文档\ IISEx preSS \ config并编辑对ApplicationHost.config。找到您的网站列表和删除从本地主机绑定
<网站名称=S-Innovations.TrafficTheory.Web2ID =1591449597>
<应用路径=/applicationPool =Clr4IntegratedAppPool>
< virtualDirectory路径=/physicalPath =G:\文档\的Visual Studio 2012 \项目\ S-Innovations.TrafficTheory \ S-Innovations.TrafficTheory.Web2/>
< /用途>
<绑定>
<约束力的议定书=HTTPbindingInformation =*:909090:本地主机/>
< /绑定>
< /网站>
2A),国际空间站需要以管理员身份运行,运行Visual Studio以管理员身份也开始国际空间站作为管理...
3)找到你的ip,www.myip.com和改变ACS返回的URI: http://90.90.90.90:909090/api/federation/
4)改变WebBroker的使用你的IP也:
WebAuthenticationResult webAuthenticationResult =等待WebAuthenticationBroker.AuthenticateAsync(
WebAuthenticationOptions.None,
新Uri("https://traffictheory.accesscontrol.windows.net:443/v2/wsfederation?wa=wsignin1.0&wtrealm=http%3a%2f%2flocalhost%3a48451%2f"),
新的URI(http://99.99.99.99:909090/api/federation/end));
一切工作对我来说是这样的。我有一个Hello World传递给我的地铁应用程序的令牌。
问题
我已经建立了一个WCF服务和地铁应用程序。WCF服务设置使用Azure的ACS认证。
我做了一个控制台应用程序与Web Service与ACS的作品:
静态无效的主要(字串[] args)
{
尝试
{
//首先启动Web项目,那么客户端
Web客户端的客户端=新的Web客户端();
VAR令牌= RetrieveACSToken();
client.Headers.Add(授权,令牌);
client.Headers.Add(内容型,为text / xml);
VAR URL =新的URI(http://traffictheory.azurewebsites.net/UserService.svc/Users);
// VAR URL =新的URI(HTTP://本地主机:4000 / UserService.svc /用户); //
流流= client.OpenRead(URL);
StreamReader的读者=新的StreamReader(流);
串响应= reader.ReadToEnd();
Console.Write(响应);
}
赶上(例外前)
{
Console.Write(ex.Message);
}
到Console.ReadLine();
}
私人静态字符串RetrieveACSToken()
{
变种acsHostName = ConfigurationManager.AppSettings.Get(ACSHostName);
变种acsNamespace = ConfigurationManager.AppSettings.Get(ACSNamespace);
变种的用户名= ConfigurationManager.AppSettings.Get(ServiceIdentityUserName);
VAR密码= ConfigurationManager.AppSettings.Get(ServiceIdentityCredentialPassword);
VAR范围=http://traffictheory.azurewebsites.net/;
// VAR范围=HTTP://本地主机:4000 /; //
//要求从ACS令牌
Web客户端的客户端=新的Web客户端();
client.BaseAddress =的String.Format(HTTPS:// {0} {1},acsNamespace,acsHostName);
NameValueCollection中值=新
的NameValueCollection();
values.Add(wrap_name,用户名);
values.Add(wrap_password,密码);
values.Add(wrap_scope,范围);
byte []的responseBytes =
client.UploadValues(WRAPv0.9,POST,值);
字符串响应=
Encoding.UTF8.GetString(responseBytes);
字符串标记=响应
.Split('和;')
。单(值=>
value.StartsWith(wrap_access_token =,
StringComparison.OrdinalIgnoreCase))
.Split(=)[1];
VAR德codedToken =的String.Format(WRAP access_token = \{0} \,HttpUtility.UrlDe code(令牌));
返回去codedToken;
}
我面临着两个问题,现在,当我想从我的地铁应用程序使用它。第一个是无关的服务,是关于WebAuthenticationBroker。
1) 当我用
WebAuthenticationResult webAuthenticationResult =等待WebAuthenticationBroker.AuthenticateAsync(
WebAuthenticationOptions.None,
新Uri("https://s-innovations.accesscontrol.windows.net:443/v2/wsfederation?wa=wsignin1.0&wtrealm=http%3a%2f%2ftraffictheory.azurewebsites.net%2f"),
新的URI(https://s-innovations.accesscontrol.windows.net)
);
我能够登录使用,LiveID的,脸谱等。不是谷歌,因为ACS不要有正确的ID。但我没有得到任何形式的代币的背面或索赔。我只得到:
https://s-innovations.accesscontrol.windows。净/ V2 / wsfederation?WA = wsignin1.0 https://s-innovations.accesscontrol.windows.net/v2/facebook?cx=cHI9d3NmZWRlcmF0aW9uJn...cmFmZmljdGhlb3J5LmF6dXJld2Vic2l0ZXMubmV0JTJmJmlwPUZhY2Vib29rLTM1NTk5MjQ2NzgxNzc5OQ2&$c$c=AQDagvqoXQ.......
我如何获得索赔就像这个电影的结尾: http://channel9.msdn.com/Events/BUILD/BUILD2011/SAC-858T 他的应用程序的工作原理!
2)如上图所示得到验证并获得令牌的控制台应用程序来调用API的时候,我如何获得这个令牌中的地铁应用程序传递给服务。
更新
我创建的控制器提示:
[HttpPost]
公众的ActionResult结束()
{
返回JSON(的Hello World);
}
我已经把一个破发点,看它是否得到它。没有打呢。
WebAuthenticationResult webAuthenticationResult =等待WebAuthenticationBroker.AuthenticateAsync(
WebAuthenticationOptions.None,
新Uri("https://traffictheory.accesscontrol.windows.net:443/v2/wsfederation?wa=wsignin1.0&wtrealm=http%3a%2f%2flocalhost%3a48451%2f"),
新的URI(HTTP://本地主机:909090 /联合会/结束));
在我的信赖方应用程序我ahave
服务器的http://本地主机:909090 /
返回URL:没有(已尝试的http://本地主机:909090 /协会/完)
响应数据包含:的http://本地主机:909090 /协会/结束
现在
更新2
我也试过用API控制器,你在另一篇文章显示:
公共类FederationController:ApiController{
公开的Htt presponseMessage帖子()
{
VAR响应= this.Request.CreateResponse(的HTTPStatus code.Redirect);
response.Headers.Add(位置,/ API /联合会/结束acsToken =?+ ExtractBootstrapToken());
返回响应;
}
公共字符串获得()
{
返回的Hello World;
}
受保护的虚拟串ExtractBootstrapToken()
{
返回的Hello World;
}
}
现在的登录界面只挂和你正在寻找一个服务端还没有准备好,现在(或类似的东西)。
ACS返回URL 的http://本地主机:48451 / API /联邦
WebAuthenticationResult webAuthenticationResult =等待WebAuthenticationBroker.AuthenticateAsync(
WebAuthenticationOptions.None,
新Uri("https://traffictheory.accesscontrol.windows.net:443/v2/wsfederation?wa=wsignin1.0&wtrealm=http%3a%2f%2flocalhost%3a909090%2f"),
新的URI(HTTP://本地主机:909090 / API /联合会/结束));
在 WebAuthenticationBroker
只是不断浏览,直到下一个请求的页面是由<$ C $指定的C> callbackUri 参数。在这一点上,它返回最终网址给你,所以如果你想要得到任何东西它需要连接codeD中的URL。
在ACS控制面板,你需要指定一个返回URL是您网站上的某个地方依赖方。例如 https://traffictheory.azurewebsites.net/federationcallback
。然后创建一个控制器来处理接受后到该网址。该职位将有一个表单字段 wresult
这是一些XML将包含来自ACS返回的标记。
您可以发送令牌回 WebAuthenticationBroker
重定向到 https://traffictheory.azurewebsites.net/federationcallback/end?token = {任何你想要返回}
您然后将需要身份验证代理的用途更改为以下内容:
VAR webAuthenticationResult =等待WebAuthenticationBroker.AuthenticateAsync(
WebAuthenticationOptions.None,
新Uri("https://s-innovations.accesscontrol.windows.net:443/v2/wsfederation?wa=wsignin1.0&wtrealm=http%3a%2f%2ftraffictheory.azurewebsites.net%2f"),
新的URI(https://traffictheory.azurewebsites.net/federationcallback/end)
);
//数据你返回
VAR令牌= authenticateResult.ResponseData.Substring(authenticateResult.ResponseData.IndexOf(标记=,StringComparison.Ordinal)+ 6);
我的控制器来处理身份验证回调后看起来是这样的。
公共类FederationcallbackController:ApiController
{
公众的Htt presponseMessage帖子()
{
VAR响应= this.Request.CreateResponse(的HTTPStatus code.Redirect);
response.Headers.Add(位置,/ API / federationcallback /结束acsToken =?+ ExtractBootstrapToken());
返回响应;
}
受保护的虚拟串ExtractBootstrapToken()
{
返回HttpContext.Current.User.BootstrapToken();
}
}
在 BootstrapToken()
extenion方法是 wif.swt
的NuGet包的一部分。默认情况下WIF没有任何东西保存到你需要包括对&LT的
在 saveBootstrapTokens =真正的
属性,使其能够引导令牌财产;服务&GT; &LT元素; microsoft.identityModel&GT;
在你的web.config。我的是这样的:
&LT; microsoft.identityModel&GT;
&LT;服务saveBootstrapTokens =真正的&GT;
&LT; audienceUris&GT;
&LT;增加值=HTTP://本地主机:3949 //&GT;
&LT; / audienceUris&GT;
&LT; federatedAuthentication&GT;
&LT; wsFederation passiveRedirectEnabled =真发行人=https://xyz.accesscontrol.windows.net/v2/wsfederation的境界=HTTP://本地主机:3949 /回复=HTTP://本地主机:3949 / requireHttps =FALSE/&GT;
&LT;的CookieHandler requireSsl =假路径=//&GT;
&LT; / federatedAuthentication&GT;
&LT; issuerNameRegistry TYPE =Microsoft.IdentityModel.Swt.SwtIssuerNameRegistry,Wif.Swt&GT;
&LT; trustedIssuers&GT;
&LT;添加名称=https://readify.accesscontrol.windows.net/指纹={}指纹/&GT;
&LT; / trustedIssuers&GT;
&LT; / issuerNameRegistry&GT;
&LT; securityTokenHandlers&GT;
&LT;加上TYPE =Microsoft.IdentityModel.Swt.SwtSecurityTokenHandler,Wif.Swt/&GT;
&LT; / securityTokenHandlers&GT;
&LT; issuerTokenResolver TYPE =Microsoft.IdentityModel.Swt.SwtIssuerTokenResolver,Wif.Swt/&GT;
&LT; /服务&GT;
&LT; /microsoft.identityModel>
SOLUTIONMy working solution can be found in the answer or in my update two.
1) Now make sure, for testing on localhost, that you have setup windows firewalls for inbound on the localhost port. Port forwarding on the router if you have one.
2) Then you need to tell IIS Express that its okay that the request comes from outsite the localhost:Find Documents\IISExpress\config and edit applicationhost.config. Find your site in the list and remove the localhost from the binding.
<site name="S-Innovations.TrafficTheory.Web2" id="1591449597">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="G:\Documents\Visual Studio 2012\Projects\S-Innovations.TrafficTheory\S-Innovations.TrafficTheory.Web2" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:909090:localhost" />
</bindings>
</site>
2a) ISS need to run as administrator, running visual studio as administrator also starts iss as admin...
3) Locate your ip, www.myip.com and change the ACS return uri to : http://90.90.90.90:909090/api/federation/
4) change the webbroker to use your ip also:
WebAuthenticationResult webAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(
WebAuthenticationOptions.None,
new Uri("https://traffictheory.accesscontrol.windows.net:443/v2/wsfederation?wa=wsignin1.0&wtrealm=http%3a%2f%2flocalhost%3a48451%2f"),
new Uri("http://99.99.99.99:909090/api/federation/end"));
Everything worked for me like this. I got a hello world passed on to my metro app as the token.
Problem
I have set up a WCF Service and a Metro App.The WCF service is set up to authenticate using Azure ACS.
I made a Console Application that works with the WebService and ACS:
static void Main(string[] args)
{
try
{
// First start the web project, then the client
WebClient client = new WebClient();
var token = RetrieveACSToken();
client.Headers.Add("Authorization", token);
client.Headers.Add("Content-type", "text/xml");
var url = new Uri("http://traffictheory.azurewebsites.net/UserService.svc/Users");
//var url = new Uri("http://localhost:4000/UserService.svc/Users");//
Stream stream = client.OpenRead(url);
StreamReader reader = new StreamReader(stream);
String response = reader.ReadToEnd();
Console.Write(response);
}
catch (Exception ex)
{
Console.Write(ex.Message);
}
Console.ReadLine();
}
private static string RetrieveACSToken()
{
var acsHostName = ConfigurationManager.AppSettings.Get("ACSHostName");
var acsNamespace = ConfigurationManager.AppSettings.Get("ACSNamespace");
var username = ConfigurationManager.AppSettings.Get("ServiceIdentityUserName");
var password = ConfigurationManager.AppSettings.Get("ServiceIdentityCredentialPassword");
var scope = "http://traffictheory.azurewebsites.net/";
//var scope = "http://localhost:4000/";//
// request a token from ACS
WebClient client = new WebClient();
client.BaseAddress = string.Format("https://{0}.{1}", acsNamespace, acsHostName);
NameValueCollection values = new
NameValueCollection();
values.Add("wrap_name", username);
values.Add("wrap_password", password);
values.Add("wrap_scope", scope);
byte[] responseBytes =
client.UploadValues("WRAPv0.9", "POST", values);
string response =
Encoding.UTF8.GetString(responseBytes);
string token = response
.Split('&')
.Single(value =>
value.StartsWith("wrap_access_token=",
StringComparison.OrdinalIgnoreCase))
.Split('=')[1];
var decodedToken = string.Format("WRAP access_token=\"{0}\"", HttpUtility.UrlDecode(token));
return decodedToken;
}
I face two problems now when i want to use it from my Metro App.First one is unrelated to the service and is about the WebAuthenticationBroker.
1) When i use
WebAuthenticationResult webAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(
WebAuthenticationOptions.None,
new Uri("https://s-innovations.accesscontrol.windows.net:443/v2/wsfederation?wa=wsignin1.0&wtrealm=http%3a%2f%2ftraffictheory.azurewebsites.net%2f"),
new Uri("https://s-innovations.accesscontrol.windows.net")
);
I am able to log in using, LiveID, Facebook ect. Not google because ACS dont include the ID correctly. But I dont get any kind of token back or Claims. I only get:
https://s-innovations.accesscontrol.windows.net/v2/wsfederation?wa=wsignin1.0https://s-innovations.accesscontrol.windows.net/v2/facebook?cx=cHI9d3NmZWRlcmF0aW9uJn...cmFmZmljdGhlb3J5LmF6dXJld2Vic2l0ZXMubmV0JTJmJmlwPUZhY2Vib29rLTM1NTk5MjQ2NzgxNzc5OQ2&code=AQDagvqoXQ.......
How do I get the claims like in the end of this movie:http://channel9.msdn.com/Events/BUILD/BUILD2011/SAC-858THis app works!
2)The console app shown above get authenticated and get the token to pass to the service when calling the API, how do i get this token from within the metro app.
UPDATE
I created the controller as suggested:
[HttpPost]
public ActionResult End()
{
return Json("Hello World");
}
I have put in a break point to see if it get it. No hit yet.
WebAuthenticationResult webAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(
WebAuthenticationOptions.None,
new Uri("https://traffictheory.accesscontrol.windows.net:443/v2/wsfederation?wa=wsignin1.0&wtrealm=http%3a%2f%2flocalhost%3a48451%2f"),
new Uri("http://localhost:909090/Federation/End"));
On my Relying Party Application i ahave
Realm http://localhost:909090/
Return Url: Nothing (have tried http://localhost:909090/Federation/End )
The response data contains : http://localhost:909090/Federation/End
right now.
UPDATE 2
I also tried with an api controller as you shown in another post:
public class FederationController : ApiController{
public HttpResponseMessage Post()
{
var response = this.Request.CreateResponse(HttpStatusCode.Redirect);
response.Headers.Add("Location", "/api/federation/end?acsToken=" + ExtractBootstrapToken());
return response;
}
public string Get()
{
return "hello world";
}
protected virtual string ExtractBootstrapToken()
{
return "Hello World";
}
}
Now the login screen just hang and ends with a service you looking for is not ready right now (or something like that).
acs return url http://localhost:48451/api/Federation
WebAuthenticationResult webAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(
WebAuthenticationOptions.None,
new Uri("https://traffictheory.accesscontrol.windows.net:443/v2/wsfederation?wa=wsignin1.0&wtrealm=http%3a%2f%2flocalhost%3a909090%2f"),
new Uri("http://localhost:909090/api/federation/end"));
The WebAuthenticationBroker
simply keeps browsing until the next requested page is the one specified by the callbackUri
parameter. At that point it returns the final URL to you so if you want to get anything back it needs to be encoded in that URL.
In the ACS control panel for the relying party you need to specify a return url that is somewhere on your site. For example https://traffictheory.azurewebsites.net/federationcallback
. Then create a controller to handle accept a post to that URL. The post will have a form field wresult
which is some xml that will contain the token returned from ACS.
You can then send the token back to the WebAuthenticationBroker
by redirecting to https://traffictheory.azurewebsites.net/federationcallback/end?token={whatever you want to return}
You would then need to change the usage of the authentication broker to the following:
var webAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(
WebAuthenticationOptions.None,
new Uri("https://s-innovations.accesscontrol.windows.net:443/v2/wsfederation?wa=wsignin1.0&wtrealm=http%3a%2f%2ftraffictheory.azurewebsites.net%2f"),
new Uri("https://traffictheory.azurewebsites.net/federationcallback/end")
);
// The data you returned
var token = authenticateResult.ResponseData.Substring(authenticateResult.ResponseData.IndexOf("token=", StringComparison.Ordinal) + 6);
My controller for handling the authentication callback post looks like this.
public class FederationcallbackController : ApiController
{
public HttpResponseMessage Post()
{
var response = this.Request.CreateResponse(HttpStatusCode.Redirect);
response.Headers.Add("Location", "/api/federationcallback/end?acsToken=" + ExtractBootstrapToken());
return response;
}
protected virtual string ExtractBootstrapToken()
{
return HttpContext.Current.User.BootstrapToken();
}
}
The BootstrapToken()
extenion method is part of the wif.swt
NuGet package. By default WIF doesn't save anything to the bootstrap token property you need to enable it by including the saveBootstrapTokens="true"
attribute on the <service>
element under <microsoft.identityModel>
in your web.config. Mine looks like this:
<microsoft.identityModel>
<service saveBootstrapTokens="true">
<audienceUris>
<add value="http://localhost:3949/" />
</audienceUris>
<federatedAuthentication>
<wsFederation passiveRedirectEnabled="true" issuer="https://xyz.accesscontrol.windows.net/v2/wsfederation" realm="http://localhost:3949/" reply="http://localhost:3949/" requireHttps="false" />
<cookieHandler requireSsl="false" path="/" />
</federatedAuthentication>
<issuerNameRegistry type="Microsoft.IdentityModel.Swt.SwtIssuerNameRegistry, Wif.Swt">
<trustedIssuers>
<add name="https://readify.accesscontrol.windows.net/" thumbprint="{thumbprint}" />
</trustedIssuers>
</issuerNameRegistry>
<securityTokenHandlers>
<add type="Microsoft.IdentityModel.Swt.SwtSecurityTokenHandler, Wif.Swt" />
</securityTokenHandlers>
<issuerTokenResolver type="Microsoft.IdentityModel.Swt.SwtIssuerTokenResolver, Wif.Swt" />
</service>
</microsoft.identityModel>
这篇关于是否在Windows 8地铁应用程序后候选发布版的WebAuthenticationBroker工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!