Question SecurityProvider

Hi guys,

Been playing with my own cigaret package sized passively cooled (the alu case itsself is the cooler) RK3588 8-core Linux box and cheap domain name. And getting Certbot going, HTTPS works fine. And figure out FTP. Once you know how it works, it's easy as with everything :wink:

Now as I get into security, I have a problem. I use SqlLite/NodeJS. Static SecurityProvider. MacOs. When I put a SecureRestrict server API on a restrictedPage, the logon redirect part works well and opens my login page. Logging in works fine. However when I enter wrong credentials, this opens a sortof Chrome password (modal) dialog (not something that is defined in Wappler!) that won't go away WHATEVER I type, unless I use the cancel button. Therefore the unauthorized redirect does not work. Any ideas?

(Log on/Log off test buttons do work, I made sure of that, as long as correct credentials)

Bas

This sounds like a Basic Auth dialog.

Open browser developer tools, network tools, preserve log, and see the requests, what's happening.

It seems a Chrome thing, when there is a 401/unauth in a header or something like that. But how to get rid of it?

Do you have an unauthorized event on the form?

I entered notifications for all form->ServerConn events: start / done / error / unauth / forbidden / abort / invalid / succes.

When I send the WRONG credentials on button click (send user/pw/keep) to the server the following happens:

  1. start event
  2. done event
  3. abort event
  4. start event
  5. ---> Chrome Login popup opens and asks user/pw. After close popup:
  6. close event
  7. done event
  8. unauth event

In case of correct credentials everything works normal, and no popups.

(I googled that Chrome login popup is opened on 401)

Bas

What about on unauthorized event modifiers -> prevent default?

Not sure I follow...? Modifiers? I have my notifications under (all) form->SC->dynamicEvents.

On your dynamic events panel don't you have a select box that it's called modifiers?
Like this:
image

Not really no, sorry.

I see modifiers in other places, but not under Form->DynamicEvents->ServerConnect->Unauthorized.

Can you show me the code of the form?

Also, are you using local server? Nginx? What server?

Local Server, just localhost:3000, as long as it's development. See code below. In fact it all functionally works, that's important to note. And these are my first steps with secured pages :wink: and this knowlegde will be later needed later for admin pages. Thanks for taking the time.

Bas

<!-- Wappler include head-page="layouts/main" fontawesome_5="cdn" bootstrap5="local" is="dmx-app" id="loguserin" appconnect="local" components="{dmxNotifications:{},dmxBrowser:{}}" -->
<div is="dmx-browser" id="browser1"></div>
<dmx-notifications id="notifies1"></dmx-notifications>
<meta name="ac:route" content="/loguserin">
<div class="container">
    <div class="row">
        <div class="offset-3 col-6">
            <h1>Login details</h1>
        </div>
    </div>
    <div class="row">
        <div class="offset-3 col-6">
            <form id="form1" action="/api/security/loguserin" is="dmx-serverconnect-form" method="post" dmx-on:success="notifies1.success('You are logged in');browser1.goto('/restrictedPage')" dmx-on:start="notifies1.info('Start event')" dmx-on:done="notifies1.info('Done event')" dmx-on:error="notifies1.info('Error event')" dmx-on:forbidden="notifies1.info('Forbidden event')" dmx-on:abort="notifies1.info('Abort event')" dmx-on:invalid="notifies1.info('Invalid event')" dmx-on:unauthorized="notifies1.info('Unauthorized event')">
                <div class="form-group mb-3" id="Group1"> <label for="input1" class="form-label col-form-label-sm">Name</label>
                    <input type="text" class="form-control" id="input1" name="input1" aria-describedby="input1_help" placeholder="Your name here">
                </div>
                <div class="form-group mb-3" id="Group2">
                    <label for="input2" class="form-label col-form-label-sm">Password</label>
                    <input type="password" class="form-control" id="input2" name="input2" aria-describedby="input1_help" placeholder="Password">
                </div>
                <div class="form-group mb-3 row">
                    <label class="form-check-label col-form-label-sm col-6" for="input3">Keep logged in<input class="form-check-input mt-1 ms-2 me-2" type="checkbox" value="" id="input3" name="input3"></label>
                    <div class="form-check">
                    </div>
                </div>
                <button id="btn1" class="btn btn-primary" type="submit" dmx-on:click="form1.submit()">Log in</button>
            </form>
            <form id="form2" method="post" action="/api/security/loguserout" is="dmx-serverconnect-form" dmx-on:success="notifies1.success('You are logged out')">
                <button id="btn2" class="btn bg-body-tertiary mt-5" type="submit">Logout</button>
            </form>
        </div>
    </div>
</div>

Side note: when I use an EXISTING user that is not authorized for the page, then it goes straight to the non authorized page, as designed.

Only in case of a non existing bogus user, the Chrome popop distorts the flow.

Can you try:
dmx-on:unauthorized.prevent="notifies1.info('Unauthorized event')" ?
Maybe worth the try

@Apple is right here, and that's a WWW-Authenticate header on a 401 response that (according to some outside topics like stackoverflow) it's simple to avoid.. maybe @patrick can help on this:

It's ok to change this from lib\auth\provider\:

    unauthorized() {
        if (this.basicAuth) {
            this.app.res.set('WWW-Authenticate', `Basic Realm="${this.basicRealm}"`);
        }
        this.app.res.sendStatus(401);
    }

To this?:

    unauthorized() {
    if (this.basicAuth) {
            this.app.res.set('WWW-Authenticate', `Basic Realm="${this.basicRealm}"`);
    }
    else {
        this.app.res.removeHeader('WWW-Authenticate');
    }
        this.app.res.sendStatus(401);
}

Or this?:

    unauthorized() {
        this.app.res.removeHeader('WWW-Authenticate');
        this.app.res.sendStatus(401);
    }

Ah, thanks a lot for confirming I am not crazy :slight_smile: yes, I have googled likewise posts about the 401 headers. And yes, you have a couple of interesting points to try. Immediately tried the dmx-on:unauthorized.prevent but that didn't change a thing, same behaviour. The other points I will try later. Thanks for your help, much appreciated! Also I wonder: are others not having this issue?

Bas

Hi,

Please show a screenshot of this request and the response, the response headers

Hello all, especially Apple and Franse, the posted code of Franse made it clear that the flag "Basic Auth" which we can set in the Security Provider plays a role in this. And YES, once I cleared that flag (and clearing browser cache) everything works as expected. Thanks a lot for your suggestions and thinking with me (for me? :slight_smile: )

Bas

Glad to hear you found the issue! I didn't even know such flag existed