Utente che chiama le API REST per conto di un utente diverso

2

Ecco un esempio:

GET /posts
POST /posts
GET /posts/{post_id}
PUT /posts/{post_id}

Questa API viene utilizzata da SUPER_ADMIN e CONTENT_WRITERS. Funziona alla grande. Se l'utente ha effettuato l'accesso come SuperAdmin, vede tutti i post, e se l'utente è loggato come ContentWriter, vede solo il suo post.

Ma ora viene aggiunto il requisito, in cui SuperAdmin dovrebbe essere in grado di eseguire operazioni CRUD per conto di qualsiasi ContentWriter.

Ho aggiunto queste API per questo:

GET /user/{user_id}/posts
POST /user/{user_id}/posts
GET /user/{user_id}/posts/{post_id}
PUT /user/{user_id}/posts/{post_id}

Funziona bene anche lui. Ma il problema qui è, ora ci sono troppe API / controller da mantenere . Anche se i controller usano lo stesso servizio per questo.

La mia domanda è, sto andando nella giusta direzione? O ci sono altre buone pratiche per questo?

UPDATE 1

L'idea qui è in qualche modo simile a Impersonation .

    
posta TheManish 15.10.2018 - 11:20
fonte

4 risposte

2

Un requisito per consentire agli amministratori di impersonare gli utenti non dovrebbe richiedere più endpoint API di quelli già esistenti nel sistema. Questo dovrebbe essere gestito con campi modulo aggiuntivi sul tuo creare / modificare POST / PUT piuttosto che endpoint completamente diversi. Dovresti aggiungere la convalida che questi campi vengano compilati solo quando la richiesta proviene da un amministratore o ignorarli per i non amministratori. Dovresti già disporre del meccanismo di autorizzazione per riconoscere una richiesta di amministrazione da un non amministratore, questa funzionalità può essere vista come una leggera estensione. Anche se non è necessario per soddisfare le esigenze aziendali, sarebbe anche una buona idea modificare il database / livello di persistenza per tenere traccia di chi ha fatto un aggiornamento e chi dovrebbe essere visualizzato come aggiornamento. Ciò si rivelerà utile nel caso in cui un amministratore abusi del loro potere.

    
risposta data 15.10.2018 - 14:01
fonte
2

Ma per quanto posso dire, quello che stai cercando di fare è analogo a quello che Alice invoca

sudo -u bob ls /home/bob

Penso che si possa argomentare ragionevolmente in due modi

Innanzitutto, questa è una risorsa diversa ; condivide un insieme comune di rappresentazioni con ls /home/bob , ma le regole di autorizzazione sono diverse. Sul web, ciò significherebbe due identificatori diversi

/home/bob
/su/bob/home/bob

In effetti, abbiamo un nuovo protocollo, quindi creiamo nuove risorse per supportare quel protocollo.

L'altro argomento è che queste sono la stessa risorsa, e la differenza tra i due casi è Autorizzazione intestazione. Sembra giusto? ma non riesco a trovare alcun esempio che faccia questo.

Puoi trovare alcuni esempi in cui le persone hanno implementato un'idea simile usando intestazioni http personalizzate. Ad esempio link

A causa della mancanza di chiari precedenti, raccomanderei di continuare con il primo approccio.

    
risposta data 15.10.2018 - 15:07
fonte
1

Non sono un esperto in questo, ma dal momento che stai provando a fare richieste per conto di altri utenti, dal punto di vista delle API le richieste provengono da quell'utente, non dall'Amministratore.

Hai preso in considerazione l'aggiunta di una route di amministrazione che consente all'utente amministratore di ottenere un token di sessione per un altro utente? Ciò consentirà all'amministratore di inviare le richieste agli endpoint che hai già utilizzato quel token di altri utenti.

    
risposta data 15.10.2018 - 13:57
fonte
0

Penso che una cosa fondamentale saranno i tuoi requisiti esatti in merito a ciò che significa "pubblicare per conto di un altro utente"

Ma supponendo che sia solo il nome dell'autore avrei semplicemente una proprietà sull'oggetto Post

class Post
{
    public string AuthoredByUserId {get;set;}
    ....
}

Ora nel tuo controller puoi controllare se AuthoredByUserId è uguale a quello che invia il post e permetterlo ai super utenti o non permetterlo ai normali utenti.

Detto questo, personalmente vorrei ancora aggiungere un endpoint separato semplicemente così posso usare l'autenticazione integrata per i metodi endpoint, piuttosto che dover codificare un controllo dell'autenticazione, per esempio.

[Authorise(Roles="ContentWriter")]
public Action AddPost(Post)
{
    ...error if AuthoredByUserId != the users Id
}

[Authorise(Roles="SUPER_ADMIN")]
public Action AddPostForAnotherUser(Post)
{
    ..ignore the userid validation
}
    
risposta data 15.10.2018 - 14:00
fonte

Leggi altre domande sui tag