首页 文章

ASP.NET Web API身份验证

提问于
浏览
121

我期待在使用ASP.NET Web API时从客户端应用程序验证用户 . 我观看了网站上的所有视频,还阅读了this forum post .

正确放置 [Authorize] 属性将返回 401 Unauthorized 状态 . 但是,我需要知道如何允许用户登录API .

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

3 回答

  • 12

    允许用户登录API

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

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

    • 通过发送用户名和密码向 LogOn 动作发送HTTP请求 . 反过来,此操作将调用 FormsAuthentication.SetAuthCookie 方法(如果凭据有效),这反过来将在响应中设置表单身份验证cookie .

    • 通过发送在第一个请求中检索到的表单身份验证cookie,向 [Authorize] 受保护的操作发送HTTP请求 .

    我们来举个例子吧 . 假设您的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"
    
  • 137

    我以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设备将localhost视为自己的主机 . ii . 如果在IIS中部署Web API,则必须打开表单身份验证 .

  • 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) 
    }
    

相关问题