strapi / rfcs

RFCs for Strapi future changes
70 stars 33 forks source link

Issue 3733. Split authentication from permissions #4

Closed froger closed 4 years ago

froger commented 5 years ago

This PR is to describe a refactoring of the users-permissions plugin in order to have clear separations between authentication and permissions concerns.

Edit: Link to see the RFC

Edit: Link to see the first issue created

froger commented 5 years ago

For sake of completeness, there were an interesting discussion on slack in the feature request channel.

froger commented 5 years ago

I would like to know if the core team is willing to integrate such feature. I am waiting for a review before starting, i've also heard about a "big refactoring" coming soon, so I am a bit afraid starting working on this.

alexandrebodin commented 5 years ago

Hi, We will be reviewing your RFC once we have released this refactor.

FYI, As long as we do not validate and merge the RFC into this repo any PR concerning this mater will not be considered for merging.

alexandrebodin commented 5 years ago

Hi @froger.

Thank you for this proposal. I don't really see any need for creating two plugins. The design just needs to account for the need to split the logic so authentication and authorization can be extend and plugged in with other providers independently for each other.

froger commented 5 years ago

Hi @alexandrebodin thanks for your answer ! I see your point, two plugins is maybe too much (don't know that much about strapi architecture yet). In fact my need is precisely to plug authentication and not authorization, in order to allow other kind of token validation that the default provided.

Maybe if the same plugin could provide two middlewares to separate concerns, it can be a nicer design.

The first one takes the Bearer token, validates it and define the decoded bearer as context. The second middleware would map the decoded bearer to an actual db user, and set their permissions / attributes.

With this design, It will be possible to customize authentication middleware and authorization to use external full-featured authorization server.

alexandrebodin commented 5 years ago

@froger We already are planing on opening up the plugin to make it really easy to use different authentication service (third parties, ldap...) and have an authorization layer based on that. We are considering using passportjs which already has all those features.

froger commented 5 years ago

@alexandrebodin thanks, I will follow update with attention. Just to be clear, I talk in this PR about the possibility of using Bearer tokens from another party and be able to stop using JWT's from strapi.

As I see the current project, I see the API authentication process really linked to the JWT from strapi. I am aware that passportjs will bring the ability to extend auth providers a lot, but it won't really help on the Bearer token parsing, as you will need a unique parser – opaque or encrypted JWT(JWE) won't really give you any informations. So here, using passportjs or not is not really relevant. To be more explicit, my idea was being able to customize something like :

// Called from the authentication middleware
parseTokenFromRequest(request) {
    // get the bearer token in the Authorization Header
    // validates signature, ask for introspection
    // return the payload you want
   // use passport or whatever you want
    return {
       sub: '12321-1231-12312-1232',
       email: 'hello@asd.com',
       locale: 'fr-CH'
    }
}

And then you save this query to a context like ctx['idToken'] = parseTokenFromRequest()

// Called from the authorization middleware 
userFromToken(idToken){
   // Match the user
   user = User.where({'id': idToken.sub}).first
   // Update metas with token values
   user.update({locale: idToken['locale']})
   return user;
}

And you define here your current user, and go on with permissions process.

alexandrebodin commented 5 years ago

@froger When using something la passportjs it means you can replace the authentication completely. So you can use your own jwt auth or a session auth. It would be up to you to do that.

alexandrebodin commented 4 years ago

Closing this for now as there are no new comments on it