Using Angular to interact with an API that requires HTTP Digest Authentication

Creating a web administration panel has been my goal, and I've written a backend controller to assist in delivering the necessary data. However, due to sensitive information, I decided to implement HTTP Digest authentication. When accessing the site via a browser, users can enter their username and password into the browser-generated login screen (standard browser auth box). If the credentials are correct, the data is displayed in JSON format as it functions as a RESTful API.

I have attempted to implement this feature in Angular for days without success. While I came across blog posts with instructions, they only covered HTTP Basic authentication, which is not what I'm looking for.

Trying to retrieve the realm/nonce and other details by sending a GET request to the specified URL has proven unsuccessful. Every attempt results in receiving the "WWW-Authenticate" header along with an error message (401 unauthorized), making it impossible to read the required information for further steps involving md5(username:realm:password) encryption. Reading the WWW-Authenticate header or utilizing X-headername has also proven challenging.

sendCredentials()
{
console.log("Send cred");
this.http.get(this.targetUrl, {observe: 'response'}).subscribe(res => {
  console.log(res.headers.get('WWW-Authenticate'));
}) 
 //Normally i want to set the nonce here and then i 
 //want to generate my md5 Value to send this in the next step with a new http get request)
}

In search of a solution to this issue, Google hasn't been much help to me. Any assistance would be greatly appreciated!

Answer №1

If anyone is curious about my approach:

I created a custom class for implementing digest authentication:

If anyone is interested in the details (it's functional for me, but not fully compliant with the HTTP Digest Authentication Standard): -> The NC and Nonce are sent on the initial step by my Server, while the username and password are retrieved from an HTML form

    export class AuthComponent {

  loggedIn: string = "false";
  sessionID: string = "n.s";
  username = "";
  password = "";
  targetUrl: string = "<<targetUrl>>";

  md5gen: Md5 = new Md5();
  nc = "<<your nc>>";
  nonce = "";
  opaque = "";
  qop = "";
  realm = "";
  uri = "";
  cNonce = '<<your nonce>>';

  constructor(private http: HttpClient, private router: Router, private toast: HotToastService) 
  {
    this.http.get<authModel>(this.targetUrl).subscribe(res =>
      {
          console.log(res);
          this.loggedIn = res.loggedIn;
          this.nc = res.counter;
          this.nonce = res.nonce;
          this.opaque = res.opaque;
          this.qop = res.qop;
          this.realm = res.realm;
          this.uri = res.uri;
          this.username = res.username;
      })
   }


   sendCredentials() {    
    //Create needed Hashes or auth
    this.md5gen.start();
    var A1 = this.md5gen.appendStr(this.username + ":" + this.realm + ":" + this.password).end();
    
    this.md5gen.start();
    var A2 = this.md5gen.appendStr("GET:" + this.uri).end();

    var stuff = A1 + ":" + this.nonce + ":" + this.nc + ":" + this.cNonce + ":" + this.qop + ":" + A2;
    
    this.md5gen.start();
    var resp =  this.md5gen.appendStr(stuff).end();

    /*
    console.log("Response: " + resp);
    console.log(this.password + " -> " + A1);
    console.log(resp);
    console.log("---------------");
    console.log("RQ-Method: " + "GET", 0);
    console.log("RQ-Uri: " + res.uri, 0);
    console.log("RQ-NONCE: " + res.nonce, 0 );
    console.log("RQ-NC: " + this.nc, 0 );
    console.log("RQ-CNONCE: " + cNonce, 0 );
    console.log("RQ-QOP: " + res.qop, 0 );
    */

    var header = 
    {
      headers: new HttpHeaders(
        {
          'Content-Type': 'application/json; charset=utf-8',
          'requestModule' : 'auth-Module',
          'Authorization': 'Digest username="' + this.username + '", realm="' + this.realm + '", nonce="' + this.nonce + '", uri="' + this.uri + '", response="' + resp + '", opaque="' + this.opaque + '", qop=' + this.qop + ', nc=' + this.nc + ', cnonce="' + this.cNonce + '"',
        }
      )
    }

    this.http.get<boolean>(this.targetUrl + "/auth", header).subscribe(
      res => {
        if(res == true)
        {
          successToast(this.toast, 'Successfully loggedIn! - Welcome ' + this.username);
          console.log("Logged In!");
          this.router.navigate(['/']);
        }
        else
        {
          if(res == null)
          {
            console.log("No Data!");

          }
          else
          {
            console.log("Wrong User/Pass!");
          }
          errorToast(this.toast, 'Wrong password or username!');
        }
      },
      err => console.log('HTTP Error', err),
      () => console.log('HTTP request completed.')
    )
      }

  
    }

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

Personalized webpage displaying HTTP errors

When working in asp.net, I have the ability to set up a custom error page using the following syntax: <configuration> <system.web> <customErrors mode="On"> <error statusCode="404" redirect="/servererrors/40 ...

Discover the fundamentals of integrating scripts into Angular 2 by utilizing Node.js and npm alongside ASP.NET Core 1

After installing asp.net core1, I was introduced to npm, bower, and nodejs. After much research, I decided to start using angular2. However, my lack of experience with tools like gulp and grunt is posing a problem. While I understand their purpose and func ...

Binding an ID to an <ion-textarea> in Ionic 3

Can an ID be assigned to an ion-textarea? For example: <ion-textarea placeholder="Enter your thoughts" id="thoughtsBox"></ion-textarea> Thank you very much ...

Angular 4 Universal - Utilizing Google Analytics with Solely Client Side Code

Currently, I am in the process of transitioning our website from a static Single Page Application to Angular Universal Rendered Server Side. However, I have encountered an issue with integrating Google Analytics. In my SPA, I typically define GA in the in ...

Get the latest version of Node Stream using Angular 2

I am currently working on generating a PDF file on the server side using node.js and then downloading it on the client side with Angular 4. It's similar to how Google Drive allows you to download files as PDFs. Here is an example of the Node JS code ...

The interface "App" is not properly implemented by the class "FirebaseApp" causing an error

My attempt to set up AngularCLI and Firebase led to encountering this issue... How should I proceed? ERROR in node_modules/angularfire2/app/firebase.app.module.d.ts(5,22): error TS2420: Class 'FirebaseApp' does not properly implement interface ...

The system was expecting a stream but received a value of 'undefined'

I've been attempting to make chained http requests using Rxjs, but encountering a frustrating error... Error: Uncaught (in promise): TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, ...

The variable 'React' is defined but not utilized in the code

Here's the code snippet in question: // tslint:disable import * as React from 'react'; import { Input, InputProps } from '../atoms/Input/Input'; import { FormControl } from '../hoc/FormControl/FormControl'; export const ...

Developing an angular 6 web client for GRPC

Having experience with grpc using a .net client and a Java grpc server, how can I integrate a grpc web client on Angular 6 using TypeScript? Additionally, what is the process for creating proto files and their typings for TypeScript? I have been referenci ...

What are some ways I can incorporate PrimeNG components into my Ionic 4 project?

Exploring the integration of PrimeNG components in an Ionic 4 application is my current project. The initial steps I took included creating a blank Ionic 4 app: ionic start myApp blank Afterwards, I proceeded to download PrimeNG into the project: npm ...

Continuing the operation following the closure of a modal

Exploring the unknown territory of transitioning from Ionic 1 to Ionic 4 brings about its fair share of challenges. In my previous Ionic 1 projects, I heavily relied on functions incorporating Ionic popups for seamless operations. Referring to a sample co ...

Is it possible to dynamically modify the custom CSS property --background of ion-item in Ionic 4?

Is there a way to dynamically set background colors? I want to display ion-item elements based on an array, with each item having a different background color derived from the array values. Any suggestions? I attempted this approach, but it doesn't s ...

Utilizing observable services efficiently in Angular

I have developed a unique service for facilitating communication between various components and modules. @Injectable({ providedIn: 'root' }) export class CommunicationService<T> { private emitChanges = new Subject<T>(); changes ...

Encountered an issue while setting up MDBoostrap Pro using oauth authentication in docker-compose

Working on deploying an application developed with MDBootstrap Pro, installed via npm and using oauth2 authentication. In the project directory, installation is done by running this command: npm install git+https://oauth2:<a href="/cdn-cgi/l/email-prote ...

What is the best way to incorporate padding into an Angular mat tooltip?

I've been attempting to enhance the appearance of the tooltip dialog window by adding padding. While adjusting the width and background color was successful, I'm encountering difficulties when it comes to styling the padding: https://i.sstatic.ne ...

What causes the child component to be rendered four times when the parent component is first loaded?

I have been facing an interesting scenario with my parent and child components. Typically, change detection is triggered by events like HTTP requests or timers such as setInterval and setTimeout. However, in this particular case, I am not utilizing any of ...

Unable to utilize React Icons component as an object value in typescript

Currently, as I develop my personal website using typescript and react, I am faced with an issue in the footer section. I have an array of objects with url and icon properties that I map through to display different icons on each iteration. Initially, this ...

Is it possible to configure TypeScript (or a tool similar to ESLint) to throw an error when a library returns undefined?

Currently working with knex and sometimes it returns any, for example when forgetting to specify the table type in the query. Are there any recommended tools available to avoid this issue, ensuring all knex queries are typed properly? ...

Guide to importing a markdown document into Next.js

Trying to showcase pure markdown on my NextJS Typescript page has been a challenge. I attempted the following: import React, { useState, useEffect } from "react"; import markdown from "./assets/1.md"; const Post1 = () => { return ...

The search for a supporting object '[object Object]' of type 'object' was unsuccessful. NgFor is limited to binding to Iterables like Arrays

import { HttpClient } from '@angular/common/http'; import { Component, OnInit} from '@angular/core'; import { AnyArray } from 'mongoose'; import { DataService } from '../../services/data.service'; @Component({ ...