Giter Club home page Giter Club logo

Comments (5)

barsifedron avatar barsifedron commented on May 24, 2024

Hi

First, I am myself not really familiar with jwt.

But taking this tutorial as an example : https://javatechonline.com/how-to-implement-jwt-authentication-in-spring-boot-project/ (the step 9)

You could do :

1/ Add your authentication parameters to your command or to your query.

public class UseCaseCommand { 

    String token;

    ... your other regular parameters
}

2/ Create a middleware that validates your token like this (pseudo code)

public class JwtCommandBusMiddleware implements CommandBusMiddleware {

    private JWTUtil util;
    private UserDetailsService userDetailsService;

    @Inject
    public JwtCommandBusMiddleware(JWTUtil util, UserDetailsService userDetailsService) {
        this.util = util;
        this.userDetailsService = userDetailsService;
    }

    @Override
    public <T> CommandResponse<T> dispatch(Command<T> command, CommandBus next) {

        // Reading Token from your command
        String token = command.token;
        if (token == null) {

            // throw an error

        }

        String username = util.getSubject(token);

        if (username == null) {

            // throw an error

        }

        //if username is not null & Context Authentication must be null
        UserDetails user = userDetailsService.loadUserByUsername(username);
        boolean tokenIsValid = util.isValidToken(token, user.getUsername());
        if (!tokenIsValid) {

            // throw an error
        }

        // if you are here, then your token is valid.
        // just dispatch to the next middleware in line
        return next.dispatch(command);
    }}

you would need one for your commands and one for your queries.

3/ Change your CommandBusFactory and/or QueryBusFactory to add this middleware in the chain

return CommandBusMiddleware.compositeOf(
                       ...
                        transactionalMiddleware,
                        // add here or anywhere convenient in the chain
                        // Since it is auth, i would assume the earlier the better but withing the transaction?
                        jwtCommandBusMiddleware, // !!!!
                        new DomainEventsDispatcher(domainEventBus))
                .decorate(new MapCommandBus(commandHandlersRegistry.handlers()));

Since your new middleware will probably rely on Spring injection, you will need to inject it in the factory.

One disadvantage of this solution is that ALL your commands will now need to posses the authentication token. Depending on your use cases it might or not be an issue for you.

You could also deal with authentication before passing the command to the bus.

Alternatively, if you want authentication SOME of the time you could:

  • Have a default bus WITH authentication and instantiate one WITHOUT authentication for special cases
  • Have a default bus WITHOUT authentication and instantiate one WITH authentication for special cases

While it could turn into an anti pattern, if in moderation, it is totaly possible to instantiate different flavors of command buses depending on your use cases.

EDIT :

Another alternative, arguably better in some cases where you want authentication only some of the time, is to use a marker interface

public interface CommandToAuthenticate {
    String getToken();
}
public class UseCaseCommand implements Command<NoResult>, CommandToAuthenticate {

    private String token;

    // .. your other params

    @Override
    public String getToken() {
        return token;
    }
}
public class JwtCommandBusMiddleware implements CommandBusMiddleware {

    private JWTUtil util;
    private UserDetailsService userDetailsService;

    @Inject
    public JwtCommandBusMiddleware(JWTUtil util, UserDetailsService userDetailsService) {
        this.util = util;
        this.userDetailsService = userDetailsService;
    }

    @Override
    public <T> CommandResponse<T> dispatch(Command<T> command, CommandBus next) {

        if (!CommandToAuthenticate.class.isAssignableFrom(command.getClass())) {
            // no need to authenticate the command.
            // pass to the next middleware in line
            return next.dispatch(command);
        }

        // if here, your command requires authentication
        // ... proceed as decribed above
    }

This is obviously more complex but, in exchange, it gives you the flexibility to decide easily, when creating a command, if it should or not be authenticated.

from candid-cqrs.

barsifedron avatar barsifedron commented on May 24, 2024

Secondly, regarding event sourcing, while I believe this bus can be used for it, I personnaly did not do it and deliberately chose not to support this in this project exemples.

I would be happy to get feedback, if you ever chose to use it for such a project.

from candid-cqrs.

kipierre avatar kipierre commented on May 24, 2024

thank you very much Mrs Jean Michel for the this answer she is exactly what i wanted

from candid-cqrs.

kipierre avatar kipierre commented on May 24, 2024

and yes we will do event sourcing and I will get back to you soon

from candid-cqrs.

kipierre avatar kipierre commented on May 24, 2024

from candid-cqrs.

Related Issues (7)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.