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)
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.