'How to scure my APIs on c#.net the best practice
I have built APIs on c#.Net
these APIs works fine, but they are not secure, which means anyone worldwide can use it
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Data.SqlClient;
using System.Data;
namespace CDAPIs.Controllers
{
public class CallSPController : ApiController
{
[Route("api/CallSP")]
public string Get(string SP = null, string Type = null, string Ps = null, string P0 = null, string P1 = null, string P2 = null, string P3 = null)
{
string sDBConn = Functions.GetConn();
string[] Parms = Ps.Split(',');
SqlConnection conn = new SqlConnection(sDBConn);
SqlCommand cmd = new SqlCommand(SP, conn);
cmd.CommandTimeout = 0;
cmd.CommandType = CommandType.StoredProcedure;
string P = "";
for (int i = 0; i < Parms.Length; i++)
{
if (i == 0) { P = P0; }
if (i == 1) { P = P1; }
if (i == 2) { P = P2; }
if (i == 3) { P = P3; }
cmd.Parameters.Add(new SqlParameter("@" + Parms[i].Trim(), P));
}
try
{
conn.Open();
if (Type.ToUpper().Trim() == "STRING")
{
string st = cmd.ExecuteScalar().ToString();
conn.Close();
conn.Dispose();
return st;
}
else
{
SqlDataReader rdr = cmd.ExecuteReader();
var dt = new DataTable();
dt.Load(rdr);
List<DataRow> result = dt.AsEnumerable().ToList();
rdr.Close();
conn.Close();
conn.Dispose();
string json = Functions.DataTableToJSON(dt);
//return Json(result, JsonRequestBehavior.AllowGet);
return json;
}
}
catch (Exception ex)
{
return ex.Message;
}
}
}
}
I want to protect these APIs and I would like to how to do that properly
I thought of adding UserID and Password to each API so the use send them as parameters
so it will be like this
[Route("api/CallSP")]
public string Get(string UserID, string Password, string SP = null, string Type = null, string Ps = null, string P0 = null, string P1 = null, string P2 = null, string P3 = null)
{
Is there a better solution?
Solution 1:[1]
No, you can't send secure data like passwords in the query as it could be easily stolen. In that case you should create an endpoint to authenticate the user and return to user secure string. This secure string is called JWT token. After that you put this token inside each request in the Authorization header. If API configured properly, and you used [Authorize] attribute, then you will automatically pass an authorization and step into your method. You can find the easiest code example (but post is in different language) here.
Solution 2:[2]
Your user should authenticate once and then reuse the connection. You should have a login action that would take a username and a password, generate a session id or something of the like and send that back to the client. The client from there on should use the session ID to authenticate and your server should be aware of session IDs.
Because, if for some reason a session ID is stolen, then the user might be temporarily impersonated by a hacker, but, if the user's credentials are stolen, then the user might be locked out from his/her account for good.
So:
- a session ID should be temporary, that is, after a week (or the period of your preference) expires, your app should no longer trust the old session id and require authentication again
- all the requests need to be encrypted
- at password/username change your app should not be satisfied by the session ID/token alone, but should ask for proper authentication as well
- it would be good if your app would have a communication channel with the user, like an email address defined at registration time or the like
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Serhii |
| Solution 2 | Lajos Arpad |
