locked
Calling a Web Api method when user is authenticated RRS feed

  • Question

  • User-1204646426 posted

    Hello,

    I am having a problem calling a Web Api method when user is authenticated using Token and OWIN.

    The fact is that when I call a Web Api method when user is authenticated, it is not recorgnized.

    Formerly, I had problem with Logout method in AccountController. I solved it by using AllowAnonymous attribute.

    However, now I am facing the same problem with ChangePassword method. I cannot add AllowAnonymous attribute in this case because when I do that I cannot retrieve the logged in user Id.

    If I don't add AllowAnonymous attribute, system throws a forbidden error.

    I am stuck here.... how can I solve it?

    For instance, this is ChangePassword method in AccountController:

        // POST api/Account/ChangePassword
        [Route("ChangePassword")]
        public async Task<IHttpActionResult> ChangePassword(ChangePasswordBindingModel model)
        {
            if (!ModelState.IsValid)
            {
                // return BadRequest(ModelState);
                return Json(GetModelErrorMessages());
            }
    
            try
            {
                IdentityResult result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword,
                    model.NewPassword);
    
                if (!result.Succeeded)
                {
                    return GetErrorResult(result);
                }
            }
            catch(Exception ex)
            {
    
            }
    
            return Ok();
        }

    This is an MVC application, and to log in, I use a custom OAuthAuthorizationServerProvider. All works perfectly, but when I try to call a Web Api method from a MVC controller or from an AJAX request. In these cases, I receive a forbidden error.

    Thanks Jaime

    Tuesday, December 4, 2018 11:33 PM

All replies

  • User475983607 posted

    This is a question for your OAuth provider.  Generally, you add a bearer token to the API request.

    Wednesday, December 5, 2018 12:21 AM
  • User-1204646426 posted

    Hello,

    This is how the auth provider is configured (Startup.Auth.cs file). This code is automatically generated by Visual Studio wizard:

    public void ConfigureAuth(IAppBuilder app)
            {
                // Configure el contexto de base de datos y el administrador de usuarios para usar una única instancia por solicitud
                //app.CreatePerOwinContext(ApplicationDbContext.Create);
                app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
                app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
    
                // Permitir que la aplicación use una cookie para almacenar información para el usuario que inicia sesión
                // y una cookie para almacenar temporalmente información sobre un usuario que inicia sesión con un proveedor de inicio de sesión de terceros
                app.UseCookieAuthentication(new CookieAuthenticationOptions());
                app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
    
                // Configure la aplicación para el flujo basado en OAuth
                PublicClientId = "self";
                OAuthOptions = new OAuthAuthorizationServerOptions
                {
                    TokenEndpointPath = new PathString("/Token"),
                    Provider = new ApplicationOAuthProvider(PublicClientId),
                    AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
                    AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
                    // En el modo de producción establezca AllowInsecureHttp = false
                    AllowInsecureHttp = true
                };
    
                // Permitir que la aplicación use tokens portadores para autenticar usuarios
                app.UseOAuthBearerTokens(OAuthOptions);
    
                // Quitar los comentarios de las siguientes líneas para habilitar el inicio de sesión con proveedores de inicio de sesión de terceros
                //app.UseMicrosoftAccountAuthentication(
                //    clientId: "",
                //    clientSecret: "");
    
                //app.UseTwitterAuthentication(
                //    consumerKey: "",
                //    consumerSecret: "");
    
                //app.UseFacebookAuthentication(
                //    appId: "",
                //    appSecret: "");
    
                //app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
                //{
                //    ClientId = "",
                //    ClientSecret = ""
                //});
            }

    On the other hand, how to add a bearer to the API request?

    This is how I invoke ChangePassword API from Ajax:

    $("#btnCambiar").on("click", function (event) {
                    event.preventDefault();
    
                    runWaitMe('#changeform', "Cambiando Contraseña...");
    
                    var data = {
                        OldPassword: $('#OldPassword').val(),
                        NewPassword: $('#NewPassword').val(),
                        ConfirmPassword: $('#ConfirmPassword').val(),
                    };
    
                    $.ajax({
                        type: 'POST',
                        url: "/api/Account/ChangePassword",
                        data: JSON.stringify(data),
                        contentType: 'application/json; charset=utf-8'
                    })
                        .done(function (data) {
                            if (data.indexOf('ERROR: ') == -1)
                                swal({
                                    type: 'success',
                                    title: 'Éxito',
                                    html: 'La contraseña fue cambiada exitosamente.'
                                });
                            else
                                swal({
                                    type: 'error',
                                    title: 'Ups...',
                                    html: data.substr(7)
                                });
                        })
                        .fail(function (jqXHR) {
                            swal({
                                type: 'error',
                                title: 'Ups...',
                                text: 'Debe llenar todos los campos del formulario en forma correcta.'
                            });
                        })
                        .always(function () {
                            hideWaitMe('#changeform');
                        });
                });

    Thanks

    Jaime

    Wednesday, December 5, 2018 12:55 AM
  • User475983607 posted

    I recommend visiting the following link to learn how to build and implement an OWIN OAuth Authorization Server.

    https://docs.microsoft.com/en-us/aspnet/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server

    .

    Wednesday, December 5, 2018 12:07 PM