Can't find user tables MVC Web API - model-view-controller

After successful registration, can't find aspnet user tables and also when I tried to login, it returns invalid grant type
public IdentityResult Register(string username, string password)
{
var userStore = new UserStore<IdentityUser>();
var manager = new UserManager<IdentityUser>(userStore);
var user = new IdentityUser() { UserName = username, Email = username };
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 3
};
IdentityResult result = manager.Create(user, password);
return result;
}
when I tried to login, it returns invalid grant type
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var userStore = new UserStore<IdentityUser>(new ApplicationDbContext());
var manager = new UserManager<IdentityUser>(userStore);
var user = await manager.FindAsync(context.UserName, context.Password);
if(user !=null)
{
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
identity.AddClaim(new Claim("Username", user.UserName));
identity.AddClaim(new Claim("Email", user.Email));
identity.AddClaim(new Claim("LoggedOn", DateTime.Now.ToString()));
context.Validated();
}
else
{
return;
}
}
public class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext()
: base("MyEntities")
{
}
public DbSet<userlogindetails> userlogindetails{ get; set; }
}
webconfig
<add name="MyEntities" connectionString="metadata=res://*/Models.MyModel.csdl|res://*/Models.MyModel.ssdl|res://*/Models.MyModel.msl;provider=System.Data.SqlClient;provider connection string="data source=MY-PC\SQLEXPRESS;initial catalog=MyDB;user id=user;password=pass;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />

It turns out that i need to add Default ConnectionString
<add name="DefaultConnection" connectionString="Data Source=My-PC\SQLEXPRESS;Initial Catalog=MyDB;User ID=username;Password=pass" providerName="System.Data.SqlClient" />

Related

EF Core Decryption of SQL Column Level Encryption

My team and I are attempting to decrypt values from a db (Azure SQL) that has column level encryption turned on; with certs stored in key vault.
Expected Result:
var someLinqQuery = _contex.Users.First();
someLinqQuery.SSN = "000-00-0000";
Actual Result:
var someLinqQuery = _context.Users.First();
someLinqQuery.SSN = "the var binary (encrypted) version of the ssn";
FWIW, this works fine w/ raw sql. But we would like the option of not doing it this way, and encrypting more data.
Also we have the azure keyvault code here:
//Key Vault Code Below
private static ClientCredential _clientCredential;
public static void InitializeAzureKeyVaultProvider()
{
if (!isActivated)
{
_clientCredential = new ClientCredential(_applicationId, _clientKey);
SqlColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider = new SqlColumnEncryptionAzureKeyVaultProvider(GetToken);
Dictionary<string, SqlColumnEncryptionKeyStoreProvider> providers = new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>
{
{ SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, azureKeyVaultProvider }
};
SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers);
isActivated = true;
}
}
public static async Task<string> GetToken(string authority, string resource, string scope)
{
var authContext = new AuthenticationContext(authority);
AuthenticationResult result = await authContext.AcquireTokenAsync(resource, _clientCredential);
if (result == null)
{
throw new InvalidOperationException("Failed to obtain the access token");
}
AccessToken = result.AccessToken;
return result.AccessToken;
}
This is loaded in the startup class. I've also moved the code to other places in the app w/ the same results.
My question is this, on .net core 2.1.x and EF core 2.1.x is this possible using LINQ? Do I need to upgrade?
According to my research, if we want to use Always Encryption( Column Encryption), we need to use the Microsoft.Data.SqlClient. For more details, please refer to the document. Besides, Microsoft.EntityFrameworkCore.SqlServer 3.x depends on Microsoft.Data.SqlClient, so I suggest you use EF core 3.x
For example. I do a test in the console application.
Configure database
Application
a. Install SDK
<PackageReference Include="Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider" Version="1.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.2" />
<PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="5.2.7" />
b. data model
class Patient
{
public int PatientId { get; set; }
public string SSN { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime BirthDate { get; set; }
}
c. database context
private static Boolean isInitialized;
public TestContext(DbContextOptions<TestContext> options) : base(options) {
if(! isInitialized) { InitializeAzureKeyVaultProvider(); isInitialized = true; }
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// your sql server connnection string
var constr = "Server=<>;Initial Catalog=<>;User ID=<>;Password=<>;Column Encryption Setting=enabled";
SqlConnection connection = new SqlConnection(constr);
optionsBuilder.UseSqlServer(connection);
}
public DbSet<Patient> Patients { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Patient>().ToTable("Patients");
}
private static string clientId = "";
private static string clientSecret = "";
private static ClientCredential _clientCredential;
private static void InitializeAzureKeyVaultProvider()
{
_clientCredential = new ClientCredential(clientId, clientSecret);
SqlColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider =
new SqlColumnEncryptionAzureKeyVaultProvider(GetToken);
Dictionary<string, SqlColumnEncryptionKeyStoreProvider> providers =
new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>();
providers.Add(SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, azureKeyVaultProvider);
SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers);
}
private static async Task<string> GetToken(string authority, string resource, string scope)
{
var authContext = new AuthenticationContext(authority);
AuthenticationResult result = await authContext.AcquireTokenAsync(resource, _clientCredential);
if (result == null)
throw new InvalidOperationException("Failed to obtain the access token");
return result.AccessToken;
}
d. test
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
DbContextOptions<TestContext> options = new DbContextOptions<TestContext>();
var db =new TestContext(options);
var results =db.Patients.ToListAsync().Result;
foreach (var r in results) {
Console.WriteLine(r.SSN);
}
Console.ReadLine();
}

Postman is giving 401 instead of 403 on Web API

With this code:
MyAuthorizationServerProvider
public class MyAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
context.Validated(); //
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
if (context.UserName == "admin" && context.Password == "admin")
{
identity.AddClaim(new Claim(ClaimTypes.Role, "admin"));
identity.AddClaim(new Claim("username", "admin"));
identity.AddClaim(new Claim(ClaimTypes.Name, "Juan Dela Cruz"));
context.Validated(identity);
}
else if (context.UserName == "user" && context.Password == "user")
{
identity.AddClaim(new Claim(ClaimTypes.Role, "user"));
identity.AddClaim(new Claim("username", "user"));
identity.AddClaim(new Claim(ClaimTypes.Name, "Barok Kabundukan"));
context.Validated(identity);
}
else
{
context.SetError("invalid_grant", "Provided username or password is incorrect");
return;
}
}
}
AuthorizeAttribute
protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
{
if (!HttpContext.Current.User.Identity.IsAuthenticated)
{
base.HandleUnauthorizedRequest(actionContext);
}
else
{
actionContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Forbidden);
}
}
Startup
public class Startup
{
public void Configuration(IAppBuilder app)
{
//enable cors origin requests
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
var myProvider = new MyAuthorizationServerProvider();
OAuthAuthorizationServerOptions options = new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = myProvider
};
app.UseOAuthAuthorizationServer(options);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
HttpConfiguration config = new HttpConfiguration();
WebApiConfig.Register(config);
}
}
DataController
public class DataController : ApiController
{
[AllowAnonymous]
[HttpGet]
[Route("api/data/forall")]
public IHttpActionResult Get()
{
return Ok("Server time is: " + DateTime.Now);
}
[Authorize]
[HttpGet]
[Route("api/data/authenticate")]
public IHttpActionResult GetForAuthenticate()
{
var identity = (ClaimsIdentity)User.Identity;
return Ok("Hello " + identity.Name);
}
[Authorize(Roles = "admin")]
[HttpGet]
[Route("api/data/authorize")]
public IHttpActionResult GetForAdmin()
{
var identity = (ClaimsIdentity)User.Identity;
var roles = identity.Claims
.Where(c => c.Type == ClaimTypes.Role)
.Select(c => c.Value);
return Ok("Hello " + identity.Name + " Role: " + string.Join(",", roles.ToList()));
}
}
With that code, I am able to get the token and authenticate. The problem however is when I use the "user" credentials and authenticate then access the method that has Authorize(Role="admin"), in the Postman, I get "401". I should be getting the "403" since I am authenticated already but do not have a role of "admin". Can you please show me where I am getting it wrong? Thank you.
No, you should still get 401. 401 means unauthorized, not unauthenticated. In your scenario, you do not have the admin role, so you are not authorized to access the requested resource.
EDIT:
I don't usually post Wikipedia, but I think the article on 403 explains this pretty well; see the section on the differences between 401 and 403:
https://en.wikipedia.org/wiki/HTTP_403

webapi-use claims with windows authentication

The method has been secured with roles=admin:
[Authorize(Roles = "admin")]
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}}
I am successfully to use claims with Webapi project where Individual User Account is selected where the claim admin is injected in
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager, string authenticationType)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
// Add custom user claims here
userIdentity.AddClaim(new Claim(ClaimTypes.Role, "admin"));
return userIdentity;
}
}
Now I want to test with Windows authentication option where a IAuthenticationFilter is implemented:
public class CustomAuthenticationFilter : IAuthenticationFilter
{
public bool AllowMultiple { get { return true; } }
public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
var windowsPrincipal = context.Principal as WindowsPrincipal;
if (windowsPrincipal != null)
{
var name = windowsPrincipal.Identity.Name;
// TODO: fetch claims from db (i guess based on name)
var identity = new ClaimsIdentity(windowsPrincipal.Identity);
identity.AddClaim(new Claim(ClaimTypes.Role, "admin"));
var claimsPrincipal = new ClaimsPrincipal(identity);
// here is the punchline - we're replacing original windows principal
// with our own claims principal
context.Principal = claimsPrincipal;
}
return Task.FromResult(0);
}
public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
{
return Task.FromResult(0);
}
}
and added to class webapiconfig:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.Filters.Add(new CustomAuthenticationFilter());
...
}
}
The claim admin is in User.Identity.Claims when debugging webapi project, however it could not be authorized in method /api/values/get.
Any idea?
The default identity RoleClaimType is identity/claims/groupsid which is not role.
By setting RoleClaimType to identity/claims/role in the ClaimsIdentity constructor, we can get it passing [Authorize(Roles = "admin")]
public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
var windowsPrincipal = context.Principal as WindowsPrincipal;
if (windowsPrincipal != null)
{
var name = windowsPrincipal.Identity.Name;
// TODO: fetch claims from db (i guess based on name)
var identity = new ClaimsIdentity(windowsPrincipal.Identity,
null,
"Negotiate",
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role");
//identity
identity.AddClaim(new Claim(ClaimTypes.Role, "admin"));
var claimsPrincipal = new ClaimsPrincipal(identity);
// here is the punchline - we're replacing original windows principal
// with our own claims principal
context.Principal = claimsPrincipal;
}
return Task.FromResult(0);
}
Here is the new identity:

Explicitly token validation

I am developing an Asp.net web Api 2 project and I am using OAuth. Now I am able to generate token and send it to client. Now how I will send that token to server from client using jQuery ajax call and validated that token explicitly and get user information. I am not using asp.net identity.
Code
public class UserModel
{
public string UserName { get; set; }
public string Password { get; set; }
public string ConfirmPassword { get; set; }
}
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
ConfigureOAuth(app);
HttpConfiguration config = new HttpConfiguration();
WebApiConfig.Register(config);
app.UseWebApi(config);
}
public void ConfigureOAuth(IAppBuilder app)
{
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = new SimpleAuthorizationServerProvider()
};
// Token Generation
app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
}
public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
// Resource owner password credentials does not provide a client ID.
if (context.ClientId == null)
{
context.Validated();
}
return Task.FromResult<object>(null);
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
using (AuthRepository _repo = new AuthRepository())
{
var user = _repo.FindUser(context.UserName, context.Password);
if (user == null)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
}
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
identity.AddClaim(new Claim("sub", context.UserName));
identity.AddClaim(new Claim("role", "user"));
context.Validated(identity);
}
}
You do not need and should not validate the token manually, just attribute you protected API end point with [Authorize] attribute and leave this validation to the framework, if the token is invalid or expired Web API will return 401 and your are good to go.
Regarding sending your obtained token from client application the server, you need to send the token in the Authorization header for your request with Bearer scheme Authorization: Bearer xf7jsjaaa9292....
Something like the below will help
beforeSend: function (xhr) {
xhr.setRequestHeader ("Authorization", "Bearer YOUR_TOKEN_GOES_HERE");
}
So you can use jQuery beforeSend callback to add an HTTP Authorization header.
Btw I guess the sample code is from my blog http://bitoftech.net so feel free to remove the below claims as it is not useful for your case:
identity.AddClaim(new Claim("sub", context.UserName));
identity.AddClaim(new Claim("role", "user"));
And replace it with this one:
identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));

Web API 2 OWIN Bearer token authentication - AccessTokenFormat null?

I have an existing ASP.NET MVC 5 project and I'm adding a Web API 2 project to it. I want to use bearer token authentication and have followed Hongye Sun's tutorial "OWIN Bearer Token Authentication with Web API Sample" and this question as well.
In my Login method, for the line Startup.OAuthBearerOptions.AccessTokenFormat.Protect(ticket);, the AccessTokenFormat is null. Any idea why?
My AccountController:
[RoutePrefix("api")]
public class AccountController : ApiController
{
public AccountController() {}
// POST api/login
[HttpPost]
[Route("login")]
public HttpResponseMessage Login(int id, string pwd)
{
if (id > 0) // testing - not authenticating right now
{
var identity = new ClaimsIdentity(Startup.OAuthBearerOptions.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, id.ToString()));
AuthenticationTicket ticket = new AuthenticationTicket(identity, new AuthenticationProperties());
var currentUtc = new SystemClock().UtcNow;
ticket.Properties.IssuedUtc = currentUtc;
ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromMinutes(30));
var token = Startup.OAuthBearerOptions.AccessTokenFormat.Protect(ticket);
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ObjectContent<object>(new
{
UserName = id.ToString(),
AccessToken = token
}, Configuration.Formatters.JsonFormatter)
};
}
return new HttpResponseMessage(HttpStatusCode.BadRequest);
}
// POST api/token
[Route("token")]
[HttpPost]
public HttpResponseMessage Token(int id, string pwd)
{
// Never reaches here. Do I need this method?
return new HttpResponseMessage(HttpStatusCode.OK);
}
}
Startup class:
public class Startup
{
private static readonly ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; }
public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
public static Func<MyUserManager> UserManagerFactory { get; set; }
public static string PublicClientId { get; private set; }
static Startup()
{
PublicClientId = "MyWeb";
UserManagerFactory = () => new MyUserManager(new UserStore<MyIdentityUser>());
OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/api/token"),
Provider = new MyWebOAuthProvider(PublicClientId, UserManagerFactory),
AuthorizeEndpointPath = new PathString("/api/login"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true
};
}
public void Configuration(IAppBuilder app)
{
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/api/login")
});
// Configure Web API to use only bearer token authentication.
var config = GlobalConfiguration.Configuration;
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthBearerOptions.AuthenticationType));
app.UseWebApi(config);
}
}
MyIdentityUser just adds an extra property:
public class MyIdentityUser : IdentityUser
{
public int SecurityLevel { get; set; }
}
MyUserManager calls my custom user authentication method to an internal server:
public class MyUserManager : UserManager<MyIdentityUser>
{
public MyUserManager(IUserStore<MyIdentityUser> store) : base(store) { }
public MyIdentityUser ValidateUser(int id, string pwd)
{
LoginIdentityUser user = null;
if (MyApplication.ValidateUser(id, pwd))
{
// user = ??? - not yet implemented
}
return user;
}
}
MyWebOAuthProvider (I took this from the SPA template. Only GrantResourceOwnerCredentials has been changed):
public class MyWebOAuthProvider : OAuthAuthorizationServerProvider
{
private readonly string _publicClientId;
private readonly Func<MyUserManager> _userManagerFactory;
public MyWebOAuthProvider(string publicClientId, Func<MyUserManager> userManagerFactory)
{
if (publicClientId == null)
{
throw new ArgumentNullException("publicClientId");
}
if (userManagerFactory == null)
{
throw new ArgumentNullException("userManagerFactory");
}
_publicClientId = publicClientId;
_userManagerFactory = userManagerFactory;
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
using (MyUserManager userManager = _userManagerFactory())
{
MyIdentityUser user = null;
var ctx = context as MyWebOAuthGrantResourceOwnerCredentialsContext;
if (ctx != null)
{
user = userManager.ValidateUser(ctx.Id, ctx.Pwd);
}
if (user == null)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
ClaimsIdentity oAuthIdentity = await userManager.CreateIdentityAsync(user,
context.Options.AuthenticationType);
ClaimsIdentity cookiesIdentity = await userManager.CreateIdentityAsync(user,
CookieAuthenticationDefaults.AuthenticationType);
AuthenticationProperties properties = CreateProperties(user.UserName);
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(ticket);
context.Request.Context.Authentication.SignIn(cookiesIdentity);
}
}
public override Task TokenEndpoint(OAuthTokenEndpointContext context)
{
... // unchanged from SPA template
}
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
... // unchanged from SPA template
}
public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)
{
... // unchanged from SPA template
}
public static AuthenticationProperties CreateProperties(string userName)
{
... // unchanged from SPA template
}
}
MyWebOAuthGrantResourceOwnerCredientialsContext:
public class MyWebOAuthGrantResourceOwnerCredentialsContext : OAuthGrantResourceOwnerCredentialsContext
{
public MyWebOAuthGrantResourceOwnerCredentialsContext (IOwinContext context, OAuthAuthorizationServerOptions options, string clientId, string userName, string password, IList<string> scope)
: base(context, options, clientId, userName, password, scope)
{ }
public int Id { get; set; }
public string Pwd { get; set; }
}
How is AccessTokenFormat set? Is what I've set up correct? I'm not authenticating against any external services, just a legacy internal server.
Thanks.
I had the same problem - it was to do with my initialisation in Startup().
Like you, I was storing the OAuthBearerOptions in a static field:
OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
But then I was wrongly using a new instance of the same class later on:
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); // wrong!
Obviously the fix was to use the static field instead:
app.UseOAuthBearerAuthentication(OAuthBearerOptions);
In fact, it doesn't look like you call UseOAuthBearerAuthentication() at all. I followed this excellent series of posts by Taiseer Joudeh.
Full Startup.cs:
public class Startup
{
public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; }
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)
{
//use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseExternalSignInCookie(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ExternalCookie);
OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions() {
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = new SimpleAuthorizationServerProvider() // see post
};
// Token Generation
app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseOAuthBearerAuthentication(OAuthBearerOptions);
//[Configure External Logins...]
}
}
I'm not sure if you're still looking for the answer to this - but here's a bit of code that I'm using in my AngularJS app to get the security token from my WebAPI2 endpoint.
$http({
method: 'POST', url: '/token', data: { username: uName, password: uPassword, grant_type: 'password' },
transformRequest: function (obj) {
var str = [];
for (var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
}
}).success(function (data, status, headers, config) {
console.log("http success", data);
accessToken.value = data.access_token;
console.log("access token = ", accessToken.value);
}).error(function (data, status, headers, config) {
console.log("http error", data);
});
I can then pass the accessToken in the header of any other requests in order to get the authentication validation.
I have removed the sample code as it can cause confusion when it's used with Web API and SPA template. You'd better stay with the template code to use OAuth authorization server to generate token. In your scenario, you should use resource owner password grant to authenticate the user. Please check my blog on SPA template which has details about the password flow on http://blogs.msdn.com/b/webdev/archive/2013/09/20/understanding-security-features-in-spa-template.aspx
Instead of writing your own Web API to handle login, you need to use OWIN OAuth Server's /token endpoint to handle password login.

Resources