0

I have my Application set-up as following:

Resource

@Path("/books")
public class BookResource {
    @Inject
    BookService bookService;

    @Context
    SecurityContext securityContext;

    @GET
    public Response getBooks() {
        List<BookDTO> books = bookService.getAllBooks();

        return Response.ok(books).build();
    }
}

Service

public interface BookService {
    List<BookDTO> getAllBooks();
}

ServiceImpl

public class BookServiceImpl implements BookService {

    @Context
    SecurityContext securityContext;

    @Override
    public List<BookDTO> getAllBooks() {
        BookDTO book1 = new BookDTO("Catcher in the Rye");
        BookDTO book2 = new BookDTO("Moby Dick");

        return Arrays.asList(new Book[]{book1,book2});
    }
}

In my Resource, the SecurityContext is injected and i can fetch the current user.

Is there a way to inject the SecurityContext outside of the Resource (the place where i put my path annotations)? If so, how can I do this? I want to move my security back to the service and maybe repository too.

Update I solved it by the following code, but I think it can get a lot better/cleaner.

BaseResource

public class BaseResource {

    @Context
    SecurityContext securityContext;


    public class BaseRequest {

        private Principal principal;

        public BaseRequest() {
            principal = securityContext.getUserPrincipal();
        }

        public Principal getPrincipal() {
            return principal;
        }
    }
}

BookResource

public class BookResource extends BaseResource {

    @Inject
    BookService bookService;

    @Path("/{id}")
    public Response getBookById(@PathParam("id") Long id) {
        BookDTO book = bookService.getBookById(new GetBookRequest(id));

        return Response.ok(book).build();
    }

    public Response getAllBooks() {
        List<BookDTO > books = bookService.getAllBooks(new GetAllBooksRequest());

        return Response.ok(books).build();
    }

    public class GetBookRequest extends BaseRequest {

        private Long id;

        public GetBookRequest(Long id) {
            super();
            this.id = id;
        }

        public Long getId() {
            return id;
        }
    }

    public class GetAllBooksRequest extends BaseRequest {

        public GetAllBooksRequest() {
            super();
        }
    }
}

BookService

public interface BookService {

    public List<BookDTO> getAllBooks(GetAllBooksRequest request);

    public BookDTO getBookById(GetBookRequest request);
}

BookServiceImpl

@Named
public class BookServiceImpl implements BookService {

    @Override
    public List<BookDTO> getAllBooks(GetAllBooksRequest request) {
        Principal principal = request.getPrincipal();

        BookDTO book1 = new BookDTO();
        book1.setName("Catcher in the Rye");
        book1.setId(1L);

        BookDTO book2 = new BookDTO();
        book2.setName("Moby Dick");
        book2.setId(2L);

        return Arrays.asList( new BookDTO[]{ book1, book2 });
    }

    @Override
    public BookDTO getBookById(GetBookRequest request) {
        Principal principal = request.getPrincipal();

        BookDTO book = new BookDTO();
        book.setName("Catcher in the Rye");
        book.setId(request.getId());

        return book;
    }

}
Pascal W.
  • 3
  • 1
  • 6

1 Answers1

0

You don't need to inject anything. Use SecurityContextHolder insteed.

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
var principalName = authentication.getName();
Tomasz
  • 884
  • 8
  • 12