WebAuthenticationBroker是否在Release 8候选版本的Windows 8 Metro App中运行
解决方案我的工作解决方案可以在答案或我的更新中找到。
1)现在确保在localhost上测试您已在localhost端口上为入站设置了Windows防火墙。 路由器上的端口转发(如果有)。
2)然后你需要告诉IIS Express可以请求来自本地主机的现场:查找Documents \ IISExpress \ config并编辑applicationhost.config。 在列表中找到您的站点,并从绑定中删除localhost 。
2a)ISS需要以管理员身份运行,以管理员身份运行visual studio也以admin身份启动iss …
3)找到您的IP,www.myip.com并将ACS返回uri更改为:http: http://90.90.90.90:909090/api/federation/
: http://90.90.90.90:909090/api/federation/
4)更改webbroker以使用你的ip:
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"));
一切都像这样对我有用。 我有一个hello world传递给我的metro应用程序作为令牌。
问题
我已经设置了WCF服务和Metro应用程序。 WCF服务设置为使用Azure ACS进行身份validation。
我制作了一个适用于WebService和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; }
当我想从我的Metro应用程序中使用它时,我现在面临两个问题。 第一个与服务无关,与WebAuthenticationBroker有关。
1)当我使用
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") );
我可以使用,LiveID,Facebook等登录。 不是谷歌,因为ACS没有正确包含ID。 但是我没有得到任何令牌或声明。 我只得到:
https://s-innovations.accesscontrol.windows.net/v2/wsfederation?wa=wsignin1.0 https://s-innovations.accesscontrol.windows.net/v2/facebook?cx=cHI9d3NmZWRlcmF0aW9uJn…cmFmZmljdGhlb3J5LmF6dXJld2Vic2l0ZXMubmV0JTJmJmlwPUZhY2Vib29rLTM1NTk5MjQ2NzgxNzc5OQ2&code=AQDagvqoXQ …….
我怎么得到这部电影最后的声明: http : //channel9.msdn.com/Events/BUILD/BUILD2011/SAC-858T他的应用程序有效!
2)上面显示的控制台应用程序经过身份validation并在调用API时获取令牌传递给服务,如何从metro应用程序中获取此令牌。
UPDATE
我按照建议创建了控制器:
[HttpPost] public ActionResult End() { return Json("Hello World"); }
我已经提出了一个突破点,看它是否得到它。 还没打到。
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"));
在我的依赖方应用程序上我有一个
Realm http://localhost:909090/ Return Url: Nothing (have tried http://localhost:909090/Federation/End )
响应数据现在包含: http://localhost:909090/Federation/End
。
更新2
我还尝试使用api控制器,如您在另一篇文章中所示:
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"; }
}
现在,登录屏幕只是挂起并以您正在寻找的服务结束,现在还没有准备好(或类似的东西)。
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"));
WebAuthenticationBroker
只是继续浏览,直到下一个请求的页面是callbackUri
参数指定的页面。 此时它会返回给您的最终URL,因此如果您想要获取任何内容,则需要在该URL中进行编码。
在依赖方的ACS控制面板中,您需要指定站点上某处的返回URL。 例如https://traffictheory.azurewebsites.net/federationcallback
。 然后创建一个控制器来处理接受该URL的post。 该post将有一个表单字段wresult
,它是一些xml,它将包含从ACS返回的令牌。
然后,您可以通过重定向到https://traffictheory.azurewebsites.net/federationcallback/end?token={whatever you want to return}
将令牌发送回WebAuthenticationBroker
。
然后,您需要将身份validation代理的使用情况更改为以下内容:
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);
我的处理身份validation回调帖的控制器看起来像这样。
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(); } }
BootstrapToken()
扩展方法是wif.swt
NuGet包的一部分。 默认情况下,WIF不会通过在web.config中的
下的
元素中包含saveBootstrapTokens="true"
属性来保存启动它所需的任何引导令牌属性。 我看起来像这样: