Authentication Authentication Asp.Net WebApi OWIN

After using the online tutorial on using token-based authentication using OWIN, I was able to run a test application with a hard coded username / password, as the demo did.

However, now I want to use my model from my web application.

My authentication happens, as the demo says, in this piece of code.

namespace UI { public class AuthorisationServerProvider : OAuthAuthorizationServerProvider { public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) { context.Validated(); // Means I have validated the client. } public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { // Here we validate the user... var identity = new ClaimsIdentity(context.Options.AuthenticationType); if (context.UserName == "user" && context.Password == "password") { identity.AddClaim(new Claim(ClaimTypes.Role, "admin")); identity.AddClaim(new Claim("username", "user")); identity.AddClaim(new Claim(ClaimTypes.Name, "My Full Name")); context.Validated(identity); } else { context.SetError("Invalid grant", "Username or password are incorrect"); return; } } } } 

I have a WebAPI controller from which I get the model, and ... not sure how to call the above code from my webapi controller. At the moment, the above code is expecting a call to myurl / token, which was defined in the start code.

  public class Startup { public void Configuration(IAppBuilder app) { // Enables cors origin requests. app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); // Config OAuth authorisation server; var myProvider = new AuthorisationServerProvider(); OAuthAuthorizationServerOptions options = new OAuthAuthorizationServerOptions { AllowInsecureHttp = true, // Live version should use HTTPS... TokenEndpointPath = new PathString("/token"), AccessTokenExpireTimeSpan = TimeSpan.FromDays(1), Provider = myProvider }; app.UseOAuthAuthorizationServer(options); app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); HttpConfiguration config = new HttpConfiguration(); WebApiConfig.Register(config); } } 

So, I assume that the url of my webapi call should be / token? So in my (knockout model) in my user interface I tried this:

  Login() { var data = { username : this.login.emailAddress(), password : this.login.password(), RememberMe: this.login.rememberMe(), grant_type: "password" } return $.ajax({ type: "POST", data: data ? JSON.stringify(data) : null, dataType: "json", url: "/token", contentType: "application/json" }).done((reply) => { alert("Done!"); }); } 

But I get an exception:

 "error": "unsupported_grant_type" 

In Postman, I can authenticate a hard-coded username / password.

enter image description here

But I'm not sure how to connect my api call from my user interface for authentication.

I was hoping to create a "Login" method on my api controller (ASP.Net WebAPI), for example:

 [Route("login"), HttpPost, AllowAnonymous] public ReplyDto Login(LoginRequest login) { ReplyDto reply = _userService.Login(login.Email, login.Password); return reply; } 

So, my _userService checks if the user is in the database ... if so, call my OAuth authentication here by passing a few parameters. But not sure if this is possible. Can I call my authentication from this api method? However, I will need to remove the bit / token.

+6
authentication c # asp.net-web-api
source share
2 answers

You do not need to create a Login method, since you already have it. This is http: // localhost: 1234 / token . This will generate a token if the user exists and if the password is correct. But get this behavior needed to implement your own AuthServerProvider using OAuthAuthorizationServerProvider

 public class DOAuthServerProvider : OAuthAuthorizationServerProvider 

and then you override the method to implement your logic:

 public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { try { string allowedOrigin = context.OwinContext.Get<string>(DOAuthStatic.ALLOWED_CORS_ORIGINS_KEY); if (allowedOrigin != null) { context.OwinContext.Response.Headers[DOAuthStatic.CORS_HEADER] = allowedOrigin; } DAuthenticationResponse authResponse = await _authRepository.Authenticate(context.UserName, context.Password); if (!authResponse.IsAuthenticated) { context.SetError(OAuthError.InvalidGrant, $"{(int)authResponse.AuthenticateResult}:{authResponse.AuthenticateResult}"); return; } if (authResponse.User.ChangePasswordOnLogin) { _userAuthenticationProvider.GeneratePasswordResetToken(authResponse.User); } IDictionary<string, string> props = new Dictionary<string, string> { { DOAuthStatic.CLIENT_NAME_KEY, context.ClientId ?? string.Empty } }; ValidateContext(context, authResponse, props); } catch (Exception ex) { DLogOAuth.LogException(ex, "DCO0407E", "OAuthServerProvider - Error validating user"); throw; } } 

You are almost there, you just need to take two more steps:

  • Add AuthorizeAttribute to your method or controller to restrict access to unverified users.
  • Add an access token requesting a header. If you skip this step, you will receive a status code 401 HTTP, which means unauthorized access. Here's how you can confirm that the authorize attribute added in step 1 works.

Here is a series of TV shows in which everything is explained very well: Token-based authentication (better than I have :))

+6
source share

Change the content type "application / json" to "Application / www-form-urlencoded"

You sent the data in Postman format "application / www-form-urlencoded". But in your code using "application / Json" the content type mismatch. Therefore, the data does not send the correct format.

You can change if it works fine.

+1
source share

All Articles