0
votes

I'm building a desktop APP using windows forms that needs to be authenticated via a WebAPI using Token authentication.

The API is proved that work because a mobile APP is using it and also I can get results using POSTMAN

enter image description here The problem is when I'm calling the Authentication method from the desktop App.

When I do the request, the API recieves it and it only goes until ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context), not reaching GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) in the Auth process.

Here is my CustomAuthProvider

public class CustomOAuthProvider : OAuthAuthorizationServerProvider
{

    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
            context.Validated();
            return Task.FromResult<object>(null);
    }

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        var allowedOrigin = "*";
        context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });
        var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();

        ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);

        if (user == null)
        {
            context.SetError("invalid_grant", "El nombre de usuario o contraseƱa son incorrectos");
            return;
        }

        ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, "JWT");
        var ticket = new AuthenticationTicket(oAuthIdentity, null);
        context.Validated(ticket);
    }
}

Here is my Startup class

 public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        ConfigureAuth(app);

        HttpConfiguration httpConfig = new HttpConfiguration();

        ConfigureOAuthTokenGeneration(app);
        ConfigureOAuthTokenConsumption(app);
        ConfigureWebApi(httpConfig);


    }
}

At the moment I'm trying two different ways to authenticate the APP.

First One:

public LoginResponseModel Authenticate(LoginRequestModel applicationUser)
    {
        using (var client = new WebClient())
        {
            try
            {

                client.Headers["Content-Type"] = "application/json";

                var data = applicationUser.Serialize();
                var response = client.UploadString(Context.ApiUrl + "Authenticate","POST", JsonConvert.SerializeObject(applicationUser));
                var resultJson = JsonConvert.DeserializeObject<LoginResponseModel>(response);

                return resultJson;
            }
            catch (Exception exception)
            {
            }
        }
        return null;
    }

And second one:

public async Task<ApplicationUser> Authenticate(LoginRequestModel applicationUser)
    {
        var client = new HttpClient();

            try
            {
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(
                    new MediaTypeWithQualityHeaderValue("application/json"));
            var data = applicationUser.Serialize();
                var response = await client.PostAsJsonAsync(Context.ApiUrl + "Authenticate",data );

                // return null by default (test)
                return null;
            }
            catch (Exception exception)
            {
            }
        return null;
    }

And this is the model I'm using for the request

public class LoginRequestModel
{
    public string Grant_type { get; set; } = "Password";
    public string UserName { get; set; }
    public string Password { get; set; }
}

And this should be the response:

public class LoginResponseModel
{
    public string Access_token { get; set; }
    public string Token_type { get; set; }
    public string Expires_in { get; set; }
}

Ah the moment both ways of calling the API only reach the initial verification of the owin process (ValidateClientAuthentication). What can be happening? How I can fix this? What I need to do to make the process go to GrantResourceOwnerCredentials?

thanks for the help

1

1 Answers

1
votes

I solved my problem. The problem was that the form wasn't being filled and sent correctly.

private AuthToken GetAuthToken(LoginRequestModel applicationUser)
    {
        using (var client = new HttpClient())
        {
            var form = new Dictionary<string, string>
            {
                {"grant_type", "password"},
                {"username", applicationUser.UserName},
                {"password", applicationUser.Password},
            };
            try
            {
                var tokenResponse = client.PostAsync(Context.ApiUrl + "Authenticate", new FormUrlEncodedContent(form)).Result; 
                var token = tokenResponse.Content.ReadAsAsync<AuthToken>(new[] { new JsonMediaTypeFormatter() }).Result;
               return token;
            }
            catch (Exception e)
            {
                Log4Net.log.Error("Error Getting Auth token", e);

                return null;
            }

        }
    }