Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Web API – authenticate with bearer token

I have created a MVC application for allowing external authentication/registration. It has been created with all the necessary components (Owin, EF, register, login, logout) and I am able to perform all the basic activities in the application.

Now, I want to integrate the web application with the Web API which is going to be used by my mobile app too. I stuck in the authentication in the Web API calls (with the bearer token I received from the web application).

I saw examples to create WEB API projects with OWIN middleware enabled. But i dont know how to centralize the external authentication process and use the token for both my web application and the mobile application And I don't want to go for the ANGULAR or Single page application. Can anyone suggest me the right technical path to fix this issue. Thank you.

Step 1:

I created a MVC project in visual studio 2015 with Individual Login Enabled. And configured the Keys that i configured everything in the google developer console. My Startup.cs will have the following code

 public void ConfigureAuth(IAppBuilder app)
    {
        // Configure the db context, user manager and signin manager to use a single instance per request
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

        // Enable the application to use a cookie to store information for the signed in user
        // and to use a cookie to temporarily store information about a user logging in with a third party login provider
        // Configure the sign in cookie
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            Provider = new CookieAuthenticationProvider
            {
                // Enables the application to validate the security stamp when the user logs in.
                // This is a security feature which is used when you change a password or add an external login to your account.  
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                        validateInterval: TimeSpan.FromMinutes(30),
                        regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
            }
        });

Step 2:

Changed the webconfig file to point my local DB and run the app, i am able to successfully login through google with my gmail account and user details are added to ASPUSerTables in the DB successfully

Step 3:

Now I wanted to create a WEB API Project which will be connected to the DB and retrive some data to the MVC web application and Mobile application (I am stuck on authentication part here). I need to use third party authentication to my mobile app too (Xamarin) and use the common API from my mobile app and MVC website

Step 4 So I thought, Instead of WEB application (Step 1), I should have created WEB API Project which will look like below to return the auth token in Startup.cs and store that cookie in the website to pass in the subsequent requests.

app.UseCookieAuthentication(new CookieAuthenticationOptions());
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        // Configure the application for OAuth based flow
        PublicClientId = "self";
        OAuthOptions = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/Token"),
            Provider = new ApplicationOAuthProvider(PublicClientId),
            AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
            // In production mode set AllowInsecureHttp = false
            AllowInsecureHttp = true
        };

I don't want to go with ANGULAR and I need my WebApplication(MVC) and WEB API project Authenticates properly for all the requests. Please advise me the right path. Thanks

like image 475
DevExpress Avatar asked Mar 23 '17 18:03

DevExpress


1 Answers

What you need to do is follow these steps

  • Create a Web API project with Individual User Accounts Authentication.
  • Now, you will have all ready to use API's for Register, change password, as well as API endpoint to generate token for a user.
  • Create another project but this time it is MVC with No Authentication in same solution.

well this will be our architecture

enter image description here

This is API controller

[Authorize]
public class ValuesController : ApiController
{
      [HttpGet]
      public IEnumerable<string> Get()
      {
         return new string[] { "values1", "values2" };
      }
}

This is your MVC controller

public class MVCValuesController : Controller
{
     HttpClient client;

     // web api Url
     string url = string.Format("http://localhost:60143/api/Values");
     string bearerToken = string.Format("bearer token from web api");
     public MVCValuesController()
     {
        client = new HttpClient(); 
        client.BaseAddress = new Uri(url);
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        client.DefaultRequestHeaders.Accept.Add("Authorization", "Bearer " + bearerToken);
     }

     public ActionResult GetValues()
     {
         HttpResponseMessage responseMessage = client.Get(url);
         if (responseMessage.IsSuccessStatusCode)
         {
             var responseData =   responseMessage.Content.ReadAsStringAsync().Result;
             var jsonResponse = JsonConvert.DeserializeObject<List<string>>(responseData);
             return View(jsonResponse);
         }
         return View("Error");
     }
}

I have not used async here, but you can do it. and also you need to start both of your projects when you run it. right click on solution and click Set Start Up projects then you can select multiple projects and set action as Start.

public class MVCAccountController : Controller
{
     HttpClient client;

     // web api Url
     string url = string.Format("http://localhost:60143/");
     //string bearerToken = string.Format("bearer token from web api");
     public MVCValuesController()
     {
        client = new HttpClient(); 
        client.BaseAddress = new Uri(url);
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
         // just adding a JObject you can create a class 

         JObject tokenJobject = new JObject(
                                        new JProperty("Email", "[email protected]"),
                                        new JProperty("Password", "Pass123"));
                                        new JProperty("ConfirmPassword", "Pass123"));
            HttpContent baseContent = new StringContent(tokenJobject.ToString(), Encoding.UTF8, "application/json");
        //client.DefaultRequestHeaders.Accept.Add("Authorization", "Bearer " + bearerToken);


     }

     public async Task<ActionResult> GetValues()
     {
         string requestUri = string.Format("api/Account/Register");
         HttpResponseMessage responseMessage = await client.PostAsync(requestUri, baseContent);
         if (responseMessage.IsSuccessStatusCode)
         {
             var responseData =   responseMessage.Content.ReadAsStringAsync();
             var jsonResponse = JsonConvert.DeserializeObject<string>(responseData);
             return View(jsonResponse);
         }
         return View("Error");
     }
}
like image 194
Jawand Singh Avatar answered Nov 15 '22 06:11

Jawand Singh