且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

验证一个SWT令牌REST WCF服务

更新时间:2022-10-17 20:12:50

令牌,这是我发送给服务器,有格式错误。
以上令牌是一个JSON格式,并包含一个securityToken',这是EN codeD XML。随着 HttpUtility.UrlDe code 的XMLReader 就可以检索的base64字符串。上述令牌的基于64位字符串是:

aHR0cCUzYSUyZiUyZnNjaGVtYXMueG1sc29hcC5vcmclMmZ3cyUyZjIwMDUlMmYwNSUyZmlkZW50aXR5JTJmY2xhaW1zJTJmZW1haWxhZGRyZXNzPXBhdHJpY2suZWNrZXIlNDBnbWFpbC5jb20maHR0cCUzYSUyZiUyZnNjaGVtYXMueG1sc29hcC5vcmclMmZ3cyUyZjIwMDUlMmYwNSUyZmlkZW50aXR5JTJmY2xhaW1zJTJmbmFtZT1QYXRyaWNrK0Vja2VyJmh0dHAlM2ElMmYlMmZzY2hlbWFzLnhtbHNvYXAub3JnJTJmd3MlMmYyMDA1JTJmMDUlMmZpZGVudGl0eSUyZmNsYWltcyUyZm5hbWVpZGVudGlmaWVyPWh0dHBzJTNhJTJmJTJmd3d3Lmdvb2dsZS5jb20lMmZhY2NvdW50cyUyZm84JTJmaWQlM2ZpZCUzZEFJdE9hd2xzM1doNlgwRFJ6d1BsdzU2a1R0WURmLVNNaDZxZFJtQSZodHRwJTNhJTJmJTJmc2NoZW1hcy5taWNyb3NvZnQuY29tJTJmYWNjZXNzY29udHJvbHNlcnZpY2UlMmYyMDEwJTJmMDclMmZjbGFpbXMlMmZpZGVudGl0eXByb3ZpZGVyPUdvb2dsZSZBdWRpZW5jZT1odHRwJTNhJTJmJTJmbG9jYWxob3N0JTNhNzEwMCUyZlNlcnZpY2UlMmZEZWZhdWx0LmFzcHgmRXhwaXJlc09uPTEzMjY5OTk4MjEmSXNzdWVyPWh0dHBzJTNhJTJmJTJmZmhiYXlhenVyZW5zLmFjY2Vzc2NvbnRyb2wud2luZG93cy5uZXQlMmYmSE1BQ1NIQTI1Nj1SUnN3OUJTSlc2ZFJ0MjJyNkNkcjZWZHpyJTJicTF6MHlhV0FMNVdlJTJiJTJmV3owJTNk$c$c>

我去codeD这个字符串,并得到了我的ACS令牌。这ACS令牌是现在有效,可用于我的REST风格的WCF服务。

在服务器端code并没有改变。这是我已经得到了在客户端:

  //解析从JSON字符串令牌,
VAR令牌= JsonNotifyRequestSecurityTokenResponse.FromJson(txtReceivedToken.Text);
//获取安全令牌和去code将其
字符串的xmlString = HttpUtility.UrlDe code(token.SecurityTokenString);
//获取的base64字符串的
字符串string64 =;
使用(XmlReader中的XMLReader = XmlReader.Create(新StringReader(的xmlString))){
  而(xmlReader.Read()){
    如果(xmlReader.NodeType == XmlNodeType.Text){//找到第一个文本元素,它应该是为Base64字符串
      string64 = xmlReader.Value;
      打破;
    }
  }
}
//德code将其
字符串acsToken = base64De code(string64);//设置页眉
字符串headerValue =的String.Format(WRAP的access_token = \\{0} \\,acsToken);
client.Headers.Add(授权,headerValue);
流流= client.OpenRead(@http://127.0.0.1:81/Service1.svc/users);StreamReader的读者=新的StreamReader(流);
串响应= reader.ReadToEnd();

base64De code 方法从http://www.vbforums.com/showthread.php?t=287324.
JsonNotifyRequestSecurityTokenResponse.FromJson 部分,我从 http://www.leastprivilege.com/了一>,但我认为这可能与任何可用的JSON解析器解析。

我不知道这是否是***的解决办法,但它为我工作。

I'm currently working on a WPF client, which obtains a SWT token from Windows Azure AppFabric ACS. With this token I want to consume a RESTful WCF Service. I used this tutorial to obtain the SWT token and it works perfect. With the help of this MSDN tutorial I created the RESTful WCF service.

The problem is that the token may have the wrong format, because the token validator can't validate it (Error in the IsHMACValid method of the token validator, swtWithSignatur.Length == 1).

Example of a token with which I contact the server:

{"appliesTo":"http://localhost:7100/Service/Default.aspx","context":null,"created":1326996221,"expires":1326999821,"securityToken":"<?xml version="1.0" encoding="utf-16"?><wsse:BinarySecurityToken wsu:Id="uuid:74ba5667-04ea-4074-9544-aaafb570c648" ValueType="http://schemas.xmlsoap.org/ws/2009/11/swt-token-profile-1.0" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">aHR0cCUzYSUyZiUyZnNjaGVtYXMueG1sc29hcC5vcmclMmZ3cyUyZjIwMDUlMmYwNSUyZmlkZW50aXR5JTJmY2xhaW1zJTJmZW1haWxhZGRyZXNzPXBhdHJpY2suZWNrZXIlNDBnbWFpbC5jb20maHR0cCUzYSUyZiUyZnNjaGVtYXMueG1sc29hcC5vcmclMmZ3cyUyZjIwMDUlMmYwNSUyZmlkZW50aXR5JTJmY2xhaW1zJTJmbmFtZT1QYXRyaWNrK0Vja2VyJmh0dHAlM2ElMmYlMmZzY2hlbWFzLnhtbHNvYXAub3JnJTJmd3MlMmYyMDA1JTJmMDUlMmZpZGVudGl0eSUyZmNsYWltcyUyZm5hbWVpZGVudGlmaWVyPWh0dHBzJTNhJTJmJTJmd3d3Lmdvb2dsZS5jb20lMmZhY2NvdW50cyUyZm84JTJmaWQlM2ZpZCUzZEFJdE9hd2xzM1doNlgwRFJ6d1BsdzU2a1R0WURmLVNNaDZxZFJtQSZodHRwJTNhJTJmJTJmc2NoZW1hcy5taWNyb3NvZnQuY29tJTJmYWNjZXNzY29udHJvbHNlcnZpY2UlMmYyMDEwJTJmMDclMmZjbGFpbXMlMmZpZGVudGl0eXByb3ZpZGVyPUdvb2dsZSZBdWRpZW5jZT1odHRwJTNhJTJmJTJmbG9jYWxob3N0JTNhNzEwMCUyZlNlcnZpY2UlMmZEZWZhdWx0LmFzcHgmRXhwaXJlc09uPTEzMjY5OTk4MjEmSXNzdWVyPWh0dHBzJTNhJTJmJTJmZmhiYXlhenVyZW5zLmFjY2Vzc2NvbnRyb2wud2luZG93cy5uZXQlMmYmSE1BQ1NIQTI1Nj1SUnN3OUJTSlc2ZFJ0MjJyNkNkcjZWZHpyJTJicTF6MHlhV0FMNVdlJTJiJTJmV3owJTNk</wsse:BinarySecurityToken>","tokenType":"http://schemas.xmlsoap.org/ws/2009/11/swt-token-profile-1.0"}

In the Windows Azure Management Portal I've selected SWT as token format for my Relying Party Application. According to the first tutorial the format for the SWT token looks good, but the token validator won't accept it.

PS: If someone is trying the second tutorial (How To: Authenticate to a REST WCF Service Deployed to Windows Azure Using ACS): I think there is an error in point 11 in step 3, where you have to modify the web.config file (the system/webService section doesn't exist). The configuration should look something like this:

<?xml version="1.0"?>
<configuration>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="SWTModule" type="SecurityModule.SWTModule, SecurityModule" />
    </modules>
  </system.webServer>
</configuration>

The token, which I sent to the server, had the wrong format. The above token is in a json format and contains a 'securityToken', which is encoded xml. With HttpUtility.UrlDecode and XMLReader it is possible to retrieve the base64 string. The base64 string of the above token is:

aHR0cCUzYSUyZiUyZnNjaGVtYXMueG1sc29hcC5vcmclMmZ3cyUyZjIwMDUlMmYwNSUyZmlkZW50aXR5JTJmY2xhaW1zJTJmZW1haWxhZGRyZXNzPXBhdHJpY2suZWNrZXIlNDBnbWFpbC5jb20maHR0cCUzYSUyZiUyZnNjaGVtYXMueG1sc29hcC5vcmclMmZ3cyUyZjIwMDUlMmYwNSUyZmlkZW50aXR5JTJmY2xhaW1zJTJmbmFtZT1QYXRyaWNrK0Vja2VyJmh0dHAlM2ElMmYlMmZzY2hlbWFzLnhtbHNvYXAub3JnJTJmd3MlMmYyMDA1JTJmMDUlMmZpZGVudGl0eSUyZmNsYWltcyUyZm5hbWVpZGVudGlmaWVyPWh0dHBzJTNhJTJmJTJmd3d3Lmdvb2dsZS5jb20lMmZhY2NvdW50cyUyZm84JTJmaWQlM2ZpZCUzZEFJdE9hd2xzM1doNlgwRFJ6d1BsdzU2a1R0WURmLVNNaDZxZFJtQSZodHRwJTNhJTJmJTJmc2NoZW1hcy5taWNyb3NvZnQuY29tJTJmYWNjZXNzY29udHJvbHNlcnZpY2UlMmYyMDEwJTJmMDclMmZjbGFpbXMlMmZpZGVudGl0eXByb3ZpZGVyPUdvb2dsZSZBdWRpZW5jZT1odHRwJTNhJTJmJTJmbG9jYWxob3N0JTNhNzEwMCUyZlNlcnZpY2UlMmZEZWZhdWx0LmFzcHgmRXhwaXJlc09uPTEzMjY5OTk4MjEmSXNzdWVyPWh0dHBzJTNhJTJmJTJmZmhiYXlhenVyZW5zLmFjY2Vzc2NvbnRyb2wud2luZG93cy5uZXQlMmYmSE1BQ1NIQTI1Nj1SUnN3OUJTSlc2ZFJ0MjJyNkNkcjZWZHpyJTJicTF6MHlhV0FMNVdlJTJiJTJmV3owJTNk

I decoded this string and got my ACS token. This ACS token is now valid and my RESTful WCF service can be used.

Code on the server side didn't changed. This is what I've got on the client side:

// parse the token from the json string, 
var token = JsonNotifyRequestSecurityTokenResponse.FromJson(txtReceivedToken.Text);
// get the security token and decode it
string xmlString = HttpUtility.UrlDecode(token.SecurityTokenString);
// get the base64 string an
string string64 = "";
using (XmlReader xmlReader = XmlReader.Create(new StringReader(xmlString))) {
  while (xmlReader.Read()) {
    if (xmlReader.NodeType == XmlNodeType.Text) { // find the first text element, which should be the base64 string
      string64 = xmlReader.Value;
      break;
    }
  }
}
// decode it
string acsToken = base64Decode(string64);

// set the header
string headerValue = string.Format("WRAP access_token=\"{0}\"", acsToken);
client.Headers.Add("Authorization", headerValue);
Stream stream = client.OpenRead(@"http://127.0.0.1:81/Service1.svc/users");

StreamReader reader = new StreamReader(stream);
String response = reader.ReadToEnd();

The base64Decode method i 'stole' from http://www.vbforums.com/showthread.php?t=287324. The JsonNotifyRequestSecurityTokenResponse.FromJson part i got from http://www.leastprivilege.com/ , but i think it could be parsed with any available JSON parser.

I don't know if it is the best solution, but it works for me.