Explore all Authorization open source software, libraries, packages, source code, cloud functions and APIs.

Popular New Releases in Authorization

casbin

v2.44.2

laravel-permission

5.5.2

RxPermissions

v0.12

opa

v0.39.0

Dexter

Fix duplicated permission report

Popular Libraries in Authorization

casbin

by casbin doticongodoticon

star image 11753 doticonApache-2.0

An authorization library that supports access control models like ACL, RBAC, ABAC in Golang

laravel-permission

by spatie doticonphpdoticon

star image 10248 doticonMIT

Associate users with roles and permissions

RxPermissions

by tbruyelle doticonjavadoticon

star image 10169 doticonApache-2.0

Android runtime permissions powered by RxJava2

opa

by open-policy-agent doticongodoticon

star image 6500 doticonApache-2.0

An open source, general-purpose policy engine.

cancan

by ryanb doticonrubydoticon

star image 6313 doticonMIT

Authorization Gem for Ruby on Rails.

entrust

by Zizaco doticonphpdoticon

star image 6180 doticonMIT

Role-based Permissions for Laravel 5

global-state

by sebastianbergmann doticonphpdoticon

star image 6115 doticonNOASSERTION

Snapshotting of global state, factored out of PHPUnit into a stand-alone component

Dexter

by Karumi doticonjavadoticon

star image 4982 doticonApache-2.0

Android library that simplifies the process of requesting permissions at runtime.

PermissionScope

by nickoneill doticonswiftdoticon

star image 4909 doticonMIT

Intelligent iOS permissions UI and unified API

Trending New libraries in Authorization

oso

by osohq doticonrustdoticon

star image 2362 doticonApache-2.0

Oso is a batteries-included framework for building authorization in your application.

the-bastion

by ovh doticonperldoticon

star image 1052 doticonNOASSERTION

Authentication, authorization, traceability and auditability for SSH accesses.

cerbos

by cerbos doticongodoticon

star image 341 doticonApache-2.0

Cerbos is the open core, language-agnostic, scalable authorization solution that makes user permissions and authorization simple to implement and manage by writing context-aware access control policies for your application resources.

AuthPermissions.AspNetCore

by JonPSmith doticoncsharpdoticon

star image 257 doticonMIT

This library provides extra authorization and multi-tenant features to an ASP.NET Core application.

caddy-authorize

by greenpau doticongodoticon

star image 227 doticonApache-2.0

Authorization Plugin for Caddy v2 (JWT/PASETO)

hierarchical-namespaces

by kubernetes-sigs doticongodoticon

star image 209 doticonApache-2.0

Home of the Hierarchical Namespace Controller (HNC). Adds hierarchical policies and delegated creation to Kubernetes namespaces for improved in-cluster multitenancy.

trasa

by seknox doticongodoticon

star image 201 doticonMPL-2.0

Zero Trust Service Access

caddy-auth-jwt

by greenpau doticongodoticon

star image 189 doticonApache-2.0

JWT Authorization Plugin for Caddy v2

casbin-cpp

by casbin doticonc++doticon

star image 168 doticonApache-2.0

An authorization library that supports access control models like ACL, RBAC, ABAC in C/C++

Top Authors in Authorization

1

casbin

41 Libraries

star icon20625

2

php-casbin

19 Libraries

star icon1645

3

node-casbin

9 Libraries

star icon241

4

yahoojapan

8 Libraries

star icon66

5

open-policy-agent

6 Libraries

star icon9383

6

osohq

6 Libraries

star icon2424

7

pycasbin

6 Libraries

star icon205

8

gulp-bem

5 Libraries

star icon20

9

xyproto

5 Libraries

star icon614

10

psecio

5 Libraries

star icon434

1

41 Libraries

star icon20625

2

19 Libraries

star icon1645

3

9 Libraries

star icon241

4

8 Libraries

star icon66

5

6 Libraries

star icon9383

6

6 Libraries

star icon2424

7

6 Libraries

star icon205

8

5 Libraries

star icon20

9

5 Libraries

star icon614

10

5 Libraries

star icon434

Trending Kits in Authorization

No Trending Kits are available at this moment for Authorization

Trending Discussions on Authorization

Instead change the require of index.js, to a dynamic import() which is available in all CommonJS modules

Google Colab - Google Drive can´t be mounted anymore - Browser Popup (Google Drive for Desktop) instead of Link in the code output for authorization

Google OAuth 2.0 failing with Error 400: invalid_request for some client_id, but works well for others in the same project

Pushing from Eclipse to my GitHub repository via HTTPS stopped working: "git-receive-pack not permitted" error

How to use scoped APIs with (GSI) Google Identity Services

Any POST or GET requests from the Revue API return 401

Android Studio Disconnects From Physical Device

throwError(error) is now deprecated, but there is no new Error(HttpErrorResponse)

Google Colab drive mount (with underscore) is not working

Save authenticated users to database coming from Azure AD

QUESTION

Instead change the require of index.js, to a dynamic import() which is available in all CommonJS modules

Asked 2022-Apr-05 at 06:25

Trying to work with node/javascript/nfts, I am a noob and followed along a tutorial, but I get this error:

1error [ERR_REQUIRE_ESM]: require() of ES Module [...] is not supported. Instead change the require of index.js [ in my file...]  to a dynamic import() which is available in all CommonJS modules
2

My understanding is that they've updated the node file, so i need a different code than that in the tutorial, but i don't know which one I'm supposed to change, where and to what. Please be as specific as you can

1error [ERR_REQUIRE_ESM]: require() of ES Module [...] is not supported. Instead change the require of index.js [ in my file...]  to a dynamic import() which is available in all CommonJS modules
2const FormData = require('form-data');
3const fetch = require('node-fetch');
4const path = require("path")
5const basePath = process.cwd();
6const fs = require("fs");
7
8fs.readdirSync(`${basePath}/build/images`).foreach(file).forEach(file => {
9    const formData = new FormData();
10    const fileStream = fs.createReadStream(`${basePath}/build/images/${file}`);
11    formData.append('file',fileStream);
12
13    let url = 'https://api.nftport.xyz/v0/files';
14
15    let options = {
16      method: 'POST',
17      headers: {
18        Authorization: '[...]',
19      },
20      body: formData
21    };
22    
23    fetch(url, options)
24      .then(res => res.json())
25      .then(json => {
26       const fileName = path.parse(json.file_name).name;
27       let rawdata = fs.readFileSync(`${basePath}/build/json/${fileName}.json`);
28       let metaData = JSON.parse(rawdata);
29
30       metaData.file_url = json.ipfs_url;
31
32       fs.writeFileSync(`${basePath}/build/json${fileName}.json`, JSON.stringify(metaData, null, 2));
33
34       console.log(`${json.file_name} uploaded & ${fileName}.json updated!`);
35      })
36      .catch(err => console.error('error:' + err));
37})
38
39

ANSWER

Answered 2021-Dec-31 at 10:07

It is because of the node-fetch package. As recent versions of this package only support ESM, you have to downgrade it to an older version node-fetch@2.6.1 or lower.

npm i node-fetch@2.6.1

This should solve the issue.

Source https://stackoverflow.com/questions/70541068

QUESTION

Google Colab - Google Drive can´t be mounted anymore - Browser Popup (Google Drive for Desktop) instead of Link in the code output for authorization

Asked 2022-Apr-01 at 09:48

Since yesterday I have had the problem that I can no longer mount my Google account. Normally, when I run it, I get a link to authorize myself with. Now, when the code is executed, an extra browser window is opened where I should authorize myself. But if I do it over it, it doesn't work. Do you know why it can be that this authorization link is suddenly no longer shown? Any security setting maybe? I've tried several browsers.

EDIT: With the new authorization popup it works if i mount the google drive from the same google account like colab. But the problem is that my main google drive is on another account than Google Colab. With the link it used to work without any problems earlier...

EDIT 2: I have now solved it in such a way that I have shared the required folder for my other account and can now access it via my Colab Google Drive account. But I still didn't manage to get the link back.

After the code execution and authorization with the new popup i get this error message on Google Colab:

MessageError Traceback (most recent call last) in () 1 #Connect Google Drive 2 from google.colab import drive ----> 3 drive.mount('/gdrive')

3 frames /usr/local/lib/python3.7/dist-packages/google/colab/_message.py in read_reply_from_input(message_id, timeout_sec) 104 reply.get('colab_msg_id') == message_id): 105 if 'error' in reply: --> 106 raise MessageError(reply['error']) 107 return reply.get('data', None) 108

MessageError: Error: credential propagation was unsuccessful

I use this code:

1#Connect Google Drive
2from google.colab import drive
3drive.mount('/gdrive')
4

ANSWER

Answered 2021-Nov-07 at 20:45

This is a problem with Google Colab Pro. I have a Pro account as well as a normal account. My normal account works as intended (with the link) whereas my Pro account has the pop-up window that gives me the same error as OP.

Source https://stackoverflow.com/questions/69822304

QUESTION

Google OAuth 2.0 failing with Error 400: invalid_request for some client_id, but works well for others in the same project

Asked 2022-Mar-30 at 14:21

We have some apps (or maybe we should call them a handful of scripts) that use Google APIs to facilitate some administrative tasks. Recently, after making another client_id in the same project, I started getting an error message similar to the one described in localhost redirect_uri does not work for Google Oauth2 (results in 400: invalid_request error). I.e.,

Error 400: invalid_request

You can't sign in to this app because it doesn't comply with Google's OAuth 2.0 policy for keeping apps secure.

You can let the app developer know that this app doesn't comply with one or more Google validation rules.

Request details:

The content in this section has been provided by the app developer. This content has not been reviewed or verified by Google.

If you’re the app developer, make sure that these request details comply with Google policies.

redirect_uri: urn:ietf:wg:oauth:2.0:oob

How do I get through this error? It is important to note that:

  • The OAuth consent screen for this project is marked as "Internal". Therefore any mentions of Google review of the project, or publishing status are irrelevant
  • I do have "Trust internal, domain-owned apps" enabled for the domain
  • Another client id in the same project works and there are no obvious differences between the client IDs - they are both "Desktop" type which only gives me a Client ID and Client secret that are different
  • This is a command line script, so I use the "copy/paste" verification method as documented here hence the urn:ietf:wg:oauth:2.0:oob redirect URI (copy/paste is the only friendly way to run this on a headless machine which has no browser).
  • I was able to reproduce the same problem in a dev domain. I have three client ids. The oldest one is from January 2021, another one from December 2021, and one I created today - March 2022. Of those, only the December 2021 works and lets me choose which account to authenticate with before it either accepts it or rejects it with "Error 403: org_internal" (this is expected). The other two give me an "Error 400: invalid_request" and do not even let me choose the "internal" account. Here are the URLs generated by my app (I use the ruby google client APIs) and the only difference between them is the client_id - January 2021, December 2021, March 2022.

Here is the part of the code around the authorization flow, and the URLs for the different client IDs are what was produced on the $stderr.puts url line. It is pretty much the same thing as documented in the official example here (version as of this writing).

1
2OOB_URI = 'urn:ietf:wg:oauth:2.0:oob'
3
4def user_credentials_for(scope, user_id = 'default')
5    token_store = Google::Auth::Stores::FileTokenStore.new(:file => token_store_path)
6    authorizer = Google::Auth::UserAuthorizer.new(client_id, scope, token_store)
7    credentials = authorizer.get_credentials(user_id)
8    if credentials.nil?
9        url = authorizer.get_authorization_url(base_url: OOB_URI)
10        $stderr.puts ""
11        $stderr.puts "-----------------------------------------------"
12        $stderr.puts "Requesting authorization for '#{user_id}'"
13        $stderr.puts "Open the following URL in your browser and authorize the application."
14        $stderr.puts url
15        code = $stdin.readline.chomp
16        $stderr.puts "-----------------------------------------------"
17        credentials = authorizer.get_and_store_credentials_from_code(
18            user_id: user_id, code: code, base_url: OOB_URI)
19    end
20    credentials
21end
22                                                                                                                                          
23

ANSWER

Answered 2022-Mar-02 at 07:56

steps.oauth.v2.invalid_request 400 This error name is used for multiple different kinds of errors, typically for missing or incorrect parameters sent in the request. If is set to false, use fault variables (described below) to retrieve details about the error, such as the fault name and cause.

  • GenerateAccessToken GenerateAuthorizationCode
  • GenerateAccessTokenImplicitGrant
  • RefreshAccessToken

Google Oauth Policy

Source https://stackoverflow.com/questions/71318804

QUESTION

Pushing from Eclipse to my GitHub repository via HTTPS stopped working: "git-receive-pack not permitted" error

Asked 2022-Mar-25 at 03:18

I recently did a push to my GitHub repository for a few weeks ago. I got a main from GitHub that GitHub is soon quitting regular authorization and going to replace it with another authorization method.

So today I push a new update to my GitHub repository and got the message:

1git-receive-pack not permitted
2

That's leads to two questions:

  1. Has EGit stopped working now?
  2. I have Eclipse 2021-03, how can I fix this issue so I can do a push?

ANSWER

Answered 2021-Aug-20 at 07:52

Since August 13, 2021, GitHub does not support authentication via HTTPS with your GitHub account password for security reasons anymore. Instead, in Eclipse, when pushing to a GitHub repository or when fetching from a private repository, you will get a git-upload-pack not permitted on 'https://github.com...' error.

As solution, use either

  • a GitHub specific Personal access tokens as password instead of your previously used GitHub account password or
  • SSH with an SSH key of which the private and public key is on your local machine and configured in Eclipse and the public key is uploaded to your GitHub account instead.
Personal access token (GitHub specific)

enter image description here

  1. Go to your GitHub account to Settings > Developer settings > Personal access tokens website:
    1. Click the Generate new token button in the upper right
      • Enter a Note, e.g. GitHub repo token
      • Choose Expiration, e.g. No expiration
      • Tick the checkbox repo
    2. Click the Generate token button at the bottom
    3. Copy the generated token to the clipboard
  2. In Eclipse, in the Git Repositories view:
    1. Right-click the Remotes sub-node for GitHub (origin or the name you have chosen when you have cloned the repository) and choose Configure Push...
    2. Click the Change... button to change the URI in the upper right
    3. Replace the password with with the copied generated GitHub token
    4. Click Finish and Save to apply the changes
SSH
  1. Create an SSH key (skip this step when you already have one):
    1. In Eclipse, in the preferences General > Network Connections > SSH2 tab Key Management hit the Generate RSA Key... button
    2. Hit Save Private Key... and choose a location, preferably the subfolder .ssh of your user home directory
  2. Upload public key to your GitHub account:
    1. For a new created key, copy the string shown in the Key Management tab to the clipboard; for an existing key add it in the preferences General > Network Connections > SSH2 tab General and copy the content of the public key file <name>.pub
    2. Go to your GitHub account settings to the SSH and GPG keys section and hit the New SSH key button
    3. Paste the copied public key into the Key field
  3. Change HTTPS to SSH URLs of already cloned repositories:
    1. In Eclipse, in the Git Repositories view right-click the repository and choose Properties and click the Open button
    2. In the text editor of the config file change the remote URL as follows:

      HTTPS (old; does not work for push anymore):
1git-receive-pack not permitted
2url = <b>https</b><b>://</b>github.com<b>/</b>&lt;username&gt;/&lt;repo&gt;.git

SSH (new):
1git-receive-pack not permitted
2url = <b>https</b><b>://</b>github.com<b>/</b>&lt;username&gt;/&lt;repo&gt;.giturl = <b>git@</b>github.com<b>:</b>&lt;username&gt;/&lt;repo&gt;.git

Source https://stackoverflow.com/questions/68790276

QUESTION

How to use scoped APIs with (GSI) Google Identity Services

Asked 2022-Mar-17 at 00:31

Google recently sent me an email with the following:

One or more of your web applications uses the legacy Google Sign-In JavaScript library. Please migrate your project(s) to the new Google Identity Services SDK before March 31, 2023

The project in question uses the Google Drive API alongside the now legacy authentication client.

The table on the migration page (https://developers.google.com/identity/gsi/web/guides/migration) says:

Old New Notes
JavaScript libraries
apis.google.com/js/platform.js accounts.google.com/gsi/client Replace old with new.
apis.google.com/js/api.js accounts.google.com/gsi/client Replace old with new.

I was currently using gapi on the front-end to perform authorization which is loaded from apis.google.com/js/api.js. According to the table I would need to replace it with the new library.

I've tried the following to authenticate and authorize in the same manner that I used to do with gapi:

1window.google.accounts.id.initialize({
2  client_id: GOOGLE_CLIENT_ID,
3  callback: console.log,
4  scope: &quot;https://www.googleapis.com/auth/drive.file&quot;,
5  discoveryDocs: [&quot;https://www.googleapis.com/discovery/v1/apis/drive/v3/rest&quot;],
6});
7
8window.google.accounts.id.renderButton(ref.current, {
9  size: &quot;medium&quot;,
10  type: &quot;standard&quot;,
11});
12
13

However, when I try to authenticate with the Google Sign In button, the scope field is not respected and it does not ask the user to authorize the requested scopes. It also doesn't return any form of access token in the Credential Response in the callback.

I'm not sure how else to authorize using the new library.

ANSWER

Answered 2021-Aug-26 at 19:19

In the new Gooogle Identity Services, the authentication moment and the authorization moment are separated. This means, GIS provides different APIs for websites to call on these two different moments. You cannot combine them together in one API call (and UX flow) any more.

In the authenction moment, users just sign in or sign up into your website (by leveraging the information shared by Google). The only decision users need to make is whether they want to sign in (or sign-up). No authorization-related decison need to make at this point.

In the authentication moment, users will see consistent One Tap or button UX across all websites (since the same scopes are requested implicitly). Consistence leads to more smoothly UX, which may further lead to more usage. With the consitent and optimized authentication UX (across all websites), users will have a better experience with federated sign-in.

After users sign-in, when you really want to load some data from a Google data service, you can call GIS authorization API to trigger an UX flow to allow end users to grant the permission. That's the authorization moment.

Currently (August 2021), only authentication API has been published. If your website only cares about authentication, you can migrate to GIS now. If you also need the authorization API, you have to wait for further notice.

Source https://stackoverflow.com/questions/68815693

QUESTION

Any POST or GET requests from the Revue API return 401

Asked 2022-Mar-08 at 13:55

I am trying to add subscribers to my newsletter using the Revue api. According to the documentation, I need to add a header called 'Authorization' and value 'Token MY-TOKEN' in my requests.

In order to test out the API I am using Postman as seen in the screenshot below:

enter image description here

Any request I do to any url, ends up with a 401.

What am I missing here? The token value is copy pasted from the bottom of https://www.getrevue.co/app/integrations ('Your API key is xyz') as the documentation mentions. Double checked that there are no extra spaces added.

ANSWER

Answered 2022-Jan-06 at 07:43

If you have the following when you log in to Revue

"We are reviewing your account."

You will not be able to make API calls and will get a 401.

I've talked to support on the issue and unfortunately, it's undocumented at the moment.

getrevue dashboard "we are reviewing your account"

Took nearly a week for me to get reviewed but it's working fine now. It is at the end of the Christmas period so I am hoping they are only temporarily that slow at reviewing accounts.

Source https://stackoverflow.com/questions/70556228

QUESTION

Android Studio Disconnects From Physical Device

Asked 2022-Mar-06 at 15:11

Android Studio Bumblebee (2021.1.1) was released stably on 25 January 2022 bundled with a new Device Manager (accompanying new support for Android 11+ device debugging over WIFI). I jumped on this stable release, updating from Android Studio Arctic Fox (2020.3.1 Patch 4).

Unfortunately however, since updating, physical devices/handsets don't remain connected to Android Studio for the purpose of debugging. I can confirm that the issue was introduced from Android Studio Bumblebee onwards (occurring in Beta and Canary builds also). I've reproduced the issue on Android Studio Bumblebee (Stable), Chipmunk (Beta), and Dolphin (Canary), but Android Studio Arctic Fox (superseded Stable) continues to work just fine.

The issue occurs soon after opening Android Studio (Bumblebee+) with one of my physical devices connected. Everything appears fine initially and I may even have enough time to deploy my project to the handset, before the device disappears from Android Studio (as if I'd physically disconnected the USB cable from my computer or from the handset itself).

I've tried a fair few things in an attempt to determine a root cause. These include testing:

  • With different USB cables.
  • With different handsets (both varying makes and models).
  • With various versions of the Android Studio IDE (as mentioned above).
  • Plugging the USB cables into different USB ports on my computer.
  • Rebooting handsets and my computer.
  • Restarting Android Studio.
  • Invalidating caches and restarting Android Studio.
  • adb kill-server then adb start-server.
  • Revoking/reaccepting USB debugging authorization.
  • Reinstalled build tools/platform tools, and ADB.
  • A great number of further possibilities, to no avail.

I searched and read through remotely similar issues, including (but not limited to) these:

This particular comment in one of the above issues clued me onto a possible root cause:

I have been fighting for a few days with adb not seeing my device. After trying many other posted solutions, I discovered that the issue was with Chrome also trying to connect its debugger to a web view. If Chrome is connected using chrome://inspect, then adb seems to disconnect. Quitting Chrome resolves the issue. Then I can connect with Android Studio and then restart Chrome and reconnect. Hope this helps someone else.

However I've been unable to do anything with the above discovery, other than close Google Chrome, and hope for the best. Obviously this isn't an ideal solution. It appears as though the moment Google Chrome shows the connected physical device in the chrome://inspect/#devices page, the physical device promptly becomes unavailable through Android Studio.

I've jumped back to Android Studio Arctic Fox (2020.3.1 Patch 4) for the moment, however this brings with it other issues (my current core project targets the latest SDK version, which requires the updated IDE).

Absolutely any help with this would be insanely appreciated. I've exhausted just about every avenue that I can think of!

ANSWER

Answered 2022-Feb-01 at 17:29

I solved the problem by disabling

Settings -> Build, Execution, Deployment -> Debugger -> "Enable adb mDNS for wireless debugging"

Source https://stackoverflow.com/questions/70936120

QUESTION

throwError(error) is now deprecated, but there is no new Error(HttpErrorResponse)

Asked 2022-Mar-01 at 00:42

Apparently throwError(error) is now deprecated. The IntelliSense of VS Code suggests throwError(() => new Error('error'). new Error(...) accepts only strings. What's the correct way to replace it without breaking my HttpErrorHandlerService ?

http-error.interceptor.ts
1import { Injectable } from '@angular/core';
2import {
3  HttpEvent,
4  HttpInterceptor,
5  HttpHandler,
6  HttpRequest,
7  HttpErrorResponse,
8  HttpResponse,
9  HttpHeaders
10} from '@angular/common/http';
11import { Observable, EMPTY, finalize, catchError, timeout, map, throwError } from 'rxjs';
12
13import { HttpErrorHandlerService } from '@core/services';
14
15@Injectable()
16export class HttpErrorInterceptor implements HttpInterceptor {
17  private readonly APP_XHR_TIMEOUT = 6000;
18
19  constructor(private errorHandlerService: HttpErrorHandlerService) {}
20
21  intercept(request: HttpRequest&lt;any&gt;, next: HttpHandler): Observable&lt;HttpEvent&lt;any&gt;&gt; {
22    return next.handle(this.performRequest(request)).pipe(
23      timeout(this.APP_XHR_TIMEOUT),
24      map((event: HttpEvent&lt;any&gt;) =&gt; this.handleSuccessfulResponse(event)),
25      catchError((error: HttpErrorResponse) =&gt; this.processRequestError(error, request, next)),
26      finalize(this.handleRequestCompleted.bind(this))
27    );
28  }
29
30  private performRequest(request: HttpRequest&lt;any&gt;): HttpRequest&lt;any&gt; {
31    let headers: HttpHeaders = request.headers;
32    //headers = headers.set('MyCustomHeaderKey', `MyCustomHeaderValue`);
33    return request.clone({ headers });
34  }
35
36  private handleSuccessfulResponse(event: HttpEvent&lt;any&gt;): HttpEvent&lt;any&gt; {
37    if (event instanceof HttpResponse) {
38      event = event.clone({ body: event.body.response });
39    }
40    return event;
41  }
42
43  private processRequestError(
44    error: HttpErrorResponse,
45    request: HttpRequest&lt;any&gt;,
46    next: HttpHandler
47  ): Observable&lt;HttpEvent&lt;any&gt;&gt; {
48    console.log('http error response');
49
50    if ([401].includes(error.status)) {
51      return throwError(error);
52    }
53
54    this.errorHandlerService.handle(error);
55
56    return throwError(error);
57  }
58
59  private handleRequestCompleted(): void {
60    // console.log(`Request finished`);
61  }
62}
63
64import { Injectable } from '@angular/core';
65import { HttpErrorResponse } from '@angular/common/http';
66
67import { MessageService } from 'primeng/api';
68import { TimeoutError } from 'rxjs';
69
70/**
71 * Shows a user-friendly error message when a HTTP request fails.
72 */
73@Injectable({
74  providedIn: 'root'
75})
76export class HttpErrorHandlerService {
77  constructor(private messageService: MessageService) {}
78
79  handle(error: Error | HttpErrorResponse) {
80    if (error instanceof TimeoutError) {
81      return this.openDialog('error', `Няма връзка до сървъра.`);
82    }
83
84    if (error instanceof HttpErrorResponse &amp;&amp; error.error &amp;&amp; error.error.message) {
85      return this.openDialog('error', error.error.message);
86    }
87
88    if (error instanceof Error) {
89      switch (error.message) {
90        default:
91          return this.openDialog('error', `An unknown error occurred`);
92      }
93    }
94
95    // Generic HTTP errors
96    switch (error.status) {
97      case 400:
98        switch (error.error) {
99          case 'invalid_username_or_password':
100            return this.openDialog('error', 'Невалидно потребителско име или парола');
101          default:
102            return this.openDialog('error', 'Bad request');
103        }
104
105      case 401:
106        return this.openDialog('error', 'Ще трябва да се логнете отново');
107
108      case 403:
109        return this.openDialog('error', `You don't have the required permissions`);
110
111      case 404:
112        return this.openDialog('error', 'Resource not found');
113
114      case 422:
115        return this.openDialog('error', 'Invalid data provided');
116
117      case 500:
118      case 501:
119      case 502:
120      case 503:
121        return this.openDialog('error', 'An internal server error occurred');
122
123      case -1:
124        return this.openDialog(
125          'error',
126          'You appear to be offline. Please check your internet connection and try again.'
127        );
128
129      case 0:
130        return this.openDialog('error', `CORS issue?`);
131
132      default:
133        return this.openDialog('error', `An unknown error occurred`);
134    }
135  }
136
137  private openDialog(severity: string, message: string) {
138    if (message?.trim()) {
139      this.messageService.add({
140        key: 'interceptor',
141        severity: severity,
142        summary: 'Информация',
143        detail: message,
144        life: 3000
145      });
146    }
147  }
148}
149
150
auth.interceptor.ts
1import { Injectable } from '@angular/core';
2import {
3  HttpEvent,
4  HttpInterceptor,
5  HttpHandler,
6  HttpRequest,
7  HttpErrorResponse,
8  HttpResponse,
9  HttpHeaders
10} from '@angular/common/http';
11import { Observable, EMPTY, finalize, catchError, timeout, map, throwError } from 'rxjs';
12
13import { HttpErrorHandlerService } from '@core/services';
14
15@Injectable()
16export class HttpErrorInterceptor implements HttpInterceptor {
17  private readonly APP_XHR_TIMEOUT = 6000;
18
19  constructor(private errorHandlerService: HttpErrorHandlerService) {}
20
21  intercept(request: HttpRequest&lt;any&gt;, next: HttpHandler): Observable&lt;HttpEvent&lt;any&gt;&gt; {
22    return next.handle(this.performRequest(request)).pipe(
23      timeout(this.APP_XHR_TIMEOUT),
24      map((event: HttpEvent&lt;any&gt;) =&gt; this.handleSuccessfulResponse(event)),
25      catchError((error: HttpErrorResponse) =&gt; this.processRequestError(error, request, next)),
26      finalize(this.handleRequestCompleted.bind(this))
27    );
28  }
29
30  private performRequest(request: HttpRequest&lt;any&gt;): HttpRequest&lt;any&gt; {
31    let headers: HttpHeaders = request.headers;
32    //headers = headers.set('MyCustomHeaderKey', `MyCustomHeaderValue`);
33    return request.clone({ headers });
34  }
35
36  private handleSuccessfulResponse(event: HttpEvent&lt;any&gt;): HttpEvent&lt;any&gt; {
37    if (event instanceof HttpResponse) {
38      event = event.clone({ body: event.body.response });
39    }
40    return event;
41  }
42
43  private processRequestError(
44    error: HttpErrorResponse,
45    request: HttpRequest&lt;any&gt;,
46    next: HttpHandler
47  ): Observable&lt;HttpEvent&lt;any&gt;&gt; {
48    console.log('http error response');
49
50    if ([401].includes(error.status)) {
51      return throwError(error);
52    }
53
54    this.errorHandlerService.handle(error);
55
56    return throwError(error);
57  }
58
59  private handleRequestCompleted(): void {
60    // console.log(`Request finished`);
61  }
62}
63
64import { Injectable } from '@angular/core';
65import { HttpErrorResponse } from '@angular/common/http';
66
67import { MessageService } from 'primeng/api';
68import { TimeoutError } from 'rxjs';
69
70/**
71 * Shows a user-friendly error message when a HTTP request fails.
72 */
73@Injectable({
74  providedIn: 'root'
75})
76export class HttpErrorHandlerService {
77  constructor(private messageService: MessageService) {}
78
79  handle(error: Error | HttpErrorResponse) {
80    if (error instanceof TimeoutError) {
81      return this.openDialog('error', `Няма връзка до сървъра.`);
82    }
83
84    if (error instanceof HttpErrorResponse &amp;&amp; error.error &amp;&amp; error.error.message) {
85      return this.openDialog('error', error.error.message);
86    }
87
88    if (error instanceof Error) {
89      switch (error.message) {
90        default:
91          return this.openDialog('error', `An unknown error occurred`);
92      }
93    }
94
95    // Generic HTTP errors
96    switch (error.status) {
97      case 400:
98        switch (error.error) {
99          case 'invalid_username_or_password':
100            return this.openDialog('error', 'Невалидно потребителско име или парола');
101          default:
102            return this.openDialog('error', 'Bad request');
103        }
104
105      case 401:
106        return this.openDialog('error', 'Ще трябва да се логнете отново');
107
108      case 403:
109        return this.openDialog('error', `You don't have the required permissions`);
110
111      case 404:
112        return this.openDialog('error', 'Resource not found');
113
114      case 422:
115        return this.openDialog('error', 'Invalid data provided');
116
117      case 500:
118      case 501:
119      case 502:
120      case 503:
121        return this.openDialog('error', 'An internal server error occurred');
122
123      case -1:
124        return this.openDialog(
125          'error',
126          'You appear to be offline. Please check your internet connection and try again.'
127        );
128
129      case 0:
130        return this.openDialog('error', `CORS issue?`);
131
132      default:
133        return this.openDialog('error', `An unknown error occurred`);
134    }
135  }
136
137  private openDialog(severity: string, message: string) {
138    if (message?.trim()) {
139      this.messageService.add({
140        key: 'interceptor',
141        severity: severity,
142        summary: 'Информация',
143        detail: message,
144        life: 3000
145      });
146    }
147  }
148}
149
150import { Injectable } from '@angular/core';
151import {
152  HttpRequest,
153  HttpHandler,
154  HttpEvent,
155  HttpInterceptor,
156  HttpErrorResponse
157} from '@angular/common/http';
158import {
159  BehaviorSubject,
160  catchError,
161  EMPTY,
162  filter,
163  finalize,
164  Observable,
165  switchMap,
166  take,
167  throwError
168} from 'rxjs';
169
170import { AuthService } from '@core/services';
171import { AuthResponse } from '@core/types';
172
173@Injectable()
174export class AuthInterceptor implements HttpInterceptor {
175  private refreshTokenInProgress: boolean;
176  private refreshToken$ = new BehaviorSubject&lt;AuthResponse | null&gt;(null);
177
178  constructor(private authService: AuthService) {}
179
180  intercept(request: HttpRequest&lt;any&gt;, next: HttpHandler): Observable&lt;HttpEvent&lt;any&gt;&gt; {
181    return next
182      .handle(this.performRequest(request))
183      .pipe(
184        catchError((error: HttpErrorResponse) =&gt; this.processRequestError(error, request, next))
185      );
186  }
187
188  private performRequest(request: HttpRequest&lt;any&gt;): HttpRequest&lt;any&gt; {
189    const accessToken = this.authService.getAccessToken();
190
191    let headers = request.headers;
192    if (accessToken) {
193      headers = headers.set('Authorization', `Bearer ${accessToken}`);
194    }
195
196    return request.clone({ headers });
197  }
198
199  private processRequestError(
200    error: HttpErrorResponse,
201    request: HttpRequest&lt;any&gt;,
202    next: HttpHandler
203  ): Observable&lt;HttpEvent&lt;any&gt;&gt; {
204    console.log('auth interceptor called');
205
206    if (
207      error instanceof HttpErrorResponse &amp;&amp;
208      error.status === 401 &amp;&amp;
209      this.authService.isSignedIn()
210    ) {
211      return this.refreshToken(request, next);
212    }
213
214    return throwError(error);
215  }
216
217  private refreshToken(request: HttpRequest&lt;any&gt;, next: HttpHandler): Observable&lt;HttpEvent&lt;any&gt;&gt; {
218    console.log('refresh token in auth.interceptor called');
219
220    // in case the page consists of more than one requests
221    if (!this.refreshTokenInProgress) {
222      this.refreshToken$.next(null);
223      this.refreshTokenInProgress = true;
224
225      return this.authService.refreshToken().pipe(
226        switchMap((response) =&gt; {
227          if (response) {
228            this.refreshToken$.next(response);
229            return next.handle(this.performRequest(request));
230          }
231
232          this.authService.signOut();
233          return throwError(() =&gt; new Error(&quot;RefreshTokenFailed&quot;));
234        }),
235        catchError((error) =&gt; {
236          this.authService.signOut();
237          return throwError(error);
238        }),
239        finalize(() =&gt; (this.refreshTokenInProgress = false))
240      );
241    } else {
242      // wait while getting new token
243      return this.refreshToken$.pipe(
244        filter((result) =&gt; result !== null),
245        take(1),
246        switchMap(() =&gt; next.handle(this.performRequest(request)))
247      );
248    }
249  }
250}
251
252

ANSWER

Answered 2021-Aug-04 at 19:08

Instead of this:

1import { Injectable } from '@angular/core';
2import {
3  HttpEvent,
4  HttpInterceptor,
5  HttpHandler,
6  HttpRequest,
7  HttpErrorResponse,
8  HttpResponse,
9  HttpHeaders
10} from '@angular/common/http';
11import { Observable, EMPTY, finalize, catchError, timeout, map, throwError } from 'rxjs';
12
13import { HttpErrorHandlerService } from '@core/services';
14
15@Injectable()
16export class HttpErrorInterceptor implements HttpInterceptor {
17  private readonly APP_XHR_TIMEOUT = 6000;
18
19  constructor(private errorHandlerService: HttpErrorHandlerService) {}
20
21  intercept(request: HttpRequest&lt;any&gt;, next: HttpHandler): Observable&lt;HttpEvent&lt;any&gt;&gt; {
22    return next.handle(this.performRequest(request)).pipe(
23      timeout(this.APP_XHR_TIMEOUT),
24      map((event: HttpEvent&lt;any&gt;) =&gt; this.handleSuccessfulResponse(event)),
25      catchError((error: HttpErrorResponse) =&gt; this.processRequestError(error, request, next)),
26      finalize(this.handleRequestCompleted.bind(this))
27    );
28  }
29
30  private performRequest(request: HttpRequest&lt;any&gt;): HttpRequest&lt;any&gt; {
31    let headers: HttpHeaders = request.headers;
32    //headers = headers.set('MyCustomHeaderKey', `MyCustomHeaderValue`);
33    return request.clone({ headers });
34  }
35
36  private handleSuccessfulResponse(event: HttpEvent&lt;any&gt;): HttpEvent&lt;any&gt; {
37    if (event instanceof HttpResponse) {
38      event = event.clone({ body: event.body.response });
39    }
40    return event;
41  }
42
43  private processRequestError(
44    error: HttpErrorResponse,
45    request: HttpRequest&lt;any&gt;,
46    next: HttpHandler
47  ): Observable&lt;HttpEvent&lt;any&gt;&gt; {
48    console.log('http error response');
49
50    if ([401].includes(error.status)) {
51      return throwError(error);
52    }
53
54    this.errorHandlerService.handle(error);
55
56    return throwError(error);
57  }
58
59  private handleRequestCompleted(): void {
60    // console.log(`Request finished`);
61  }
62}
63
64import { Injectable } from '@angular/core';
65import { HttpErrorResponse } from '@angular/common/http';
66
67import { MessageService } from 'primeng/api';
68import { TimeoutError } from 'rxjs';
69
70/**
71 * Shows a user-friendly error message when a HTTP request fails.
72 */
73@Injectable({
74  providedIn: 'root'
75})
76export class HttpErrorHandlerService {
77  constructor(private messageService: MessageService) {}
78
79  handle(error: Error | HttpErrorResponse) {
80    if (error instanceof TimeoutError) {
81      return this.openDialog('error', `Няма връзка до сървъра.`);
82    }
83
84    if (error instanceof HttpErrorResponse &amp;&amp; error.error &amp;&amp; error.error.message) {
85      return this.openDialog('error', error.error.message);
86    }
87
88    if (error instanceof Error) {
89      switch (error.message) {
90        default:
91          return this.openDialog('error', `An unknown error occurred`);
92      }
93    }
94
95    // Generic HTTP errors
96    switch (error.status) {
97      case 400:
98        switch (error.error) {
99          case 'invalid_username_or_password':
100            return this.openDialog('error', 'Невалидно потребителско име или парола');
101          default:
102            return this.openDialog('error', 'Bad request');
103        }
104
105      case 401:
106        return this.openDialog('error', 'Ще трябва да се логнете отново');
107
108      case 403:
109        return this.openDialog('error', `You don't have the required permissions`);
110
111      case 404:
112        return this.openDialog('error', 'Resource not found');
113
114      case 422:
115        return this.openDialog('error', 'Invalid data provided');
116
117      case 500:
118      case 501:
119      case 502:
120      case 503:
121        return this.openDialog('error', 'An internal server error occurred');
122
123      case -1:
124        return this.openDialog(
125          'error',
126          'You appear to be offline. Please check your internet connection and try again.'
127        );
128
129      case 0:
130        return this.openDialog('error', `CORS issue?`);
131
132      default:
133        return this.openDialog('error', `An unknown error occurred`);
134    }
135  }
136
137  private openDialog(severity: string, message: string) {
138    if (message?.trim()) {
139      this.messageService.add({
140        key: 'interceptor',
141        severity: severity,
142        summary: 'Информация',
143        detail: message,
144        life: 3000
145      });
146    }
147  }
148}
149
150import { Injectable } from '@angular/core';
151import {
152  HttpRequest,
153  HttpHandler,
154  HttpEvent,
155  HttpInterceptor,
156  HttpErrorResponse
157} from '@angular/common/http';
158import {
159  BehaviorSubject,
160  catchError,
161  EMPTY,
162  filter,
163  finalize,
164  Observable,
165  switchMap,
166  take,
167  throwError
168} from 'rxjs';
169
170import { AuthService } from '@core/services';
171import { AuthResponse } from '@core/types';
172
173@Injectable()
174export class AuthInterceptor implements HttpInterceptor {
175  private refreshTokenInProgress: boolean;
176  private refreshToken$ = new BehaviorSubject&lt;AuthResponse | null&gt;(null);
177
178  constructor(private authService: AuthService) {}
179
180  intercept(request: HttpRequest&lt;any&gt;, next: HttpHandler): Observable&lt;HttpEvent&lt;any&gt;&gt; {
181    return next
182      .handle(this.performRequest(request))
183      .pipe(
184        catchError((error: HttpErrorResponse) =&gt; this.processRequestError(error, request, next))
185      );
186  }
187
188  private performRequest(request: HttpRequest&lt;any&gt;): HttpRequest&lt;any&gt; {
189    const accessToken = this.authService.getAccessToken();
190
191    let headers = request.headers;
192    if (accessToken) {
193      headers = headers.set('Authorization', `Bearer ${accessToken}`);
194    }
195
196    return request.clone({ headers });
197  }
198
199  private processRequestError(
200    error: HttpErrorResponse,
201    request: HttpRequest&lt;any&gt;,
202    next: HttpHandler
203  ): Observable&lt;HttpEvent&lt;any&gt;&gt; {
204    console.log('auth interceptor called');
205
206    if (
207      error instanceof HttpErrorResponse &amp;&amp;
208      error.status === 401 &amp;&amp;
209      this.authService.isSignedIn()
210    ) {
211      return this.refreshToken(request, next);
212    }
213
214    return throwError(error);
215  }
216
217  private refreshToken(request: HttpRequest&lt;any&gt;, next: HttpHandler): Observable&lt;HttpEvent&lt;any&gt;&gt; {
218    console.log('refresh token in auth.interceptor called');
219
220    // in case the page consists of more than one requests
221    if (!this.refreshTokenInProgress) {
222      this.refreshToken$.next(null);
223      this.refreshTokenInProgress = true;
224
225      return this.authService.refreshToken().pipe(
226        switchMap((response) =&gt; {
227          if (response) {
228            this.refreshToken$.next(response);
229            return next.handle(this.performRequest(request));
230          }
231
232          this.authService.signOut();
233          return throwError(() =&gt; new Error(&quot;RefreshTokenFailed&quot;));
234        }),
235        catchError((error) =&gt; {
236          this.authService.signOut();
237          return throwError(error);
238        }),
239        finalize(() =&gt; (this.refreshTokenInProgress = false))
240      );
241    } else {
242      // wait while getting new token
243      return this.refreshToken$.pipe(
244        filter((result) =&gt; result !== null),
245        take(1),
246        switchMap(() =&gt; next.handle(this.performRequest(request)))
247      );
248    }
249  }
250}
251
252    catchError((error) =&gt; {
253      this.authService.signOut();
254      return throwError(error);
255    }),
256

You could try this:

1import { Injectable } from '@angular/core';
2import {
3  HttpEvent,
4  HttpInterceptor,
5  HttpHandler,
6  HttpRequest,
7  HttpErrorResponse,
8  HttpResponse,
9  HttpHeaders
10} from '@angular/common/http';
11import { Observable, EMPTY, finalize, catchError, timeout, map, throwError } from 'rxjs';
12
13import { HttpErrorHandlerService } from '@core/services';
14
15@Injectable()
16export class HttpErrorInterceptor implements HttpInterceptor {
17  private readonly APP_XHR_TIMEOUT = 6000;
18
19  constructor(private errorHandlerService: HttpErrorHandlerService) {}
20
21  intercept(request: HttpRequest&lt;any&gt;, next: HttpHandler): Observable&lt;HttpEvent&lt;any&gt;&gt; {
22    return next.handle(this.performRequest(request)).pipe(
23      timeout(this.APP_XHR_TIMEOUT),
24      map((event: HttpEvent&lt;any&gt;) =&gt; this.handleSuccessfulResponse(event)),
25      catchError((error: HttpErrorResponse) =&gt; this.processRequestError(error, request, next)),
26      finalize(this.handleRequestCompleted.bind(this))
27    );
28  }
29
30  private performRequest(request: HttpRequest&lt;any&gt;): HttpRequest&lt;any&gt; {
31    let headers: HttpHeaders = request.headers;
32    //headers = headers.set('MyCustomHeaderKey', `MyCustomHeaderValue`);
33    return request.clone({ headers });
34  }
35
36  private handleSuccessfulResponse(event: HttpEvent&lt;any&gt;): HttpEvent&lt;any&gt; {
37    if (event instanceof HttpResponse) {
38      event = event.clone({ body: event.body.response });
39    }
40    return event;
41  }
42
43  private processRequestError(
44    error: HttpErrorResponse,
45    request: HttpRequest&lt;any&gt;,
46    next: HttpHandler
47  ): Observable&lt;HttpEvent&lt;any&gt;&gt; {
48    console.log('http error response');
49
50    if ([401].includes(error.status)) {
51      return throwError(error);
52    }
53
54    this.errorHandlerService.handle(error);
55
56    return throwError(error);
57  }
58
59  private handleRequestCompleted(): void {
60    // console.log(`Request finished`);
61  }
62}
63
64import { Injectable } from '@angular/core';
65import { HttpErrorResponse } from '@angular/common/http';
66
67import { MessageService } from 'primeng/api';
68import { TimeoutError } from 'rxjs';
69
70/**
71 * Shows a user-friendly error message when a HTTP request fails.
72 */
73@Injectable({
74  providedIn: 'root'
75})
76export class HttpErrorHandlerService {
77  constructor(private messageService: MessageService) {}
78
79  handle(error: Error | HttpErrorResponse) {
80    if (error instanceof TimeoutError) {
81      return this.openDialog('error', `Няма връзка до сървъра.`);
82    }
83
84    if (error instanceof HttpErrorResponse &amp;&amp; error.error &amp;&amp; error.error.message) {
85      return this.openDialog('error', error.error.message);
86    }
87
88    if (error instanceof Error) {
89      switch (error.message) {
90        default:
91          return this.openDialog('error', `An unknown error occurred`);
92      }
93    }
94
95    // Generic HTTP errors
96    switch (error.status) {
97      case 400:
98        switch (error.error) {
99          case 'invalid_username_or_password':
100            return this.openDialog('error', 'Невалидно потребителско име или парола');
101          default:
102            return this.openDialog('error', 'Bad request');
103        }
104
105      case 401:
106        return this.openDialog('error', 'Ще трябва да се логнете отново');
107
108      case 403:
109        return this.openDialog('error', `You don't have the required permissions`);
110
111      case 404:
112        return this.openDialog('error', 'Resource not found');
113
114      case 422:
115        return this.openDialog('error', 'Invalid data provided');
116
117      case 500:
118      case 501:
119      case 502:
120      case 503:
121        return this.openDialog('error', 'An internal server error occurred');
122
123      case -1:
124        return this.openDialog(
125          'error',
126          'You appear to be offline. Please check your internet connection and try again.'
127        );
128
129      case 0:
130        return this.openDialog('error', `CORS issue?`);
131
132      default:
133        return this.openDialog('error', `An unknown error occurred`);
134    }
135  }
136
137  private openDialog(severity: string, message: string) {
138    if (message?.trim()) {
139      this.messageService.add({
140        key: 'interceptor',
141        severity: severity,
142        summary: 'Информация',
143        detail: message,
144        life: 3000
145      });
146    }
147  }
148}
149
150import { Injectable } from '@angular/core';
151import {
152  HttpRequest,
153  HttpHandler,
154  HttpEvent,
155  HttpInterceptor,
156  HttpErrorResponse
157} from '@angular/common/http';
158import {
159  BehaviorSubject,
160  catchError,
161  EMPTY,
162  filter,
163  finalize,
164  Observable,
165  switchMap,
166  take,
167  throwError
168} from 'rxjs';
169
170import { AuthService } from '@core/services';
171import { AuthResponse } from '@core/types';
172
173@Injectable()
174export class AuthInterceptor implements HttpInterceptor {
175  private refreshTokenInProgress: boolean;
176  private refreshToken$ = new BehaviorSubject&lt;AuthResponse | null&gt;(null);
177
178  constructor(private authService: AuthService) {}
179
180  intercept(request: HttpRequest&lt;any&gt;, next: HttpHandler): Observable&lt;HttpEvent&lt;any&gt;&gt; {
181    return next
182      .handle(this.performRequest(request))
183      .pipe(
184        catchError((error: HttpErrorResponse) =&gt; this.processRequestError(error, request, next))
185      );
186  }
187
188  private performRequest(request: HttpRequest&lt;any&gt;): HttpRequest&lt;any&gt; {
189    const accessToken = this.authService.getAccessToken();
190
191    let headers = request.headers;
192    if (accessToken) {
193      headers = headers.set('Authorization', `Bearer ${accessToken}`);
194    }
195
196    return request.clone({ headers });
197  }
198
199  private processRequestError(
200    error: HttpErrorResponse,
201    request: HttpRequest&lt;any&gt;,
202    next: HttpHandler
203  ): Observable&lt;HttpEvent&lt;any&gt;&gt; {
204    console.log('auth interceptor called');
205
206    if (
207      error instanceof HttpErrorResponse &amp;&amp;
208      error.status === 401 &amp;&amp;
209      this.authService.isSignedIn()
210    ) {
211      return this.refreshToken(request, next);
212    }
213
214    return throwError(error);
215  }
216
217  private refreshToken(request: HttpRequest&lt;any&gt;, next: HttpHandler): Observable&lt;HttpEvent&lt;any&gt;&gt; {
218    console.log('refresh token in auth.interceptor called');
219
220    // in case the page consists of more than one requests
221    if (!this.refreshTokenInProgress) {
222      this.refreshToken$.next(null);
223      this.refreshTokenInProgress = true;
224
225      return this.authService.refreshToken().pipe(
226        switchMap((response) =&gt; {
227          if (response) {
228            this.refreshToken$.next(response);
229            return next.handle(this.performRequest(request));
230          }
231
232          this.authService.signOut();
233          return throwError(() =&gt; new Error(&quot;RefreshTokenFailed&quot;));
234        }),
235        catchError((error) =&gt; {
236          this.authService.signOut();
237          return throwError(error);
238        }),
239        finalize(() =&gt; (this.refreshTokenInProgress = false))
240      );
241    } else {
242      // wait while getting new token
243      return this.refreshToken$.pipe(
244        filter((result) =&gt; result !== null),
245        take(1),
246        switchMap(() =&gt; next.handle(this.performRequest(request)))
247      );
248    }
249  }
250}
251
252    catchError((error) =&gt; {
253      this.authService.signOut();
254      return throwError(error);
255    }),
256    catchError((error) =&gt; {
257      this.authService.signOut();
258      return throwError(() =&gt; error);
259    }),
260

I wasn't able to test it thoroughly, but a simple attempt seemed to work.

This was my simple test (using RxJS v7.2):

Service

1import { Injectable } from '@angular/core';
2import {
3  HttpEvent,
4  HttpInterceptor,
5  HttpHandler,
6  HttpRequest,
7  HttpErrorResponse,
8  HttpResponse,
9  HttpHeaders
10} from '@angular/common/http';
11import { Observable, EMPTY, finalize, catchError, timeout, map, throwError } from 'rxjs';
12
13import { HttpErrorHandlerService } from '@core/services';
14
15@Injectable()
16export class HttpErrorInterceptor implements HttpInterceptor {
17  private readonly APP_XHR_TIMEOUT = 6000;
18
19  constructor(private errorHandlerService: HttpErrorHandlerService) {}
20
21  intercept(request: HttpRequest&lt;any&gt;, next: HttpHandler): Observable&lt;HttpEvent&lt;any&gt;&gt; {
22    return next.handle(this.performRequest(request)).pipe(
23      timeout(this.APP_XHR_TIMEOUT),
24      map((event: HttpEvent&lt;any&gt;) =&gt; this.handleSuccessfulResponse(event)),
25      catchError((error: HttpErrorResponse) =&gt; this.processRequestError(error, request, next)),
26      finalize(this.handleRequestCompleted.bind(this))
27    );
28  }
29
30  private performRequest(request: HttpRequest&lt;any&gt;): HttpRequest&lt;any&gt; {
31    let headers: HttpHeaders = request.headers;
32    //headers = headers.set('MyCustomHeaderKey', `MyCustomHeaderValue`);
33    return request.clone({ headers });
34  }
35
36  private handleSuccessfulResponse(event: HttpEvent&lt;any&gt;): HttpEvent&lt;any&gt; {
37    if (event instanceof HttpResponse) {
38      event = event.clone({ body: event.body.response });
39    }
40    return event;
41  }
42
43  private processRequestError(
44    error: HttpErrorResponse,
45    request: HttpRequest&lt;any&gt;,
46    next: HttpHandler
47  ): Observable&lt;HttpEvent&lt;any&gt;&gt; {
48    console.log('http error response');
49
50    if ([401].includes(error.status)) {
51      return throwError(error);
52    }
53
54    this.errorHandlerService.handle(error);
55
56    return throwError(error);
57  }
58
59  private handleRequestCompleted(): void {
60    // console.log(`Request finished`);
61  }
62}
63
64import { Injectable } from '@angular/core';
65import { HttpErrorResponse } from '@angular/common/http';
66
67import { MessageService } from 'primeng/api';
68import { TimeoutError } from 'rxjs';
69
70/**
71 * Shows a user-friendly error message when a HTTP request fails.
72 */
73@Injectable({
74  providedIn: 'root'
75})
76export class HttpErrorHandlerService {
77  constructor(private messageService: MessageService) {}
78
79  handle(error: Error | HttpErrorResponse) {
80    if (error instanceof TimeoutError) {
81      return this.openDialog('error', `Няма връзка до сървъра.`);
82    }
83
84    if (error instanceof HttpErrorResponse &amp;&amp; error.error &amp;&amp; error.error.message) {
85      return this.openDialog('error', error.error.message);
86    }
87
88    if (error instanceof Error) {
89      switch (error.message) {
90        default:
91          return this.openDialog('error', `An unknown error occurred`);
92      }
93    }
94
95    // Generic HTTP errors
96    switch (error.status) {
97      case 400:
98        switch (error.error) {
99          case 'invalid_username_or_password':
100            return this.openDialog('error', 'Невалидно потребителско име или парола');
101          default:
102            return this.openDialog('error', 'Bad request');
103        }
104
105      case 401:
106        return this.openDialog('error', 'Ще трябва да се логнете отново');
107
108      case 403:
109        return this.openDialog('error', `You don't have the required permissions`);
110
111      case 404:
112        return this.openDialog('error', 'Resource not found');
113
114      case 422:
115        return this.openDialog('error', 'Invalid data provided');
116
117      case 500:
118      case 501:
119      case 502:
120      case 503:
121        return this.openDialog('error', 'An internal server error occurred');
122
123      case -1:
124        return this.openDialog(
125          'error',
126          'You appear to be offline. Please check your internet connection and try again.'
127        );
128
129      case 0:
130        return this.openDialog('error', `CORS issue?`);
131
132      default:
133        return this.openDialog('error', `An unknown error occurred`);
134    }
135  }
136
137  private openDialog(severity: string, message: string) {
138    if (message?.trim()) {
139      this.messageService.add({
140        key: 'interceptor',
141        severity: severity,
142        summary: 'Информация',
143        detail: message,
144        life: 3000
145      });
146    }
147  }
148}
149
150import { Injectable } from '@angular/core';
151import {
152  HttpRequest,
153  HttpHandler,
154  HttpEvent,
155  HttpInterceptor,
156  HttpErrorResponse
157} from '@angular/common/http';
158import {
159  BehaviorSubject,
160  catchError,
161  EMPTY,
162  filter,
163  finalize,
164  Observable,
165  switchMap,
166  take,
167  throwError
168} from 'rxjs';
169
170import { AuthService } from '@core/services';
171import { AuthResponse } from '@core/types';
172
173@Injectable()
174export class AuthInterceptor implements HttpInterceptor {
175  private refreshTokenInProgress: boolean;
176  private refreshToken$ = new BehaviorSubject&lt;AuthResponse | null&gt;(null);
177
178  constructor(private authService: AuthService) {}
179
180  intercept(request: HttpRequest&lt;any&gt;, next: HttpHandler): Observable&lt;HttpEvent&lt;any&gt;&gt; {
181    return next
182      .handle(this.performRequest(request))
183      .pipe(
184        catchError((error: HttpErrorResponse) =&gt; this.processRequestError(error, request, next))
185      );
186  }
187
188  private performRequest(request: HttpRequest&lt;any&gt;): HttpRequest&lt;any&gt; {
189    const accessToken = this.authService.getAccessToken();
190
191    let headers = request.headers;
192    if (accessToken) {
193      headers = headers.set('Authorization', `Bearer ${accessToken}`);
194    }
195
196    return request.clone({ headers });
197  }
198
199  private processRequestError(
200    error: HttpErrorResponse,
201    request: HttpRequest&lt;any&gt;,
202    next: HttpHandler
203  ): Observable&lt;HttpEvent&lt;any&gt;&gt; {
204    console.log('auth interceptor called');
205
206    if (
207      error instanceof HttpErrorResponse &amp;&amp;
208      error.status === 401 &amp;&amp;
209      this.authService.isSignedIn()
210    ) {
211      return this.refreshToken(request, next);
212    }
213
214    return throwError(error);
215  }
216
217  private refreshToken(request: HttpRequest&lt;any&gt;, next: HttpHandler): Observable&lt;HttpEvent&lt;any&gt;&gt; {
218    console.log('refresh token in auth.interceptor called');
219
220    // in case the page consists of more than one requests
221    if (!this.refreshTokenInProgress) {
222      this.refreshToken$.next(null);
223      this.refreshTokenInProgress = true;
224
225      return this.authService.refreshToken().pipe(
226        switchMap((response) =&gt; {
227          if (response) {
228            this.refreshToken$.next(response);
229            return next.handle(this.performRequest(request));
230          }
231
232          this.authService.signOut();
233          return throwError(() =&gt; new Error(&quot;RefreshTokenFailed&quot;));
234        }),
235        catchError((error) =&gt; {
236          this.authService.signOut();
237          return throwError(error);
238        }),
239        finalize(() =&gt; (this.refreshTokenInProgress = false))
240      );
241    } else {
242      // wait while getting new token
243      return this.refreshToken$.pipe(
244        filter((result) =&gt; result !== null),
245        take(1),
246        switchMap(() =&gt; next.handle(this.performRequest(request)))
247      );
248    }
249  }
250}
251
252    catchError((error) =&gt; {
253      this.authService.signOut();
254      return throwError(error);
255    }),
256    catchError((error) =&gt; {
257      this.authService.signOut();
258      return throwError(() =&gt; error);
259    }),
260  getProducts(): Observable&lt;IProduct[]&gt; {
261    return this.http.get&lt;IProduct[]&gt;(this.productUrl)
262      .pipe(
263        tap(data =&gt; console.log('All: ', JSON.stringify(data))),
264        catchError(this.handleError)
265      );
266  }
267
268  private handleError(err: HttpErrorResponse): Observable&lt;never&gt; {
269    // just a test ... more could would go here
270    return throwError(() =&gt; err);
271  }
272

Notice that err here is of type HttpErrorResponse.

Component

1import { Injectable } from '@angular/core';
2import {
3  HttpEvent,
4  HttpInterceptor,
5  HttpHandler,
6  HttpRequest,
7  HttpErrorResponse,
8  HttpResponse,
9  HttpHeaders
10} from '@angular/common/http';
11import { Observable, EMPTY, finalize, catchError, timeout, map, throwError } from 'rxjs';
12
13import { HttpErrorHandlerService } from '@core/services';
14
15@Injectable()
16export class HttpErrorInterceptor implements HttpInterceptor {
17  private readonly APP_XHR_TIMEOUT = 6000;
18
19  constructor(private errorHandlerService: HttpErrorHandlerService) {}
20
21  intercept(request: HttpRequest&lt;any&gt;, next: HttpHandler): Observable&lt;HttpEvent&lt;any&gt;&gt; {
22    return next.handle(this.performRequest(request)).pipe(
23      timeout(this.APP_XHR_TIMEOUT),
24      map((event: HttpEvent&lt;any&gt;) =&gt; this.handleSuccessfulResponse(event)),
25      catchError((error: HttpErrorResponse) =&gt; this.processRequestError(error, request, next)),
26      finalize(this.handleRequestCompleted.bind(this))
27    );
28  }
29
30  private performRequest(request: HttpRequest&lt;any&gt;): HttpRequest&lt;any&gt; {
31    let headers: HttpHeaders = request.headers;
32    //headers = headers.set('MyCustomHeaderKey', `MyCustomHeaderValue`);
33    return request.clone({ headers });
34  }
35
36  private handleSuccessfulResponse(event: HttpEvent&lt;any&gt;): HttpEvent&lt;any&gt; {
37    if (event instanceof HttpResponse) {
38      event = event.clone({ body: event.body.response });
39    }
40    return event;
41  }
42
43  private processRequestError(
44    error: HttpErrorResponse,
45    request: HttpRequest&lt;any&gt;,
46    next: HttpHandler
47  ): Observable&lt;HttpEvent&lt;any&gt;&gt; {
48    console.log('http error response');
49
50    if ([401].includes(error.status)) {
51      return throwError(error);
52    }
53
54    this.errorHandlerService.handle(error);
55
56    return throwError(error);
57  }
58
59  private handleRequestCompleted(): void {
60    // console.log(`Request finished`);
61  }
62}
63
64import { Injectable } from '@angular/core';
65import { HttpErrorResponse } from '@angular/common/http';
66
67import { MessageService } from 'primeng/api';
68import { TimeoutError } from 'rxjs';
69
70/**
71 * Shows a user-friendly error message when a HTTP request fails.
72 */
73@Injectable({
74  providedIn: 'root'
75})
76export class HttpErrorHandlerService {
77  constructor(private messageService: MessageService) {}
78
79  handle(error: Error | HttpErrorResponse) {
80    if (error instanceof TimeoutError) {
81      return this.openDialog('error', `Няма връзка до сървъра.`);
82    }
83
84    if (error instanceof HttpErrorResponse &amp;&amp; error.error &amp;&amp; error.error.message) {
85      return this.openDialog('error', error.error.message);
86    }
87
88    if (error instanceof Error) {
89      switch (error.message) {
90        default:
91          return this.openDialog('error', `An unknown error occurred`);
92      }
93    }
94
95    // Generic HTTP errors
96    switch (error.status) {
97      case 400:
98        switch (error.error) {
99          case 'invalid_username_or_password':
100            return this.openDialog('error', 'Невалидно потребителско име или парола');
101          default:
102            return this.openDialog('error', 'Bad request');
103        }
104
105      case 401:
106        return this.openDialog('error', 'Ще трябва да се логнете отново');
107
108      case 403:
109        return this.openDialog('error', `You don't have the required permissions`);
110
111      case 404:
112        return this.openDialog('error', 'Resource not found');
113
114      case 422:
115        return this.openDialog('error', 'Invalid data provided');
116
117      case 500:
118      case 501:
119      case 502:
120      case 503:
121        return this.openDialog('error', 'An internal server error occurred');
122
123      case -1:
124        return this.openDialog(
125          'error',
126          'You appear to be offline. Please check your internet connection and try again.'
127        );
128
129      case 0:
130        return this.openDialog('error', `CORS issue?`);
131
132      default:
133        return this.openDialog('error', `An unknown error occurred`);
134    }
135  }
136
137  private openDialog(severity: string, message: string) {
138    if (message?.trim()) {
139      this.messageService.add({
140        key: 'interceptor',
141        severity: severity,
142        summary: 'Информация',
143        detail: message,
144        life: 3000
145      });
146    }
147  }
148}
149
150import { Injectable } from '@angular/core';
151import {
152  HttpRequest,
153  HttpHandler,
154  HttpEvent,
155  HttpInterceptor,
156  HttpErrorResponse
157} from '@angular/common/http';
158import {
159  BehaviorSubject,
160  catchError,
161  EMPTY,
162  filter,
163  finalize,
164  Observable,
165  switchMap,
166  take,
167  throwError
168} from 'rxjs';
169
170import { AuthService } from '@core/services';
171import { AuthResponse } from '@core/types';
172
173@Injectable()
174export class AuthInterceptor implements HttpInterceptor {
175  private refreshTokenInProgress: boolean;
176  private refreshToken$ = new BehaviorSubject&lt;AuthResponse | null&gt;(null);
177
178  constructor(private authService: AuthService) {}
179
180  intercept(request: HttpRequest&lt;any&gt;, next: HttpHandler): Observable&lt;HttpEvent&lt;any&gt;&gt; {
181    return next
182      .handle(this.performRequest(request))
183      .pipe(
184        catchError((error: HttpErrorResponse) =&gt; this.processRequestError(error, request, next))
185      );
186  }
187
188  private performRequest(request: HttpRequest&lt;any&gt;): HttpRequest&lt;any&gt; {
189    const accessToken = this.authService.getAccessToken();
190
191    let headers = request.headers;
192    if (accessToken) {
193      headers = headers.set('Authorization', `Bearer ${accessToken}`);
194    }
195
196    return request.clone({ headers });
197  }
198
199  private processRequestError(
200    error: HttpErrorResponse,
201    request: HttpRequest&lt;any&gt;,
202    next: HttpHandler
203  ): Observable&lt;HttpEvent&lt;any&gt;&gt; {
204    console.log('auth interceptor called');
205
206    if (
207      error instanceof HttpErrorResponse &amp;&amp;
208      error.status === 401 &amp;&amp;
209      this.authService.isSignedIn()
210    ) {
211      return this.refreshToken(request, next);
212    }
213
214    return throwError(error);
215  }
216
217  private refreshToken(request: HttpRequest&lt;any&gt;, next: HttpHandler): Observable&lt;HttpEvent&lt;any&gt;&gt; {
218    console.log('refresh token in auth.interceptor called');
219
220    // in case the page consists of more than one requests
221    if (!this.refreshTokenInProgress) {
222      this.refreshToken$.next(null);
223      this.refreshTokenInProgress = true;
224
225      return this.authService.refreshToken().pipe(
226        switchMap((response) =&gt; {
227          if (response) {
228            this.refreshToken$.next(response);
229            return next.handle(this.performRequest(request));
230          }
231
232          this.authService.signOut();
233          return throwError(() =&gt; new Error(&quot;RefreshTokenFailed&quot;));
234        }),
235        catchError((error) =&gt; {
236          this.authService.signOut();
237          return throwError(error);
238        }),
239        finalize(() =&gt; (this.refreshTokenInProgress = false))
240      );
241    } else {
242      // wait while getting new token
243      return this.refreshToken$.pipe(
244        filter((result) =&gt; result !== null),
245        take(1),
246        switchMap(() =&gt; next.handle(this.performRequest(request)))
247      );
248    }
249  }
250}
251
252    catchError((error) =&gt; {
253      this.authService.signOut();
254      return throwError(error);
255    }),
256    catchError((error) =&gt; {
257      this.authService.signOut();
258      return throwError(() =&gt; error);
259    }),
260  getProducts(): Observable&lt;IProduct[]&gt; {
261    return this.http.get&lt;IProduct[]&gt;(this.productUrl)
262      .pipe(
263        tap(data =&gt; console.log('All: ', JSON.stringify(data))),
264        catchError(this.handleError)
265      );
266  }
267
268  private handleError(err: HttpErrorResponse): Observable&lt;never&gt; {
269    // just a test ... more could would go here
270    return throwError(() =&gt; err);
271  }
272  ngOnInit(): void {
273    this.sub = this.productService.getProducts().subscribe({
274      next: products =&gt; {
275        this.products = products;
276        this.filteredProducts = this.products;
277      },
278      error: err =&gt; this.errorMessage = err.message
279    });
280  }
281

Here I was able to retrieve the message property from the error response and display it in my UI.

Let me know if this works for you.

Source https://stackoverflow.com/questions/68655492

QUESTION

Google Colab drive mount (with underscore) is not working

Asked 2022-Feb-13 at 11:04

Until yesterday (20 Jan) I could connect to another google drive account (using drive._mount), but when I tried this today, google colab showed me this error:

1from google.colab import drive
2drive._mount('/content/drive/')
3
4    /usr/local/lib/python3.7/dist-packages/google/colab/drive.py in _mount(mountpoint, force_remount, timeout_ms, use_metadata_server, ephemeral)
5    294       wrote_to_fifo = True
6    295     elif case == 5 and not use_metadata_server:
7--&gt; 296       raise ValueError('mount failed: invalid oauth code')
8    297     elif case == 6:
9    298       # Terminate the DriveFS binary before killing bash.
10
11ValueError: mount failed: invalid oauth code
12

Strange thing is that error tells me "invalid oauth code", but not let me connect to google page and copy the code!

And I set use_metadata_server=True but this time, new error appeares:

1from google.colab import drive
2drive._mount('/content/drive/')
3
4    /usr/local/lib/python3.7/dist-packages/google/colab/drive.py in _mount(mountpoint, force_remount, timeout_ms, use_metadata_server, ephemeral)
5    294       wrote_to_fifo = True
6    295     elif case == 5 and not use_metadata_server:
7--&gt; 296       raise ValueError('mount failed: invalid oauth code')
8    297     elif case == 6:
9    298       # Terminate the DriveFS binary before killing bash.
10
11ValueError: mount failed: invalid oauth code
12    from google.colab import drive
13    drive._mount('/content/drive/', use_metadata_server=True)
14ValueError                                Traceback (most recent call last)
15&lt;ipython-input-5-42a561ce7057&gt; in &lt;module&gt;()
16      1 from google.colab import drive
17----&gt; 2 drive._mount('/content/drive/', use_metadata_server=True)
18
19/usr/local/lib/python3.7/dist-packages/google/colab/drive.py in _mount(mountpoint, force_remount, timeout_ms, use_metadata_server, ephemeral)
20    285             ': timeout during initial read of root folder; for more info: '
21    286             'https://research.google.com/colaboratory/faq.html#drive-timeout')
22--&gt; 287       raise ValueError('mount failed' + extra_reason)
23    288     elif case == 2:
24    289       # Not already authorized, so do the authorization dance.
25
26ValueError: mount failed
27

Also I used drive.mount but showed pop-up and ask me to enter another account credentials. When I enter it, this error appears:

1from google.colab import drive
2drive._mount('/content/drive/')
3
4    /usr/local/lib/python3.7/dist-packages/google/colab/drive.py in _mount(mountpoint, force_remount, timeout_ms, use_metadata_server, ephemeral)
5    294       wrote_to_fifo = True
6    295     elif case == 5 and not use_metadata_server:
7--&gt; 296       raise ValueError('mount failed: invalid oauth code')
8    297     elif case == 6:
9    298       # Terminate the DriveFS binary before killing bash.
10
11ValueError: mount failed: invalid oauth code
12    from google.colab import drive
13    drive._mount('/content/drive/', use_metadata_server=True)
14ValueError                                Traceback (most recent call last)
15&lt;ipython-input-5-42a561ce7057&gt; in &lt;module&gt;()
16      1 from google.colab import drive
17----&gt; 2 drive._mount('/content/drive/', use_metadata_server=True)
18
19/usr/local/lib/python3.7/dist-packages/google/colab/drive.py in _mount(mountpoint, force_remount, timeout_ms, use_metadata_server, ephemeral)
20    285             ': timeout during initial read of root folder; for more info: '
21    286             'https://research.google.com/colaboratory/faq.html#drive-timeout')
22--&gt; 287       raise ValueError('mount failed' + extra_reason)
23    288     elif case == 2:
24    289       # Not already authorized, so do the authorization dance.
25
26ValueError: mount failed
27from google.colab import drive
28drive.mount('/content/drive/')
29
30MessageError                              Traceback (most recent call last)
31&lt;ipython-input-1-91874b305a32&gt; in &lt;module&gt;()
32      1 from google.colab import drive
33----&gt; 2 drive.mount('/content/drive/')
34
353 frames
36/usr/local/lib/python3.7/dist-packages/google/colab/_message.py in read_reply_from_input(message_id, timeout_sec)
37    104         reply.get('colab_msg_id') == message_id):
38    105       if 'error' in reply:
39--&gt; 106         raise MessageError(reply['error'])
40    107       return reply.get('data', None)
41    108 
42
43MessageError: Error: credential propagation was unsuccessful
44

I think this is new policy. Is there an solution?

ANSWER

Answered 2022-Jan-21 at 14:00

Alright, until this problem get solved, I did this trick for my project:
I shared which files I need (like datasets) with my other accounts. For this, you should:

  1. Go to your google drive (where your file is stored) then right-click on it and choose "Share"
  2. Click on "Change to anyone with the link"
  3. Copy link and open it in new window
  4. In top-right side, click on your google accounts list and select which one you need
  5. At the opened window, in top-right side click on "Add shortcut to Drive" and choose location where you want to save file in it
  6. Your file now is accessible in account you did choose

Source https://stackoverflow.com/questions/70798293

QUESTION

Save authenticated users to database coming from Azure AD

Asked 2022-Feb-10 at 15:47

I am working on a simple web app for learning purposes using Angular for the frontend and Java Spring for the backend. I don't have a particular problem that I want you guys to help me out with, instead I have a question about OAuth2 authentication.

I have registered my Angular SPA in Azure AD (Authorization Code Flow + PKCE), I set up roles and everything is working okay. My question is what do I do when authenticated users ping my backend? My backend has no information about the users.

I thought of a solution to make a web filter, and every time an authenticated user pings any endpoint requiring the user to be authenticated, to check the database if the user exists (through the username), and save him if he does not exist. I'm pretty sure this will work, but I don't think this is the best solution, considering my web filter will have to read from the databases for every single HTTP request that comes in, and write to the database occasionally (if the user logs in for the first time).

I shouldn't be worried about performance issues because I'm building this strictly for learning purposes, but nevertheless I want to do this the right way. I tried googling this in multiple ways, but I guess I'm not using the right keywords to find what I'm looking for. Any opinion or advice would be much appreciated! Thanks!

EDIT: I followed this article to achieve the OAuth2 + OIDC authentication and authorization, my security config in the backend is the same: https://ordina-jworks.github.io/security/2020/08/18/Securing-Applications-Azure-AD.html

ANSWER

Answered 2022-Feb-10 at 15:47

Post the discussion with clarity on the requirements. If you want to use have the following:

  • Accept an Azure AD logged in user to consumer your web service
  • You would want to check if the user exists in your application database with minimal network latency.

With the requirement of not always hitting your Database, one option is to use a cache.

The ideal solution for this cache to work is:

  • Ensure the cache is checked for every HTTP Request using Web Filter
  • Make sure the cache is always updated with the latest users being logged in via Azure AD

Example:

Implement a CacheService.java

1package com.example.springboot;
2
3import java.util.Collections;
4
5import org.apache.catalina.User;
6import org.springframework.cache.CacheManager;
7import org.springframework.cache.annotation.Cacheable;
8import org.springframework.cache.concurrent.ConcurrentMapCache;
9import org.springframework.cache.support.SimpleCacheManager;
10import org.springframework.context.annotation.Bean;
11import org.springframework.stereotype.Component;
12
13@Component
14public class CacheService {
15
16  @Bean
17  public CacheManager cacheManager() {
18    SimpleCacheManager cacheManager = new SimpleCacheManager();
19    cacheManager.setCaches(Collections.singletonList(new ConcurrentMapCache(&quot;users&quot;)));
20    return cacheManager;
21  }
22
23
24  @Cacheable(cacheNames = &quot;users&quot;)
25  public User getUser(String username) {
26    // Code below will not execute after the first calling for the given username. 
27    // So if one username is already cached, it would not invoke for the same user again from the DB.
28
29    // Get or Create a new user based on the Database call
30    return null;
31  }
32}
33

Then implement a web filter like:

1package com.example.springboot;
2
3import java.util.Collections;
4
5import org.apache.catalina.User;
6import org.springframework.cache.CacheManager;
7import org.springframework.cache.annotation.Cacheable;
8import org.springframework.cache.concurrent.ConcurrentMapCache;
9import org.springframework.cache.support.SimpleCacheManager;
10import org.springframework.context.annotation.Bean;
11import org.springframework.stereotype.Component;
12
13@Component
14public class CacheService {
15
16  @Bean
17  public CacheManager cacheManager() {
18    SimpleCacheManager cacheManager = new SimpleCacheManager();
19    cacheManager.setCaches(Collections.singletonList(new ConcurrentMapCache(&quot;users&quot;)));
20    return cacheManager;
21  }
22
23
24  @Cacheable(cacheNames = &quot;users&quot;)
25  public User getUser(String username) {
26    // Code below will not execute after the first calling for the given username. 
27    // So if one username is already cached, it would not invoke for the same user again from the DB.
28
29    // Get or Create a new user based on the Database call
30    return null;
31  }
32}
33package com.example.springboot;
34
35import java.io.IOException;
36
37import javax.servlet.FilterChain;
38import javax.servlet.ServletException;
39import javax.servlet.ServletRequest;
40import javax.servlet.ServletResponse;
41
42import org.springframework.beans.factory.annotation.Autowired;
43import org.springframework.stereotype.Component;
44import org.springframework.web.filter.GenericFilterBean;
45
46@Component
47public class CredentialsInjectionFilter extends GenericFilterBean {
48
49  @Autowired
50  private CacheService cacheService;
51
52  @Override
53  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
54      FilterChain filterChain) throws IOException, ServletException {
55
56    cacheService.getUser(&quot;my_username&quot;);
57
58    filterChain.doFilter(servletRequest, servletResponse);
59  }
60}
61

Source https://stackoverflow.com/questions/70957923

Community Discussions contain sources that include Stack Exchange Network

Tutorials and Learning Resources in Authorization

Tutorials and Learning Resources are not available at this moment for Authorization

Share this Page

share link

Get latest updates on Authorization