Reputation: 55210
I have a CustomAuthorizeAttribute
class implemented like this.
Public Overrides Sub OnAuthorization(actionContext As HttpActionContext)
If Authorize(actionContext) Then
Return
End If
HandleUnauthorizedRequest(actionContext)
End Sub
Protected Overrides Sub HandleUnauthorizedRequest(actionContext As HttpActionContext)
Dim challengeMessage = New HttpResponseMessage(HttpStatusCode.Unauthorized)
challengeMessage.Headers.Add("WWW-Authenticate", "Basic")
Throw New HttpResponseException(challengeMessage)
End Sub
Private Function Authorize(actionContext As HttpActionContext) As Boolean
Dim isAuthorized = False
Try
'make it true if all goes validations go well
Return True
Catch generatedExceptionName As Exception
End Try
Return isAuthorized
End Function
When authorization fails, it gets hit on Throw New HttpResponseException(challengeMessage)
and never enters the service endpoint as expected. The problem is that my HTTPResponse=200 OK
when I call the API instead of 403 UnAuthorized
. What is wrong with my code?
Update:
<AttributeUsage(AttributeTargets.Class Or AttributeTargets.Method, AllowMultiple:=False, Inherited:=True)>
Public Class CustomAuthorizeAttribute
Inherits AuthorizeAttribute
Upvotes: 1
Views: 759
Reputation: 6023
It looks like the 200 response you receive at the client is because the response is converted to a 302 redirect to the login page (which is what you would likely want if the request was coming from a ASP.NET WebForm or MVC view).
Try editing Startup.Auth.vb
and replace the original app.UseCookieAuthentication
with the following:
app.UseCookieAuthentication(New CookieAuthenticationOptions() With {
.AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
.Provider = New CookieAuthenticationProvider() With {
.OnValidateIdentity = SecurityStampValidator.OnValidateIdentity(Of ApplicationUserManager, ApplicationUser)(
validateInterval:=TimeSpan.FromMinutes(30),
regenerateIdentity:=Function(manager, user) user.GenerateUserIdentityAsync(manager)),
.OnApplyRedirect =
Function(ctx)
If Not IsApiRequest(ctx.Request) Then
ctx.Response.Redirect(ctx.RedirectUri)
End If
End Function
},
.LoginPath = New PathString("/Account/Login")})
which will also require you to add the following function IsApiRequest
at the bottom of Startup.Auth.vb
after the ConfigureAuth
function block and before the End Class
statement:
Private Shared Function IsApiRequest(request As IOwinRequest) As Boolean
Dim apiPath As String = VirtualPathUtility.ToAbsolute("~/api/")
Return request.Uri.LocalPath.StartsWith(apiPath)
End Function
This will avoid the redirect to the login form (for requests that are directed to your WebApi routes) and return the HTTP status 401 that your code is throwing.
More information about this (C# only) can be found in this article:
Upvotes: 3