Hallo,
ich habe folgendes Problem:
Ich möchte mich mit einem Rest Client beim WCF-Server authentifizieren, um anschließend den angebotene Service nutzen zu können. Für die Authentifizierung nutze ich BasisAuthenciation.
<webHttpBinding>
<binding name="BasicAuthentication" >
<!-- Basic Authenciation -->
<security mode="TransportCredentialOnly" >
<transport clientCredentialType="Basic" />
</security>
</binding>
</webHttpBinding>
<serviceBehaviors>
<behavior>
<!-- Custom Authenciation -->
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="GkServer.Security.CustomValidator, GkServer" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
An sich ist das auch kein Problem, ich kann wunderbar über den Browser die Services nutzen. Jedoch ist das mit javascript nicht so leicht möglich. Folgender Ansatz:
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
function drawTable(uri) {
$.ajax({
url: uri,
dataType: 'json',
type: 'GET',
async: false,
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'Basic ' + Base64.encode('test:test'));
},
error: function () { alert("error") },
success: function (data) {
// setup the new map and its variables
var map = new google.visualization.DataTable();
map.addRows(data.length); // length gives us the number of results in our returned data
var head = data[0];
for (p in head) {
if (typeof (head[p]) != 'object')
map.addColumn(typeof (head[p]), p);
}
// now we need to build the map data, loop over each result
$.each(data, function (i, v) {
var j = 0;
for (item in v) {
if (typeof (v[item]) != 'object') {
map.setValue(i, j, v[item]);
j++;
}
}
});
var table = new google.visualization.Table(document.getElementById('table'));
table.draw(map);
}
});
}
|
Jedoch sendet das xhr Object eine Option-Request anstatt einer GET-Request:
OPTIONS
http://gaia:8080/GkServer/articles?categoryId=2 HTTP/1.1
Host: gaia:8080
Connection: keep-alive
Access-Control-Request-Method: GET
Origin:
http://localhost:49551
Access-Control-Request-Headers: Origin, Authorization, Accept
Da der Link
http://gaia:8080/GkServer/articles?categoryId=2 aber mit einer Get-Method gemappt ist und die Request kein Authorization-Header-Eintrag hat, kann diese Request natürlich nicht korrekt verarbeitet werden. Dementsprechend diese Fehlermeldung auf der Client-Seite:
|
Quellcode
|
1
2
|
OPTIONS http://gaia:8080/GkServer/articles?categoryId=2 401 (Unauthorized)
XMLHttpRequest cannot load http://gaia:8080/GkServer/articles?categoryId=2. Origin http://localhost:49551 is not allowed by Access-Control-Allow-Origin.
|
Folgende (manuell erstelle) Request funktioniert hingegen ohne Probleme:
GET
http://gaia:8080/GkServer/articles?categoryId=1 HTTP/1.1
Authorization: Basic dGVzdDp0ZXN0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Hier erhalte ich als Ergebnis eine wunderbare XML-Seite mit den Artikeln.
Meine Frage ist, warum das xhr-Objekt überhaupt eine OPTION-Anfrage sendet und wie ich diese vorher beim WCF-Server abfangen und korrekt verarbeiten kann (Ich habe keine Global.asax oder *.svc Datei, da ich nicht vor habe die Services auf dem IIS zu hosten, sondern die Services selbst mit dem ServiceHost bereitstelle). Anzumerken ist, dass es nicht am CrossDomain-Problem liegt, das habe ich folgendermaßen gelöst:
|
C#-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Runtime.Serialization;
using GkServer.Model;
using System.ServiceModel.Web;
namespace GkServer.Service
{
public class GkContextService : GkServer.Service.IGkContextService
{
public GkContextService()
{
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Methods", "POST, GET");
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept");
} /* Restliche Methoden */
}
}
|
PS: Der Editor hat mich fast zur Weißglut gebracht, also seit bitte wegen der vllt. schlechten Formatierung etwas nachsichtig