Подтвердить что ты не робот

Аутентификация ASP.NET MVC для внешней веб-службы

Я пытаюсь написать приложение ASP.NET MVC, которое является интерфейсом для нашего CRM, который имеет веб-службу SOAP. Я хотел бы, чтобы пользователь входил в мое веб-приложение, используя свое имя пользователя и пароль CRM, а затем аутентифицировался против CRM, делал вызовы веб-сервисов на страницах и т.д.

Я начал изучать использование проверки подлинности с помощью форм и внедрение пользовательского поставщика членства. Я могу реализовать все методы, которые мне нужны, чтобы понравиться ValidateUser(), но проблема заключается в том, что после входа в веб-службу CRM вам предоставляется токен, который должен быть передан с каждым последующим вызовом веб-службы, и я не уверен, где я могу его хранить.

Итак, мои вопросы:

  • - это аутентификация форм, чтобы перейти сюда, или будет проще обращаться ко всей аутентификации и хранить токен в сеансе.
  • Если формальная аутентификация - это способ, где и как я должен хранить дополнительную информацию, подобную этой. Кажется, что нравится использовать Аутентификацию по формам, но затем накладывать нагрузку дополнительной информации (которая связана с аутентификацией) в файл cookie или сеанс вне этого будет немного беспорядком?

Любые советы будут оценены

4b9b3361

Ответ 1

Вы можете сохранить токен аутентификации в части userData куки файла проверки подлинности форм. Таким образом, он будет доступен по каждому запросу.

Итак, например, как только вы подтвердите учетные данные пользователя, вы можете запросить веб-службу для получения маркера и вручную создать и испустить файл cookie проверки подлинности форм.

[HttpPost]
public ActionResult LogOn(string username, string password)
{
    // TODO: verify username/password, obtain token, ...
    // and if everything is OK generate the authentication cookie like this:

    var authTicket = new FormsAuthenticationTicket(
        2,
        username,
        DateTime.Now,
        DateTime.Now.AddMinutes(FormsAuthentication.Timeout.TotalMinutes),
        false,
        "some token that will be used to access the web service and that you have fetched"
    );
    var authCookie = new HttpCookie(
        FormsAuthentication.FormsCookieName, 
        FormsAuthentication.Encrypt(authTicket)
    )
    {
        HttpOnly = true
    };
    Response.AppendCookie(authCookie);

    // ... redirect
}

Затем вы можете написать специальный атрибут authorize, который будет читать эту информацию и установить индивидуальный общий идентификатор:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var isAuthenticated = base.AuthorizeCore(httpContext);
        if (isAuthenticated) 
        {
            string cookieName = FormsAuthentication.FormsCookieName;
            if (!httpContext.User.Identity.IsAuthenticated ||
                httpContext.Request.Cookies == null || 
                httpContext.Request.Cookies[cookieName] == null)
            {
                return false;
            }

            var authCookie = httpContext.Request.Cookies[cookieName];
            var authTicket = FormsAuthentication.Decrypt(authCookie.Value);

            // This is where you can read the userData part of the authentication
            // cookie and fetch the token
            string webServiceToken = authTicket.UserData;

            IPrincipal userPrincipal = ... create some custom implementation
                                           and store the web service token as property

            // Inject the custom principal in the HttpContext
            httpContext.User = userPrincipal;
        }
        return isAuthenticated;
    }
}

Наконец, украсьте свои контроллеры/действия, требующие аутентификации с помощью этого атрибута:

[MyAuthorize]
public ActionResult Foo()
{
    // HttpContext.User will represent the custom principal you created
    // and it will contain the web service token that you could use to 
    // query the remote service
    ...
}