Forcing IAuthWithRequest.PreAuthenticate to continue with Authenticate endpoint

I am creating a custom auth provider where the Authenticate endpoint accepts a username / password , calls the custom provider, and returns a bearer token.

public object Authenticate(IServiceBase authService, IAuthSession session, Authenticate request)
{
    var loginResult = Login(request.UserName,request.Password);
    session.IsAuthenticated = true;

    return new AuthenticateResponse
    {
        BearerToken = loginResult.AccessToken,
        RefreshToken = loginResult.RefreshToken
    }; 
}

I want to use IAuthWithRequest.PreAuthenticate, which I understand is fired by the [Authorization] attribute, to verify the token (and permissions)

What appears to be happening is PreAuthenticate is being called during Authentication and overrides the authentication result and returning a 401 error.

Know I am missing something but can’t figure it out.

Thanks.

The IAuthWithRequest Auth Providers are supposed to Authenticate “per-request”, i.e. they’re not supposed to call Authenticate Service to Authenticate. They get fired when any Authenticate or RequiredRoles/Permission attributes are used or when trying to access the Users Session.

The preferred approach would be to remove any invalid credentials from the request so it doesn’t get invalidated, e.g. remove the Authorization Header or call /auth/logout to clear an sessions.

Otherwise you can override ApplyPreAuthenticateFilters() in your AppHost and choose when to ignore them, e.g:

public override void ApplyPreAuthenticateFilters(IRequest req, IResponse res)
{
    // Run pre-auth filters when `/auth` is called to check if authenticated
    if (req.Dto is Authenticate authDto && authDto.provider != null)
        return;
    
    base.ApplyPreAuthenticateFilters(req, res);
}

Thanks mythz,

I think I am going to go with a solution that utilizes 2 separate custom IAuthProviders.

  • One that implements IAuthProvider and is responsible for returning tokens (/auth/mycustomerprovider)
  • One that implements IAuthProvider and IAuthResponseFilter. The Authenticate method would throw an error if called directly