Я создал сервер авторизации OAuth2, используя DotNetOpenAuth, который работает нормально - я использую поток пароля владельца ресурса и успешно меняю учетные данные пользователя для токена доступа.
Теперь я хочу использовать этот токен доступа для извлечения данных из защищенных конечных точек в API ServiceStack, и я не могу решить, как это сделать. Я изучил поставщиков Facebook, Google и т.д., Включенных в ServiceStack, но не понял, следует ли мне следовать одному шаблону или нет.
То, что я пытаюсь достичь (я думаю!),
- OAuth клиент (мое приложение) запрашивает владельца ресурса ('Catherine Smith') для учетных данных
- Клиент отправляет запрос серверу авторизации, получает токен доступа
- Клиент запрашивает безопасный ресурс на сервере (
GET /users/csmith/photos
)- токен доступа включен в HTTP-заголовок, например.
Authorization: Bearer 1234abcd...
- токен доступа включен в HTTP-заголовок, например.
- Сервер ресурсов расшифровывает токен доступа , чтобы проверить личность владельца ресурса
- сервер ресурсов проверяет, что владелец ресурса имеет доступ к запрошенному ресурсу
- Сервер ресурсов возвращает ресурс для клиента
Шаги 1 и 2 работают, но я не могу понять, как интегрировать код сервера ресурса DotNetOpenAuth с картой авторизации ServiceStack.
Есть ли какой-нибудь пример того, как я мог бы это достичь? Я нашел аналогичный пост StackOverflow в Как создать защищенный api с использованием ServiceStack в качестве сервера ресурсов с OAuth2.0?, но это не полное решение и не похоже, используют модель поставщика авторизации ServiceStack.
РЕДАКТИРОВАТЬ: Немного подробней. Здесь есть два разных веб-приложения. Один из них - сервер аутентификации/авторизации - он не содержит никаких данных клиента (т.е. Никакого API данных), но предоставляет метод /oauth/token, который будет принимать имя пользователя/пароль и возвращать токен доступа OAuth2 и обновлять токен, а также обеспечивает возможность обновления токена. Это построено на ASP.NET MVC, потому что оно почти идентично образцу AuthorizationServer, включенному в DotNetOpenAuth. Это может быть заменено позже, но на данный момент это ASP.NET MVC.
Для фактического API данных я использую ServiceStack, потому что я нахожу его намного лучше, чем WebAPI или MVC для отображения служб данных ReSTful.
Итак, в следующем примере:
Клиент - настольное приложение, работающее на локальном компьютере пользователя, Auth server - это ASP.NET MVC + DotNetOpenAuth и Сервер ресурсов - ServiceStack
Определенный фрагмент кода DotNetOpenAuth, который требуется:
// scopes is the specific OAuth2 scope associated with the current API call.
var scopes = new string[] { "some_scope", "some_other_scope" }
var analyzer = new StandardAccessTokenAnalyzer(authServerPublicKey, resourceServerPrivateKey);
var resourceServer = new DotNetOpenAuth.OAuth2.ResourceServer(analyzer);
var wrappedRequest = System.Web.HttpRequestWrapper(HttpContext.Current.Request);
var principal = resourceServer.GetPrincipal(wrappedRequest, scopes);
if (principal != null) {
// We've verified that the OAuth2 access token grants this principal
// access to the requested scope.
}
Итак, если я нахожусь на правильном пути, мне нужно выполнить этот код где-то в конвейере запроса ServiceStack, чтобы убедиться, что заголовок авторизации в запросе API представляет действительного принципала, который предоставил доступ к запрошенная область.
Я начинаю думать, что наиболее логичным местом для реализации этого является пользовательский атрибут, который я использую для украшения моих сервисов ServiceStack:
using ServiceStack.ServiceInterface;
using SpotAuth.Common.ServiceModel;
namespace SpotAuth.ResourceServer.Services {
[RequireScope("hello")]
public class HelloService : Service {
public object Any(Hello request) {
return new HelloResponse { Result = "Hello, " + request.Name };
}
}
}
Этот подход также позволит указать область (области), необходимые для каждого метода обслуживания. Тем не менее, похоже, что это скорее противоречит принципу "подключаемого" для OAuth2, так и к перехватчикам расширяемости, встроенным в модель ServiceStack AuthProvider.
Другими словами - я волнуюсь, я стуча в гвоздь с ботинком, потому что я не могу найти молоток...