2012-12-09 2 views
9

В документах ServiceStack приведены примеры использования стороне сервера реализация аутентификации пользователя. Но как установить учетные данные пользователя на стороне клиента?Аутентификация пользователя при использовании веб-службы REST с ServiceStack

Я использую ServiceStack потреблять JSON REST услугу, как это:

var restClient = new JsonServiceClient (baseUri); 
var response = restClient.Get<MyResponse> ("/some/service"); 

Как я могу добавить любую форму аутентификации на запрос? Веб-сервис, который я хочу использовать, использует OAuth 1.0, но я также заинтересован в добавлении пользовательской аутентификации.

В моем коде я ранее выполнял обмен токенами OAuth, поэтому у меня уже есть действующий токен доступа, и теперь нужно подписывать каждый запрос REST с использованием этого токена доступа и его token_secret.

ответ

6

Отвечая себя, как я нашел хороший способ сделать это, используя LocalHttpWebRequestFilter крюк в JsonServiceClient:

Для обеспечения веб-службы с OAuth 1.0a, каждый запрос HTTP должен отправить специальный заголовок Authorization: , Внутри этого поля заголовка должен быть отправлен хэш (подпись), который использует некоторые характеристики запроса как входные данные, такие как имя хоста, URL-адрес запроса и others.

Теперь кажется, что LocalHttpWebRequestFilter вызывается службой ServiceStack непосредственно перед запросом http и предоставляет базовый объект HttpWebRequest, где можно добавить дополнительные заголовки и получить доступ к требуемым полям запроса.

Так что мое решение теперь в основном:

var client = new JsonServiceClient (baseUri); 

client.LocalHttpWebRequestFilter += (request) => { 
    // compute signature using request and a previously obtained 
    // access token 
    string authorization_header = CalculateSignature (request, access_token); 

    request.Headers.Add ("Authorization", authorization_header); 
}; 
var response = client.Get<MySecuredResponse> ("/my/service"); 

Обратите внимание, что я использую Devdefined.OAuth библиотеку, чтобы сделать все тяжелые вещи в CalculateSignature().Создание токена запроса, получение авторизации пользователя и обмен маркером запроса для токена доступа, как требуется OAuth, выполняется за пределами ServiceStack, прежде чем вызовет вышеуказанный вызов.

+0

Я пытаюсь сделать что-то подобное, у вас есть клиент asp.net, который использует сервис servicestack. пара вопросов для вас о вашей реализации. как вы получаете токен доступа? через стек обслуживания или другими способами? Кроме того, я не вижу этот метод CalculateSignature() в Devdefined.OAuth. он был заменен? Заранее спасибо за вашу помощь! – pjacko

+1

«CalculateSignature» - это всего лишь манекен, который я разместил, вам нужно будет сделать там OAuth. Для этого я использую DevDefined.OAuth. Обмен токена выполняется один раз, а не по каждому запросу. Я использовал ServiceStack + DevDefined.OAuth для обмена. Весь проект с открытым исходным кодом, поэтому вы можете взглянуть на него. Обмен токена выполняется здесь: https://github.com/Dynalon/Rainy/blob/master/Rainy/WebService/OAuth/OAuthService.cs и фильтр, который проверяет авторизацию по каждому запросу, выполняется здесь: https: // github.com/Dynalon/Rainy/blob/master/Rainy/WebService/OAuth/OAuthAccessFilter.cs – Dyna

+0

спасибо, проверим! – pjacko

8

Службы ServiceStack's AuthTests показывают различные способы аутентификации при использовании клиентов ServiceStack Service Clients. По умолчанию BasicAuth и DigestAuth встраивается клиентов, например:

var client = new JsonServiceClient(baseUri) { 
    UserName = UserName, 
    Password = Password, 
}; 

var request = new Secured { Name = "test" }; 
var response = client.Send<SecureResponse>(request);  

За кулисами ServiceStack будет пытаться отправить запрос нормально, но когда запрос будет отклонен и вызов сервером клиенты будут автоматически повторит тот же запрос но на этот раз с заголовками Basic/Digest Auth.

Чтобы пропустить дополнительный хмель, когда вы знаете, что доступ к безопасной службе, вы можете сказать, чтобы клиентам всегда посылают заголовок BasicAuth с:

client.AlwaysSendBasicAuthHeader = true; 

альтернативным способом, чтобы аутентифицировать это сделать явное позвонить в Auth службы (это требует включена CredentialsAuthProvider), например:

var authResponse = client.Send<AuthResponse>(new Auth { 
    provider = CredentialsAuthProvider.Name, 
    UserName = "user", 
    Password = "[email protected]", 
    RememberMe = true, //important tell client to retain permanent cookies 
}); 

var request = new Secured { Name = "test" }; 
var response = client.Send<SecureResponse>(request);  

После успешного вызова Auth сервиса клиент Зарегистрированным и если RememberMe, клиент сохранит Cookies сеанса, добавленные сервером, на последующие запросы, что позволяет проверять будущие запросы от этого клиента.

+0

Thx для вашего ответа! Я реализую устаревшую услугу, поэтому я не могу изменить схему auth. Но я нашел способ, посмотрю на мой ответ. Я должен не согласиться с вами :) OAuth можно использовать и для веб-сервисов. Tomboy/Ubuntu1 использует его для синхронизации заметок. После настройки сервера синхронизации в первый раз он запускает браузер, и пользовательское взаимодействие/авторизация завершаются. По завершении приложения Tomboy (используя собственный HTTP-прослушиватель) вызывается обратно и передает токен доступа. После получения маркер доступа может использоваться, как представлено в моем ответе, для всех последующих запросов в будущем без взаимодействия. – Dyna

+0

круто, удален из Q. thx за то, что дайте мне знать! – mythz

Смежные вопросы