PrepareResponse (). AsActionResult () генерирует неподдерживаемое исключение DotNetOpenAuth CTP - PullRequest
5 голосов
/ 14 декабря 2011

В настоящее время я разрабатываю сервер авторизации OAuth2 с использованием CTP-версии DotNetOpenAuth.Мой сервер авторизации находится в asp.net MVC3 и основан на примере, предоставленном библиотекой.Все работает нормально, пока приложение не достигнет точки, где пользователь авторизует потребительский клиент.

Внутри моего контроллера OAuth есть действие, которое заботится о процессе авторизации и очень похоже на эквивалентное действие в примере:

[Authorize, HttpPost, ValidateAntiForgeryToken]
    public ActionResult AuthorizeResponse(bool isApproved)
    {
        var pendingRequest = this.authorizationServer.ReadAuthorizationRequest();

        if (pendingRequest == null)
        {
            throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request.");
        }

        IDirectedProtocolMessage response;
        if (isApproved)
        {
            var client = MvcApplication.DataContext.Clients.First(c => c.ClientIdentifier == pendingRequest.ClientIdentifier);
            client.ClientAuthorizations.Add(
                new ClientAuthorization
                {
                    Scope = OAuthUtilities.JoinScopes(pendingRequest.Scope),
                    User = MvcApplication.LoggedInUser,
                    CreatedOn = DateTime.UtcNow,
                });
            MvcApplication.DataContext.SaveChanges();
            response = this.authorizationServer.PrepareApproveAuthorizationRequest(pendingRequest, User.Identity.Name);
        }
        else
        {
            response = this.authorizationServer.PrepareRejectAuthorizationRequest(pendingRequest);
        }

        return this.authorizationServer.Channel.PrepareResponse(response).AsActionResult();
    }

Каждый раз, когда программа достигает этой строки:

this.authorizationServer.Channel.PrepareResponse(response).AsActionResult();

Система выдает исключение, которое я исследовал безуспешно.Исключением является следующее: в LINQ to Entities поддерживаются только конструкторы и инициализаторы без параметров.

Трассировка стека: http://pastebin.com/TibCax2t

Единственное, что я сделал по-другому, чемПримером является то, что я использовал первый подход кода структуры сущностей, и я думаю, что образец был сделан с использованием конструктора, который автоматически генерирует сущности.

Заранее спасибо.

Ответы [ 2 ]

5 голосов
/ 07 июля 2012

Если вы начали с примера, проблема, о которой говорит Эндрю, остается в DatabaseKeyNonceStore.cs.Исключение возбуждается одним из этих двух методов:

    public CryptoKey GetKey(string bucket, string handle) {
        // It is critical that this lookup be case-sensitive, which can only be configured at the database.
        var matches = from key in MvcApplication.DataContext.SymmetricCryptoKeys
                      where key.Bucket == bucket && key.Handle == handle
                      select new CryptoKey(key.Secret, key.ExpiresUtc.AsUtc());

        return matches.FirstOrDefault();
    }

    public IEnumerable<KeyValuePair<string, CryptoKey>> GetKeys(string bucket) {
        return from key in MvcApplication.DataContext.SymmetricCryptoKeys
               where key.Bucket == bucket
               orderby key.ExpiresUtc descending
               select new KeyValuePair<string, CryptoKey>(key.Handle, new CryptoKey(key.Secret, key.ExpiresUtc.AsUtc()));
    }

Я решил переместить инициализации за пределы запроса:

    public CryptoKey GetKey(string bucket, string handle) {
        // It is critical that this lookup be case-sensitive, which can only be configured at the database.
        var matches = from key in db.SymmetricCryptoKeys
                      where key.Bucket == bucket && key.Handle == handle
                      select key;

        var match = matches.FirstOrDefault();

        CryptoKey ck = new CryptoKey(match.Secret, match.ExpiresUtc.AsUtc());

        return ck;
    }

    public IEnumerable<KeyValuePair<string, CryptoKey>> GetKeys(string bucket) {
        var matches = from key in db.SymmetricCryptoKeys
               where key.Bucket == bucket
               orderby key.ExpiresUtc descending
               select key;

        List<KeyValuePair<string, CryptoKey>> en = new List<KeyValuePair<string, CryptoKey>>();

        foreach (var key in matches)
            en.Add(new KeyValuePair<string, CryptoKey>(key.Handle, new CryptoKey(key.Secret, key.ExpiresUtc.AsUtc())));

        return en.AsEnumerable<KeyValuePair<string,CryptoKey>>();
    }

Я не уверен, что это лучшийКстати, но это работает!

1 голос
/ 05 июля 2012

Похоже, ваша реализация ICryptoKeyStore может пытаться сохранить CryptoKey напрямую, но это не тот класс, который совместим с платформой Entity (из-за отсутствия открытого конструктора по умолчанию). Вместо этого определите свой собственный класс сущностей для хранения данных в CryptoKey, а ваш ICryptoKeyStore отвечает за переход между двумя типами данных для сохранения и извлечения.

...