У меня есть какое-то устаревшее приложение 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?