Проверка подлинности веб-API ASP.NET

122

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

[Authorize]Правильная установка атрибута возвращает 401 Unauthorizedстатус. Однако мне нужно знать, как разрешить пользователю входить в API.

Я хочу предоставить учетные данные пользователя из приложения Android в API, чтобы пользователь вошел в систему, а затем предварительно аутентифицировал все последующие вызовы API.

Муджтаба Хасан
источник
Привет Муджтаба. Удалось ли вам это реализовать?
Вивек Чандрапракаш,
Сначала используйте CORS, чтобы предотвратить нежелательное попадание из чужого домена. Затем отправьте действительный файл cookie проверки подлинности с помощью форм вместе с запросом и, наконец, авторизуйте запрос по токену. Эта комбинация всегда делает ваш веб-API безопасным и оптимизированным.
Majedur Rahaman

Ответы:

137

разрешить пользователю войти в API

Вам необходимо отправить действительный файл cookie проверки подлинности с помощью форм вместе с запросом. Этот файл cookie обычно отправляется сервером при аутентификации ( LogOnдействии) путем вызова [FormsAuthentication.SetAuthCookieметода (см. MSDN ).

Итак, клиенту необходимо выполнить 2 шага:

  1. Отправьте HTTP-запрос к LogOnдействию, отправив имя пользователя и пароль. В свою очередь, это действие вызовет FormsAuthentication.SetAuthCookieметод (в случае, если учетные данные действительны), который, в свою очередь, установит файл cookie проверки подлинности форм в ответе.
  2. Отправьте HTTP-запрос к [Authorize]защищенному действию, отправив файл cookie проверки подлинности форм, полученный в первом запросе.

Возьмем пример. Предположим, у вас есть 2 контроллера API, определенных в вашем веб-приложении:

Первый отвечает за обработку аутентификации:

public class AccountController : ApiController
{
    public bool Post(LogOnModel model)
    {
        if (model.Username == "john" && model.Password == "secret")
        {
            FormsAuthentication.SetAuthCookie(model.Username, false);
            return true;
        }

        return false;
    }
}

а второй содержит защищенные действия, которые могут видеть только авторизованные пользователи:

[Authorize]
public class UsersController : ApiController
{
    public string Get()
    {
        return "This is a top secret material that only authorized users can see";
    }
}

Теперь мы могли написать клиентское приложение, использующее этот API. Вот тривиальный пример консольного приложения (убедитесь, что вы установили пакеты NuGet Microsoft.AspNet.WebApi.Clientи Microsoft.Net.Http):

using System;
using System.Net.Http;
using System.Threading;

class Program
{
    static void Main()
    {
        using (var httpClient = new HttpClient())
        {
            var response = httpClient.PostAsJsonAsync(
                "http://localhost:26845/api/account", 
                new { username = "john", password = "secret" }, 
                CancellationToken.None
            ).Result;
            response.EnsureSuccessStatusCode();

            bool success = response.Content.ReadAsAsync<bool>().Result;
            if (success)
            {
                var secret = httpClient.GetStringAsync("http://localhost:26845/api/users");
                Console.WriteLine(secret.Result);
            }
            else
            {
                Console.WriteLine("Sorry you provided wrong credentials");
            }
        }
    }
}

А вот как два HTTP-запроса выглядят в сети:

Запрос аутентификации:

POST /api/account HTTP/1.1
Content-Type: application/json; charset=utf-8
Host: localhost:26845
Content-Length: 39
Connection: Keep-Alive

{"username":"john","password":"secret"}

Ответ аутентификации:

HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Wed, 13 Jun 2012 13:24:41 GMT
X-AspNet-Version: 4.0.30319
Set-Cookie: .ASPXAUTH=REMOVED FOR BREVITY; path=/; HttpOnly
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Content-Type: application/json; charset=utf-8
Content-Length: 4
Connection: Close

true

Запрос на защищенные данные:

GET /api/users HTTP/1.1
Host: localhost:26845
Cookie: .ASPXAUTH=REMOVED FOR BREVITY

Ответ на защищенные данные:

HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Wed, 13 Jun 2012 13:24:41 GMT
X-AspNet-Version: 4.0.30319
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Content-Type: application/json; charset=utf-8
Content-Length: 66
Connection: Close

"This is a top secret material that only authorized users can see"
Дарин Димитров
источник
Будет ли он поддерживать сеанс для приложения Android?
Mujtaba Hassan
Понятно, но не могли бы вы опубликовать образец кода для второго пункта. Спасибо за Ваш ответ.
Mujtaba Hassan
2
Написание HTTP-клиента для Android - тема для другого вопроса. Это не связано с ASP.NET MVC и ASP.NET MVC Web API, о чем был ваш вопрос. Я бы порекомендовал вам начать новый поток с явной пометкой Java и Android, в котором вы спрашиваете, как написать HTTP-клиент, который отправляет запросы с использованием файлов cookie.
Darin Dimitrov
На самом деле в литературе по MVC4 WebApi написано, что WebAPI предназначен для сторонних клиентов, особенно для мобильных клиентов (и, конечно, это так). Допустим, у нас есть клиент настольного приложения, не могли бы вы опубликовать простой фрагмент кода. Спасибо
Муджтаба Хассан
2
Также см. Этот вопрос (и ответ) об использовании базовой аутентификации HTTP: stackoverflow.com/questions/10987455/…
Джим Харт,
12

Я беру андроид в качестве примера.

public abstract class HttpHelper {

private final static String TAG = "HttpHelper";
private final static String API_URL = "http://your.url/api/";

private static CookieStore sCookieStore;

public static String invokePost(String action, List<NameValuePair> params) {
    try {
        String url = API_URL + action + "/";
        Log.d(TAG, "url is" + url);
        HttpPost httpPost = new HttpPost(url);
        if (params != null && params.size() > 0) {
            HttpEntity entity = new UrlEncodedFormEntity(params, "UTF-8");
            httpPost.setEntity(entity);
        }
        return invoke(httpPost);
    } catch (Exception e) {
        Log.e(TAG, e.toString());
    }

    return null;
}

public static String invokePost(String action) {
    return invokePost(action, null);
}

public static String invokeGet(String action, List<NameValuePair> params) {
    try {
        StringBuilder sb = new StringBuilder(API_URL);
        sb.append(action);
        if (params != null) {
            for (NameValuePair param : params) {
                sb.append("?");
                sb.append(param.getName());
                sb.append("=");
                sb.append(param.getValue());
            }
        }
        Log.d(TAG, "url is" + sb.toString());
        HttpGet httpGet = new HttpGet(sb.toString());
        return invoke(httpGet);
    } catch (Exception e) {
        Log.e(TAG, e.toString());
    }

    return null;
}

public static String invokeGet(String action) {
    return invokeGet(action, null);
}

private static String invoke(HttpUriRequest request)
        throws ClientProtocolException, IOException {
    String result = null;
    DefaultHttpClient httpClient = new DefaultHttpClient();

    // restore cookie
    if (sCookieStore != null) {
        httpClient.setCookieStore(sCookieStore);
    }

    HttpResponse response = httpClient.execute(request);

    StringBuilder builder = new StringBuilder();
    BufferedReader reader = new BufferedReader(new InputStreamReader(
            response.getEntity().getContent()));
    for (String s = reader.readLine(); s != null; s = reader.readLine()) {
        builder.append(s);
    }
    result = builder.toString();
    Log.d(TAG, "result is ( " + result + " )");

    // store cookie
    sCookieStore = ((AbstractHttpClient) httpClient).getCookieStore();
    return result;
}

Внимание, i.localhost использовать нельзя. Устройство Android выглядит как локальный хост как сам хост. ii. при развертывании веб-API в IIS необходимо открыть проверку подлинности формы.

user2293998
источник
0

Используйте этот код и получите доступ к базе данных

[HttpPost]
[Route("login")]
public IHttpActionResult Login(LoginRequest request)
{
       CheckModelState();
       ApiResponse<LoginApiResponse> response = new ApiResponse<LoginApiResponse>();
       LoginResponse user;
       var count = 0;
       RoleName roleName = new RoleName();
       using (var authManager = InspectorBusinessFacade.GetAuthManagerInstance())
       {
           user = authManager.Authenticate(request); 
       } reponse(ok) 
}
Санила Салим
источник