November Happy Hour will be moved to Thursday December 5th.

WebApi + MembershipProvider + Postman

Vote:
 

CMS 11

Is there a way of using Postman with any authentication, to call an webapi directly and authenticate to SqlServerMembershipProvider (a user in db)

    [System.Web.Http.Authorize(Roles = "CmsAdmins")]
    public class MyApiController : ApiController

I do get unauthorized when using basic authentication in postman

Is it possible?

#286764
Sep 07, 2022 12:56
Vote:
 

Mr Gosso, are you trying to authenticate first and then call your webapi controller? Or are you trying to do it all in one request?

#286860
Sep 08, 2022 20:26
Vote:
 

yes, same in one request.... or what possibilities do I have?

#286965
Sep 10, 2022 14:40
Vote:
 

You could do the following in conjunction with Postman and cookie authentication:

  • As part of your webapi collection create a SignIn method. Use the ApplicationSignInManager to log in your user.
  • This will create an authentication cookie add it to the response
  • In postman take the cookie from the response and store it in a global (or collection) variable.
  • In your next request to web api that requires you to be authenticated and authorized as a 'cmsadmin', add the stored cookie to your request and execute.
  • You should find your webapi method now executes under your logged in user.

This is two calls...but if you wanted one call....maybe you could create a custom authorization attribute?

#287000
Sep 11, 2022 11:32
Vote:
 

A custom authorize attibute will be your best bet, this will enable authentication either via Postman or programmatically in one request.

Example code I've used in the past to implement WebAPI basic authentication, the Role is hardcoded as I used it purely for authentication purposes but you can pass the role as a parameter to the attribute

public class ApiBasicAuthenticationAttribute : AuthorizationFilterAttribute
	{
		private UserService _userService;

		public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
		{
			if (actionContext.Request.Headers.Authorization == null)
			{
				actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
			}
			else
			{
				//Retrieve username and password from header
				var authenticationHeader = actionContext.Request.Headers.Authorization.Parameter;
				var decodedHeader = Encoding.UTF8.GetString(Convert.FromBase64String(authenticationHeader));
				var credentials = decodedHeader.Split(':');
				
				_userService = ServiceLocator.Current.GetInstance<UserService>();

				var isAuthorised = Task.Run(() => _userService.ValidateUserAndRole(credentials[0], credentials[1], "ApiClients")).Result;

				if (!isAuthorised)
				{
					actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
				}
			}

			base.OnAuthorization(actionContext);
		}
	}

The UserService method is just a wrapper for the ApplicationUserManager

public async Task<bool> ValidateUserAndRole(string username, string password, string role)
		{
			var user = await _userManager.FindAsync(username, password);

			var isAuthorised = user != null && await _userManager.IsInRoleAsync(user.Id, role);

			return isAuthorised;
		}
#287789
Sep 21, 2022 7:16
Vote:
 

Thanks guys, I ended up with this since we got old membershipprovider, also this combines api auth and CMS cookies auth

using System;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web.Http.Filters;
using System.Web.Security;

namespace MySite.Features
{
    public class ApiBasicAuthenticationAttribute : AuthorizationFilterAttribute
    {
        public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            if (actionContext.Request.Headers.Authorization == null)
            {
                var user = Membership.GetUser();
                if (user != null && user.IsApproved && (Roles.IsUserInRole(user.UserName, "WebAdmins") || Roles.IsUserInRole(user.UserName, "Administrators")))
                {

                }
                else
                {
                    actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
                }
            }
            else
            {
                //Retrieve username and password from header
                var authenticationHeader = actionContext.Request.Headers.Authorization.Parameter;
                var decodedHeader = Encoding.UTF8.GetString(Convert.FromBase64String(authenticationHeader));
                var credentials = decodedHeader.Split(':');

                var isAuthorised = ValidateUserAndRole(credentials[0], credentials[1], "WebAdmins");

                if (!isAuthorised)
                {
                    actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
                }
            }

            base.OnAuthorization(actionContext);
        }

        public bool ValidateUserAndRole(string username, string password, string role)
        {
            if (Membership.ValidateUser(username, password))
            {
                var user = Membership.GetUser(username);
                if (user != null && user.IsApproved && (Roles.IsUserInRole(username, role) || Roles.IsUserInRole(username, "Administrators")))
                {
                    return true;
                }
            }
            return false;
        }
    }
}
#288736
Oct 06, 2022 9:14
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.