Search code examples
asp.net-web-apiwebclientbasic-authentication

.net web executable to .net web api 401 error using BASIC authentication


I am not allowed to install fiddler at work so I am kind of flying blind.

I am running the web api and the web executable on local host through two separate instances of visual studio

I am fairly certain my Web API is working ok I type the URL manually into a web browser it asks me for user Id and password and then returns my JSON.

The web executable that calls the web api also works fine until I attempted to add BASIC authentication to the controller method now I am receiving a 401 error.

here is my code from the executable.

 Public Function get_vsmric_webApi(ByRef sErrorDescription As String) As Boolean
        Try
            Using proxy As New WebClient()
                Dim myurl As String = ConfigurationManager.AppSettings("WEBAPI_URL") & "vsmric"
                Dim userName As String = "QBERT"
                Dim passWord As String = "Qb3RT!"
                Dim credentials As String = Convert.ToBase64String(Encoding.ASCII.GetBytes(userName + ":" + passWord))
                proxy.Headers(HttpRequestHeader.Authorization) = "BASIC" + credentials
                Dim json As String = proxy.DownloadString(myurl)
                Dim rics As List(Of DB2VSMRIC) = JsonConvert.DeserializeObject(Of List(Of DB2VSMRIC))(json)
                Dim list As List(Of DB2VSMRIC) = rics.Where(Function(p) HasData(p.Cage)).ToList
                If list.Count < 1 Then
                    sErrorDescription = "No VSMRIC w/Cage records found."
                Else

                    dictShipFrom = New Dictionary(Of String, String)
                    dictShipFrom = list.ToDictionary(Function(p) p.Ric, Function(p) p.Dodaac)

                    dictCage = New Dictionary(Of String, String)
                    dictCage = list.ToDictionary(Function(p) p.Ric, Function(p) p.Cage)
                End If
            End Using
        Catch ex As Exception
            sErrorDescription = "Exception in get_vsmric_webApi(), " & ex.Message

            Return False
        Finally

        End Try

        Return True
    End Function

here is the controller method on the web api

[CustomAuthentication]
    [CustomAuthorization("qbert")]
    public class VSMRICController : ApiController
    {
        /// <summary>
        /// Returns all records in the DB2 VSM RIC table
        /// </summary>
        /// <param name="id">The ID of the data.</param>
        public IEnumerable<DB2VSMRIC> Get()
        {
            return DB2VSMRICRepository.getAll();
        }

here is the filter (for authentication)

public class CustomAuthenticationAttribute : Attribute, IAuthenticationFilter
    {
        // the job of the AuthenticateAsync method is to examine the request to see whether it contains
        // the information that is required to identify a user. Information about the request is provided
        // through an instance of the HttpAuthenticationContext class.
        public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
        {
            context.Principal = null;
            AuthenticationHeaderValue authentication = context.Request.Headers.Authorization;
            if (authentication != null && authentication.Scheme == "Basic")
            {
                string[] authData = Encoding.ASCII.GetString(Convert.FromBase64String(
                    authentication.Parameter)).Split(':');
                context.Principal
                    = ApiManager.AuthenticateUser(authData[0], authData[1]);
            }

            if (context.Principal == null)
            {
                context.ErrorResult 
                    = new UnauthorizedResult(new AuthenticationHeaderValue[]{
                        new AuthenticationHeaderValue("Basic")}, context.Request);
                    }
                    return Task.FromResult<object>(null);
            }

        public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
        {
            return Task.FromResult<object>(null);
        }

        public bool AllowMultiple
        {
            get { return false; }
        }

        }

Again I'm fairly confident the Web API is working fine as I can get to JSON by directly navigating to the url and providing credentials in any web browser. I'm thinking I am doing something wrong when I set up the header in the executable. any thoughts? (I am running everything locally via 2 instance of visual studio)


Solution

  • The problem is on the line where you set the basic authentication. It should be

    ... = "Basic " + credentials

    instead of

    ... = "BASIC" + credentials

    Case sensitive and a space.

    Happy coding.