What are the semantics behind implementing Basic Authentication in AngularJS and Spring Boot?

Currently going through a tutorial that involves AngularJS and Spring Security. The AngularJS navigation controller triggers an authenticate function upon page load:

var authenticate = function(credentials, callback) {

    var headers = credentials ? {
        authorization: "Basic " +
            btoa(credentials.username + ":" + credentials.password)
    } : {};

    $http.get('user', {
        headers: headers
    }).then(function(response) {
        if (response.data.name) {
            $rootScope.authenticated = true;
        } else {
            $rootScope.authenticated = false;
        }
        callback && callback();
    }, function() {
        $rootScope.authenticated = false;
        callback && callback();
    });

}

This function is called with no credentials or callback provided, which means authentication fails on page load. It seems this specific setup is tailored for post-login browser refresh scenarios. So my question is how does the function manage to set $rootScope.authenticated as true after login when the basic authentication headers sent with the ajax request are empty ({}). Does Spring Security allow the request due to the user already being authenticated? Is this linked to setting the Authentication Basic header after form authentication?

Answer №1

The main point being made here is that Spring Boot, specifically Spring Security, generates an HttpSession on the backend after successful authentication.

Essentially, the backend maintains session data (authenticated user) on the server side, making it stateful. The client (in this case, a browser) is recognized by the provided session id.

From a protocol perspective, the authentication process looks like this:

Scenario: Browser sends an HTTP request to the backend. The backend responds with Unauthorized because the client attempts to access a protected resource without the Authorization header.

$ curl -I -H "X-Requested-With:XMLHttpRequest" http://localhost:8080/user

HTTP/1.1 401
Set-Cookie: XSRF-TOKEN=b1137571-5e15-491c-8df5-9db5d34f29a8;path=/
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Transfer-Encoding: chunked

Scenario: Preemptive basic authentication. The backend allows access to the resource and informs the client about the session id.

$ curl -I -H "X-Requested-With:XMLHttpRequest" -H "Authorization:Basic dXNlcjpwYXNzd29yZA==" http://localhost:8080/user

HTTP/1.1 200
Set-Cookie: XSRF-TOKEN=ef72f0b8-4262-4ea2-8a46-5f7e19558079;path=/
Set-Cookie: JSESSIONID=52B61923DE639EE339A653845FBFC5F2;path=/;HttpOnly
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type    : application/json;charset=UTF-8
Content-Length: 343

When the browser includes valid user credentials in the HTTP header Authorization, the backend establishes a new HttpSession and returns an identifier (session id) to the browser.

Set-Cookie: JSESSIONID=52B61923DE639EE339A653845FBFC5F2;path=/;HttpOnly

Subsequently, the browser automatically appends the session id as a cookie to each following HTTP request.

Cookie: JSESSIONID=52B61923DE639EE339A653845FBFC5F2

This mechanism prevents the need for repeated authentication cycles, as long as the session remains active on the server side.

It's important to note that basic authentication is not exclusive to Spring Boot or Angular. It has been a standardized authentication method on the Internet for many years.

However, bear in mind that basic authentication is considered outdated and discouraged in modern web applications.

Will Spring simply allow the request through since the user is already authenticated, possibly due to setting the Authentication Basic header post form authentication?

In the scenario described above, you can understand why an empty headers object does not result in rejection.

  1. The browser (Angular application) proactively sets the Authorization header with valid user credentials and sends an HTTP request to a restricted resource
  2. The server validates the user credentials, creates an HttpSession identified by a session id, and sends it back to the browser
  3. The browser automatically attaches the session id as a cookie to subsequent HTTP requests
  4. The server identifies the HTTP request using the session id and accepts the incoming request

If you configure Spring Security not to create sessions on the server, you can use the following:

.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)

Add this to SecurityConfiguration::configure.

With this configuration, every call to /resource will return an HTTP 401 status because there is no longer a session stored on the server. Now, the Angular application must independently set the Authorization header for each HTTP request.

Although the browser may also automate the inclusion of the Authorization header, it's crucial to remember that basic authentication is strongly advised against in modern web applications.

The purpose of this example is not to provide a step-by-step guide on implementing sign-in functionality with Spring Boot and Angular. Instead, the focus is on moving from basic sign-in methods towards a single sign-on approach based on OAuth2 and Spring within a microservice architecture.

Do not consider the code presented here as definitive or complete.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilize the splice function when resizing the window based on specific breakpoints

On a series of div elements, I have implemented some JS/jQuery code that organizes them by wrapping every three elements in a container with the class .each-row. <div class="element"></div> <div class="element"></div> <div class ...

Difficulty encountered while transmitting JSON data from Express to React

Currently, I am diving into learning express and facing an issue with transmitting JSON data from my express server to my react application. When working on my express server, I initiate an API call to the openweathermap API and then send the obtained JSO ...

Using JavaScript to pass a newly created variable as an argument in a default

Currently, I am developing a node application that heavily utilizes promises. To enhance the readability of my code, I have been removing anonymous functions and storing them in a JavaScript object called "myCallbacks". Here's an example: let myCallb ...

What is the reason for Firefox displaying the "excessive recursion" error message?

I have been working on generating an area Google chart using the code below, but I am running into an issue where Firefox is showing me a "too much recursion" error. The chart currently only has one point for testing purposes. Can anyone provide some gui ...

Verifying the visibility of a div and triggering its closure upon clicking outside of it

Would anyone be able to provide guidance on how I can merge these two scripts into one? Thank you in advance! $(document).ready(function(){ if ($('.myContainer').is(':visible')) { alert('Hello'); } }); $(doc ...

What is the best way to integrate JavaScript and Python for seamless collaboration?

I'm looking to create a bidirectional communication model between JavaScript and Python. The idea is for JavaScript to handle data processing, send it to Python for further processing, and then receive the results back from Python. However, I'm u ...

Issues with transferring object data from JavaScript to a Web API

I am facing issues while attempting to transfer a file from my local machine to SharePoint using JavaScript to ASP.NET MVC Web API call. I continuously encounter errors such as Type error, resource not found, etc. Is there anyone who can provide assistance ...

Footer placement not aligning at the bottom using Bootstrap

I'm having trouble getting my footer to stay at the bottom of my website without it sticking when I scroll. I want it to only appear at the bottom as you scroll down the webpage. Currently, the footer is positioned beneath the content on the webpage. ...

What is the best way to ensure that the Next.js app listener is attached before the 'load' event of the window is triggered?

Recently, I started working with next.js, incorporating TypeScript in version 13.5.5. One crucial requirement for the application is that it must be placed within an iframe and communicate with the parent/host through the window.postMessage event. To achie ...

Enhancing real-time updates with discrete solutions

Currently, I am developing an ASP.NET Core application using Angular as the front end. Let's consider a specific scenario: when a client sends a request, the server has to generate numerous mathematical models and calculate them on certain infrastruct ...

What is the best way to sort ISO DateTime objects that fall outside of a particular time frame?

I'm currently working on a project that involves a list of objects with properties for startTime and endTime, all in ISO format. Here's a snippet of the list: list = [ { startTime: '2022-06-26T10:00:00.000Z', endTime: '2022- ...

Using Express.js to import a SQL file

I am facing challenges while attempting to import an sql file into Express JS. I have tried various codes involving the mssql and fs modules, but none seem to be working as expected. fs.readFile(__dirname +'/database.sql', function (err, sqlFile ...

Automatically increase the height of a text area as you type beyond the maximum width limit

Is there a way to dynamically expand the textarea width as I type beyond its maximum set width without displaying a horizontal scrollbar? Here is the HTML code in its rendered form: <textarea name="CatchPhrase" class="inp ...

"Adding a Dynamic Template to Your AngularJS Directive: A Step-by-Step

I am looking to develop a directive similar to the following: <div ng-refreshing-when="x">Some Content In Here</div> When x is true, I want it to apply specific CSS styles and show a spinner div on top of the content. Then when x is false, I ...

The problem with document.cookie: Functions properly on localhost but displays as empty when hosted on the web

I have been exploring various resources, but none seem to describe my unique situation. Currently, I am in the process of creating a website using ReactJS for the front-end and NodeJS with Express for the back-end. The production versions are accessible a ...

Issue with jQuery click event not firing on multiple buttons with identical names

These are the two buttons that appear multiple times but do not function: <button name='btnEditar' class='btn btn-outline-success me-4' data-bs-toggle='modal' data-bs-target='#staticBackdrop'><i class=&a ...

Unused Vue Chart JS options are neglected

I'm encountering an issue with Vue Chart JS v3.5.1 in my Nuxt JS/Vue project where when trying to pass options as a prop, the chart defaults back to its default settings and does not reflect the changes I made. My project includes multiple files: pl ...

What is the best way to transfer variables defined in PHP to JavaScript?

Can the variables previously defined in JavaScript be used in the line that starts with $sql =? var southWestLat = map.getBounds().getSouthWest().lat(); var southWestLng = map.getBounds().getSouthWest().lng(); var northEastLat = map.getBounds().getNort ...

Fetching dynamic JavaScript generated by PHP

I am creating a lightweight website and I have a piece of javascript code that I want to convert into a module by putting it in a separate file. This way, the code will only be loaded after a specific onClick event occurs. Successfully loading the javascr ...

Can anyone assist with troubleshooting the font size issue for a JavaScript tooltip on Joomla 1.5 with CK Forms?

My Joomla 1.5 site has CK Forms installed and is functioning properly, except for one issue: the tooltip on the captcha is not displaying correctly. It appears in a tiny 1px font size. Even though I have tried debugging using Firebug and confirmed that the ...