1
I created a Web Api here in my work to be consumed by my project Xamarin Forms. It’s working 100% and no problems... Then I was informed that actually here we use 2 web api s for security. That is, I will have to create a Web Api ("frontend") with external access, which would act as a doorman, passing the calls to another Web Api ("backend") and this, only this, has access to the BD and only accepts internally. Since I’m a beginner and I took a beating to be able to build this Web Api and it works, I would like a help in how to do this. I would have to call Webapi 1 and it will carry the values typed by the user up to Web Api 2... this in turn will have the database calls and all the controllers...after the query is that I did not understand what to do, because the data is spit in Json and much of it I was able to make work in Rra by searching.
My code in Xamarin:
ApiCall apiCall = new ApiCall();
apiCall.GetResponse<List<Envolvido>>("nomes", "Envolvidos", nomepesquisa, nomemae, nomepai, dtnasc, nrg, ncpf).ContinueWith(t =>
{
//Aqui verificamos se houve problema ne requisição
if (t.IsFaulted)
{
Debug.WriteLine(t.Exception.Message);
Device.BeginInvokeOnMainThread(() =>
{
DisplayAlert("Falha", "Ocorreu um erro na Requisição :(", "Ok");
//IsBusy = false;
});
}
//Aqui verificamos se a requisição foi cancelada por algum Motivo
else if (t.IsCanceled)
{
Debug.WriteLine("Requisição cancelada");
Device.BeginInvokeOnMainThread(() =>
{
DisplayAlert("Cancela", "Requisição Cancelada :O", "Ok");
//IsBusy = false;
});
}
//Caso a requisição ocorra sem problemas, cairemos aqui
else
{
//Se Chegarmos aqui, está tudo ok, agora itemos tratar nossa Lista
//Aqui Usaremos a Thread Principal, ou seja, a que possui as references da UI
Device.BeginInvokeOnMainThread(() =>
{
//IsBusy = false;
ListaDados.ItemsSource = t.Result;
var count = ListaDados.ItemsSource.OfType<object>().Count();
if (count == 0)
{
DisplayAlert("Cancela", "Não há dados retornados.", "Ok");
}
else
Navigation.PushAsync(new ResultadosBuscados(ListaDados.ItemsSource));
});
}
part of my Apicall that calls the Web Api:
public class ApiCall
{
static readonly string ApiUrl = "http://Localhost:1762/api/{0}/{1}?nomePesquisa={2}&nomeMae={3}&nomePai={4}&dtNasc={5}&nrg={6}&ncpf={7}";
public async Task<T> GetResponse<T>(string controller, string method, string nomepesquisa,
string nomemae, string nomepai, string dtnasc, string nrg, string ncpf) where T : class
{
var client = new System.Net.Http.HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var urllink = string.Format(ApiUrl, controller, method, nomepesquisa, nomemae, nomepai, dtnasc, nrg, ncpf);
var response = await client.GetAsync(urllink);
//Lê a string retornada
var JsonResult = response.Content.ReadAsStringAsync().Result;
if (typeof(T) == typeof(string))
return null;
//Converte o resultado Json para uma Classe utilizando as Libs do Newtonsoft.Json
var rootobject = JsonConvert.DeserializeObject<T>(JsonResult);
return rootobject;
}
}
My controller code in the Web Api:
[RoutePrefix("api/nomes")]
public class NomesController : ApiController
{
public string GetConnectionString()
{
string MeuConnString = "Data Source=(DESCRIPTION ="
+ "(ADDRESS=(PROTOCOL = TCP)(HOST = xxx)(PORT = xxx))"
+ "(CONNECT_DATA = (SERVER = DEDICATED)(service_name = xxx)));"
+ "User Id = xxx; Password=xxx";
return MeuConnString;
}
[HttpGet]
[Route("Envolvidos")]
public IEnumerable<Envolvido> GetEnvolv(string nomePesquisa, string nomeMae, string nomePai, string dtnasc
, string nRG, string nCPF)
{
DataSet lretorno = new DataSet();
string connectionString = GetConnectionString();
using (OracleConnection connection = new OracleConnection())
{
connection.ConnectionString = connectionString;
OracleDataReader reader = null;
OracleCommand cmd = new OracleCommand();
cmd.Connection = connection;
cmd = new OracleCommand("MOBILE.XAPIMAND.BUSCAPOSCANDIDOSPF", connection);
cmd.CommandType = CommandType.StoredProcedure;
//variáveis entrada
cmd.Parameters.Add(new OracleParameter("ivnome",nomePesquisa));
cmd.Parameters.Add(new OracleParameter("ivmae", nomeMae));
cmd.Parameters.Add(new OracleParameter("ivpai", nomePai));
cmd.Parameters.Add(new OracleParameter("ivdatanasc", dtnasc));
cmd.Parameters.Add(new OracleParameter("ivrg", nRG));
cmd.Parameters.Add(new OracleParameter("icpf", nCPF));
//variáveis de saida
cmd.Parameters.Add(new OracleParameter("oretorno", OracleDbType.RefCursor)).Direction = ParameterDirection.Output;
cmd.Parameters.Add(new OracleParameter("qretorno", OracleDbType.RefCursor)).Direction = ParameterDirection.Output;
connection.Open();
cmd.ExecuteNonQuery();
reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
//CRIO A LISTA
lretorno.Load(reader, LoadOption.OverwriteChanges, "BUSCAPOSSIVEISCANDIDATOSPF");
connection.Close();
connection.Dispose();
//CARREGO O DATASET E TRANSFORMO PARA IENUMERABLE E RETORNO SEUS VALORES PRO JSON
return lretorno.Tables[0].AsEnumerable().Select(row => new Envolvido
{
SUSPID = Convert.ToInt32(row["SUSPID"]),
IVNOME = Convert.ToString(row["SUSPNOME"]),
IVMAE = Convert.ToString(row["SUSPMAE"]),
IVPAI = Convert.ToString(row["SUSPPAI"]),
IVDATANASC = Convert.ToString(row["SUSPDATANASC"]).Replace(" 00:00:00", ""),
IVRG = Convert.ToString(row["RG"]),
ICPF = Convert.ToString(row["CPF"]),
MANDADO = Convert.ToInt16(row["TEMMANDADO"]),
OCORRENCIA = Convert.ToInt16(row["TEMOCORRENCIA"]),
});
}
}
}
What’s the extra security in having two Apis?
– Jéf Bueno
@jbueno the 1st Web Api ("front") is connected externally... this connects to the 2nd ("back"), which is connected only internally...ie, if a person tries to access the BD from outside the network, theoretically, can not access.
– Mcfer
@jbueno and Marcelo, I have serious doubts about this security model, even because the simple fact of making a request to the database should not expose the database. now let’s say Webapi 1 has a serious security problem that allows a hack to take control of the server, in this case it will be within your network and will have access to Webapi 2. And finally, there are situations that is valid to have two services, but the second service would normally WCF and possibly have a nettcp Binding and a more restrictive authentication system.
– Tobias Mesquita
@Tobymosque I agree in parts.... here in my work this is the structure for everything! This Mobile is the first and test, but I was asked to follow the architecture when I did. But as I’m a beginner, it’s difficult. In my Apicall I have the URL call using System.Net.Http.Httpclient() and then enter the controller... that is, now in this "intercom" Web Api I will have to have another URL call for 2nd Web Api and in addition, pass the parameters, returning the dataset of the 2nd Web Api... Confusion in my head. I wanted someone to give an example as it would be, using this my Code.
– Mcfer
@Marcelocfernandes in this case you should not have two Webapi, you should have a WCF service using Netpeertcpbinding with point-to-point security, just remember to configure the messages using MTOM encoding.
– Tobias Mesquita
@Marcelocfernandes What is your doubt, really?
– Randrade
@Randrade My question is about what to use. I created the Web Api to consume the Oracle BD data and it’s working. Then I was informed that here I could not actually use this architecture. That they use one server for external access and another that only receives internal access and these communicate. My question is how to do this communication...I thought of 2 Web Api s, but I’m beginner and I don’t have much knowledge. A lot of what you talked about here, I don’t have a clue what rsrs are.
– Mcfer