UI BasicAuth in Login

Hello,
Not sure where to categorize this one.

I’m using custom Basic, custom Credentials and JWT authentication:

public class ConfigureAuth : IHostingStartup
{
    public void Configure(IWebHostBuilder builder) => builder
        .ConfigureServices(services => {
            //services.AddSingleton<ICacheClient>(new MemoryCacheClient()); //Store User Sessions in Memory Cache (default)
        })
        .ConfigureAppHost(appHost => 
            appHost.Plugins.Add(new AuthFeature(() => 
                    new MyUserSession(),
                    new IAuthProvider[]
                    {
                        new MyBasicAuthProvider(),
                        new MyCredentialsAuthProvider(),
                        new JwtAuthProvider(appHost.AppSettings)
                        {
                            UseTokenCookie = false,
                            AuthKeyBase64 = appHost.AppSettings.GetString("AuthKeyBase64"),
                            ExpireTokensIn = TimeSpan.FromHours(12)
                        },
                    })
            { 
                IncludeDefaultLogin = false,
                IncludeAssignRoleServices = false, 
                IncludeRegistrationService = false
            }));
}

When i go to /ui, I’m getting only Credentials and JWT as selection for login.
If you look a bit closer, JWT button is rounded on the right side corners while Credentials button have squared left side cornes, as it’s missing “Basic” button before it.

image

Consequence of this is if I do not explicitly select “Credentials”, form is asking me to perform Basic auth after clicking Login, and then it let’s me move on:

However, if I select “Credentials” before login it does add ?provider=credentials to url and it works fine.

It appears that Basic auth selection is missing from login, and also missing ?provider=basic from URL. When added manually in url it works.
My basic auth signature:

public class MyBasicAuthProvider: BasicAuthProvider

Do I have to implement something else for it to appear on UI login?

Is it your Custom MyBasicAuthProvider, i.e. does it work when you use BasicAuthProvider?

No. Here are all usecases:

Basic only:

new IAuthProvider[]
                    {
                        new BasicAuthProvider()
}

Basic and Credentials:

new IAuthProvider[]
                    {
                        new BasicAuthProvider(),
                        new CredentialsAuthProvider(),
}

Basic, Credentials and JWT:

new IAuthProvider[]
                    {
                        new BasicAuthProvider(),
                        new CredentialsAuthProvider(),
                        new JwtAuthProvider(appHost.AppSettings) { AuthKeyBase64 = appHost.AppSettings.GetString("AuthKeyBase64") },
}

Credentials and JWT:

new IAuthProvider[]
                    {
                        new CredentialsAuthProvider(),
                        new JwtAuthProvider(appHost.AppSettings) { AuthKeyBase64 = appHost.AppSettings.GetString("AuthKeyBase64") },
}


Note round edges when basic is excluded.

JWT only:

new IAuthProvider[]
                    {
                        new JwtAuthProvider(appHost.AppSettings) { AuthKeyBase64 = appHost.AppSettings.GetString("AuthKeyBase64") },
}

The Browser Basic Auth Popup is odd, are you using IIS with Windows Basic Authentication? Can you provide the HTTP Response Headers of the page causing the modal dialog.

Ok it looks like the BasicAuthProvider isn’t showing a Basic tab in the Sign In page? Not sure why that would be as it’s showing up for me, are you using the latest v6.11 release?

No, this is self-hosted app. I can’t get Basic tab in any case.

HttpResponse for /ui:

Filled form, popup appears:

I’m on 6.11.0

Created new project with x new selfhost test

I’m getting “Basic” tab and popup also.

I will try to disable customizations one by one to find cause of tab not showing.

There must be a 401 challenge response with WWW-Authenticate: Basic... to force the Browser’s Basic Auth modal dialog, I can’t repro it but you can try moving BasicAuthProvider so it’s not the first AuthProvider registered in AuthFeature plugin.

If it doesn’t prevent the modal dialog can you post the response of the HTTP Response with the WWW-Authenticate: Basic.. response header.

Yes, there is 401. It is strange that it does not stops in breakpoint in my TryAuthenticate method in first try.

RAW request:

POST http://localhost:5001/api/Authenticate HTTP/1.1
Host: localhost:5001
Connection: keep-alive
Content-Length: 91
sec-ch-ua: "Opera";v="103", "Not;A=Brand";v="8", "Chromium";v="117"
sec-ch-ua-platform: "Windows"
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 OPR/103.0.0.0
content-type: application/json
Accept: */*
Origin: http://localhost:5001
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost:5001/api-explorer
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: ss-id=4htuXa7dCzydsxMa28Pj; ss-pid=tzqVJ3Mt3JkDv55Ug7yx

{"UserName":"admin","Password":"admin","RememberMe":"","BearerToken":"","provider":"basic"}

In BasicAuthProvider.cs Im getting that userPass is null:

Still haven’t manage to make Basic tab appear.

I can’t repro it but you can try moving BasicAuthProvider so it’s not the first AuthProvider registered in AuthFeature plugin.

Tried, no effect.

One more thing, In my basic auth provider I’ve overrided only
public override async Task<bool> TryAuthenticateAsync(IServiceBase authService, string userName, string password, CancellationToken token = new CancellationToken())

public class MyBasicAuthProvider: BasicAuthProvider
{
    public override async Task<bool> TryAuthenticateAsync(IServiceBase authService, string userName, string password, CancellationToken token = new CancellationToken())
    {
        using var db = await HostContext.TryResolve<IDbConnectionFactory>().OpenAsync(token);

        //get user from db and check uname/pass

        var session = (MyUserSession)await authService.GetSessionAsync(token: token);
        //fill session data from db

        return true;
    }
}

Am I missing something?

The BasicAuthProvider is for enabling authenticating via HTTP Basic Auth, i.e. Authentication is per-request which should always be included with the Authorization: Basic ... HTTP Header when accessing the protected API directly.

It’s not for authenticating with the /api/Authenticate API, that’s what the Credentials AuthProvider is for.

So it’s not being used properly atm, what are you doing that requires HTTP Basic Auth?

Looking at the code, it doesn’t look like HTTP Basic Auth is supported by the built-in UIs and Sign In components, looking to see if it’s possible to support it.

1 Like

There is third party client that will consume my services and it supports basic auth only.

When I enabled it, it made me a problem because /ui wasn’t showing Basic tab, but it was defaulting to it and it started popping login dialog, which is why I have initiaded this post.
It’s only use is because third party client cannot use anything else. It will be closed system but conditions are such.

When I disable BasicAuth it works as expected.

You should order the Auth Providers in order of usage preference, i.e. put CredentialsAuthProvider first if that’s the preferred Auth Provider.

I’ve updated the built-in UIs to make use of Basic Auth which should now configure requests to use Basic Auth Authorization HTTP Header when making requests which is available in the latest v6.11.1+ that’s now available in the latest Pre-Release packages.

But I don’t know why the Basic tab isn’t showing up, I’ll likely need a repro to identify what’s preventing it from being displayed.

1 Like

Placing BasicAuth to last place solved the issue of popping auth dialog.

Repro for missing “Basic” tab available here (WeTransfer)

Is feedz.io preffered over MyGet for ServiceStack?

Yeah, you can use feedz or GitHub.