What is the best way to secure api requests

Hello there.
Im a c# web developer, and I'm just starting to work with Xamarin.
The app I would like to build will need to communicate with a web based application that I already have.
I would like to have a login page that will authenticate the user credentials with my web app api.

my concern is that other app might monitor the requests that coming out the device and get the login information..
is it a possibility?

Answers

  • mjdevelopermjdeveloper Member ✭✭✭

    I used "ASP.NET Identity using OAuth" in my application.
    see this video

  • idanavidanav Member

    Cant view the video..

  • mjdevelopermjdeveloper Member ✭✭✭
    edited October 13

    Inside web API

    using Microsoft.Owin;
    using Microsoft.Owin.Security.OAuth;
    using Owin;
    using YourAPI.Providers;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Http;
    
    [assembly: OwinStartup(typeof(YourAPI.Startup))]
    namespace YourAPI
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                HttpConfiguration config = new HttpConfiguration();
                ConfigureOAuth(app);
                WebApiConfig.Register(config);
                app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
                app.UseWebApi(config);
            }
    
            public void ConfigureOAuth(IAppBuilder app)
            {
                OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
                {
                    AllowInsecureHttp = true,
                    TokenEndpointPath = new PathString("/token"),
                    AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
                    Provider = new SimpleAuthorizationServerProvider()
                };
    
                // Token Generation
                app.UseOAuthAuthorizationServer(OAuthServerOptions);
                app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
    
            }
        }
    }
    

    Inside web API --->Providers folder----> yourprovider class:

    using Microsoft.AspNet.Identity;
    using Microsoft.Owin.Security;
    using Microsoft.Owin.Security.OAuth;
    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Security.Claims;
    using System.Threading.Tasks;
    using System.Web;
    using System.Web.Security;
    
    namespace YourAPI.Providers
    {
        public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
        {
            public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
            {
                context.Validated();
            }
    
            public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
            {
                context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
                MembershipUser user = null;
                user = Membership.GetUser(context.UserName);
                if (user == null)
                {
                    context.SetError("invalid_grant", "user not found.");
                    return;
                }
                bool validUser = Membership.ValidateUser(context.UserName, context.Password);
                if (validUser)
                {
                    string[] rolesArr = Roles.GetRolesForUser(context.UserName);
                    string userId = user.ProviderUserKey.ToString();
    
                    ...
    
                    var identity = new ClaimsIdentity(context.Options.AuthenticationType);
                    identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
                    foreach (string role in rolesArr)
                    {
                        identity.AddClaim(new Claim(ClaimTypes.Role, role));
                    }
    
                    List<Claim> roles = identity.Claims.Where(c => c.Type == ClaimTypes.Role).ToList();
                    AuthenticationProperties properties = CreateProperties(user.UserName, JsonConvert.SerializeObject(roles.Select(x => x.Value)), userId, customerId);
    
                    AuthenticationTicket ticket = new AuthenticationTicket(identity, properties);
    
                    context.Validated(ticket);
                }
                else
                {
                    context.SetError("invalid_grant", "The user name or password is incorrect.");
                    return;
                }
    
            }
            public static AuthenticationProperties CreateProperties(string userName, string Roles, string UserID, string CustomerID)
            {
                IDictionary<string, string> data = new Dictionary<string, string>
                {
                    { "userName", userName },
                    { "roles", Roles},
                    { "User_ID", UserID },
                    { "Customer_ID" , CustomerID } //my 
                };
                return new AuthenticationProperties(data);
            }
    
            public override Task TokenEndpoint(OAuthTokenEndpointContext context)
            {
                foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
                {
                    context.AdditionalResponseParameters.Add(property.Key, property.Value);
                }
    
                return Task.FromResult<object>(null);
            }
        }
    
    }
    

    Inside AppStart folder in WebAPI

    using Newtonsoft.Json.Serialization;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net.Http.Formatting;
    using System.Web.Http;
    using System.Web.Http.Cors;
    
    namespace YourAPI
    {
        public static class WebApiConfig
        {
            public static void Register(HttpConfiguration config)
            {
                config.EnableCors();
                config.EnableCors(new EnableCorsAttribute("*", "*", "*"));
                config.MapHttpAttributeRoutes();
                config.Routes.MapHttpRoute(
                   name: "ControllerAndAction",
                   routeTemplate: "api/{controller}/{action}/{id}",
                   defaults: new { id = RouteParameter.Optional, extension = RouteParameter.Optional }
                );
    
                var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
                jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    
            }
        }
    }
    

    Inside Your API Controller:

    [AcceptVerbs("Get", "Post")]
            [ActionName("YourMethod")]
            [Authorize]
            public HttpResponseMessage YourMethod(string userID)
            {
                int count = users.getUserCompanyCount(userID); //sample
                return new HttpResponseMessage()
                {
                    Content = new StringContent(count.ToString(), Encoding.UTF8)
                };
            }
    

    Inside Your App:

    method with Authentication send AccessToken

    public async Task<int> getYourMethodAsync(string userId, string accessToken)
            {
                var client = new HttpClient();
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
                var content = await client.GetStringAsync(Settings.API_URL + "/api/Account/YourMethod?userId=" + userId);
                var result = int.Parse(content);
                return result;
            }
    
    public class ApiUsers
        {
            public async Task<string> LoginAsync(string userName, string password)
            {
                string result = "";
                try
                {
                    var keyValues = new List<KeyValuePair<string, string>>
                    {
                        new KeyValuePair<string, string>("username", userName),
                        new KeyValuePair<string, string>("password", password),
                        new KeyValuePair<string, string>("grant_type", "password")
                    };
                    var request = new HttpRequestMessage(HttpMethod.Post, Settings.API_URL + "/Token");
                    request.Content = new FormUrlEncodedContent(keyValues);
                    var client = new HttpClient();
                    var response = await client.SendAsync(request);
                    var content = await response.Content.ReadAsStringAsync();
                    JObject jwtDynamic = JsonConvert.DeserializeObject<dynamic>(content);
                    result = content;
                    var accessToken = jwtDynamic.Value<string>("access_token");
                    var accessTokenExpiration = jwtDynamic.Value<DateTime>(".expires");
                    Settings.AccessTokenExpiration = accessTokenExpiration;
                }
                catch (Exception ex)
                {
                    result = ex.Message;
                }
                return result;
            }
    
            public async Task GetNewTokenAsync()
            {
                var keyValues = new List<KeyValuePair<string, string>>
                {
                    new KeyValuePair<string, string>("username", Settings.Username),
                    new KeyValuePair<string, string>("password", Settings.Password),
                    new KeyValuePair<string, string>("grant_type", "password")
                };
                var request = new HttpRequestMessage(HttpMethod.Post, Settings.API_URL + "/Token");
                request.Content = new FormUrlEncodedContent(keyValues);
                var client = new HttpClient();
                var response = await client.SendAsync(request);
                var content = await response.Content.ReadAsStringAsync();
                JObject jwtDynamic = JsonConvert.DeserializeObject<dynamic>(content);
                var accessToken = jwtDynamic.Value<string>("access_token");
                var accessTokenExpiration = jwtDynamic.Value<DateTime>(".expires");
                Settings.AccessToken = accessToken;
                Settings.AccessTokenExpiration = accessTokenExpiration;
            }
    

    In login Page:

    string response = await apiUsers.LoginAsync(username, pass);
                        if (!string.IsNullOrEmpty(response))
                        {
                            JObject jwtDynamic = JsonConvert.DeserializeObject<dynamic>(response);
                            var accessToken = jwtDynamic.Value<string>("access_token");
                            if (!string.IsNullOrEmpty(accessToken))
                            {
                                var user_id = jwtDynamic.Value<string>("User_ID");
                                var customer_id = jwtDynamic.Value<long>("Customer_ID");
                                var rolesJson = jwtDynamic.Value<string>("roles");
                                var roles = JsonConvert.DeserializeObject<List<string>>(rolesJson);
    
                                Settings.AccessToken = accessToken;
                                Settings.Username = username;
                                Settings.Password = pass;
                                Settings.Customer_ID = customer_id.ToString();
                                Settings.User_ID = user_id;
                                Settings.Roles = string.Join(",", roles.ToArray()); 
                            }
                            else
                            {
                                DependencyService.Get<ILodingPageService>().HideLoadingPage();
                                var messsge = "invalid user or password!";
                                DependencyService.Get<IMessage>().ShortTime(messsge);
                            }
    

    hope this helps you.

Sign In or Register to comment.