Как получить доступ к удаленному ejb, используемому в основном приложении WAR, из REST API war - PullRequest
1 голос
/ 25 апреля 2019

У меня есть какое-то устаревшее приложение JEE и модуль REST API (оба упакованы с WAR), реализованные с использованием JAX-RS, который был представлен как POC в прошлом. Теперь мне нужно кое-что заставить этих двоих поговорить друг с другом.

Все WAR затем развертываются на Apache TomEE.

Например, у меня такая ситуация

Класс конечной точки

@Path("/somepath")
@Stateless
public class Endpoint {

@EJB
private ServiceBean bean;

   @Since(CommonParams.VERSION_1)
   @GET
   @Produces(MediaType.APPLICATION_JSON)
   public Response getSomeContent(@Context UriInfo uriInfo, @BeanParam SomeParams params) {
       return getContent(uriInfo, bean.getSomeContent(), params);
   }

}

Класс бобов

@DeclareRoles("ADMIN")
@Stateless
@Remote(SomeService.class)
@Local(SomeServiceLocal.class)
public class ServiceBean {
   // Methods with @RolesAllowed("ADMIN") annotations
}

Проблема в том, что всякий раз, когда я пытаюсь вызвать конечную точку GET, TomEE отвечает с таким исключением:

javax.ejb.EJBAccessException: Unauthorized Access by Principal Denied

Я пытался реализовать какой-нибудь Servlet Filter для управления аутентификацией (BasicAuth), но даже если я могу аутентифицировать таким образом, ошибка, упомянутая выше, все еще сохраняется.

Класс фильтра Auth

@WebFilter(
        urlPatterns = "/*",
        initParams = {              
                @WebInitParam(name = "realm", value = "realm")
        })
public class AuthFilter {
        private String realm = "realm";

        private  InitialContext context;

        @Override
        public void init(FilterConfig filterConfig) throws ServletException {     

                String paramRealm = filterConfig.getInitParameter("realm");
                if (!Strings.isNullOrEmpty(paramRealm)) {
                        realm = paramRealm;
                }
        }

        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
                throws IOException, ServletException {

                HttpServletRequest request = (HttpServletRequest) servletRequest;
                HttpServletResponse response = (HttpServletResponse) servletResponse;

                String authHeader = request.getHeader("Authorization");
                if (authHeader != null) {
                        StringTokenizer st = new StringTokenizer(authHeader);
                        if (st.hasMoreTokens()) {
                                String basic = st.nextToken();

                                if (basic.equalsIgnoreCase("Basic")) {
                                        try {
                                                String credentials = new String(
                                                        Base64.decodeBase64(st.nextToken()), "UTF-8");
                                                log.info("Credentials: " + credentials);
                                                int p = credentials.indexOf(":");
                                                if (p != -1) {
                                                        String _username = credentials.substring(0, p).trim();
                                                        String _password = credentials.substring(p + 1).trim();

                                                        Properties props = new Properties();
                                                        props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.RemoteInitialContextFactory");
                                                        props.setProperty(Context.PROVIDER_URL, "ejbd://localhost:4201");
                                                        props.setProperty(Context.SECURITY_PRINCIPAL, _username);
                                                        props.setProperty(Context.SECURITY_CREDENTIALS, _password);
                                                        props.setProperty("openejb.authentication.realmName", realm);

                                                        try {
                                                                getServletContext();
                                                                context = new InitialContext(props);

                                                        } catch (NamingException e) {
                                                                e.printStackTrace();
                                                        }

                                                        filterChain.doFilter(servletRequest, servletResponse);
                                                } else {
                                                        unauthorized(response, "Invalid authentication token");
                                                }
                                        } catch (UnsupportedEncodingException e) {
                                                throw new Error("Couldn't retrieve authentication", e);
                                        }
                                }
                        }
                } else {
                        unauthorized(response);
                }


        }

        @Override
        public void destroy() {             
        }

        private void unauthorized(HttpServletResponse response, String message) throws IOException {
                response.setHeader("WWW-Authenticate", "Basic realm=\"" + realm + "\"");
                response.sendError(401, message);
        }

        private void unauthorized(HttpServletResponse response) throws IOException {
                unauthorized(response, "Unauthorized");
        }
}

Ребята, вы понимаете, что с этим может быть не так? Я скучаю по soment?

...