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
What you need to do is follow these steps
well this will be our architecture
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");
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With