ASP.NET Web API身份验证

我正在寻找使用ASP.NET Web API在客户端应用程序中对用户进行身份验证。 我观看了网站上的所有视频,并阅读了此论坛帖子。

正确放置[Authorize]属性会返回401 Unauthorized状态。 但是,我需要知道如何让用户登录到API。

我想从Android应用程序向API提供用户凭据,让用户登录,然后让所有后续API调用预先进行身份验证。


允许用户登录到API

您需要发送一个有效的表单身份验证cookie和请求。 此cookie通常由服务器通过调用[FormsAuthentication.SetAuthCookie方法(请参阅MSDN)进行身份验证( LogOn操作)时发送。

所以客户需要执行2个步骤:

  • 通过发送用户名和密码将HTTP请求发送到LogOn操作。 反过来,此操作将调用FormsAuthentication.SetAuthCookie方法(以防凭据有效),这又会在响应中设置表单身份验证Cookie。
  • 发送一个HTTP请求到一个[Authorize]受保护的动作,通过发送它在第一个请求中检索到的表单认证cookie。
  • 我们举个例子吧。 假设您的Web应用程序中定义了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的客户端应用程序 这是一个简单的控制台应用程序示例(请确保您已安装Microsoft.AspNet.WebApi.ClientMicrosoft.Net.Http NuGet包):

    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");
                }
            }
        }
    }
    

    以下是2条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为例。

    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。如果在IIS中部署Web API,则必须打开表单身份验证。


    使用此代码并访问数据库

    [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) 
    }
    
    链接地址: http://www.djcxy.com/p/20535.html

    上一篇: ASP.NET Web API Authentication

    下一篇: Custom method names in ASP.NET Web API