Java 如何从RESTAPI WAR访问主应用程序WAR中使用的远程ejb
我使用JAX-RS实现了一些遗留的JEE应用程序和RESTAPI模块(都是WAR打包的),JAX-RS在过去作为POC引入。现在我需要让这两个人互相交谈 所有的战争都部署在ApacheTomee上 例如,我有这样的情况 端点类Java 如何从RESTAPI WAR访问主应用程序WAR中使用的远程ejb,java,security,jakarta-ee,jax-rs,ejb,Java,Security,Jakarta Ee,Jax Rs,Ejb,我使用JAX-RS实现了一些遗留的JEE应用程序和RESTAPI模块(都是WAR打包的),JAX-RS在过去作为POC引入。现在我需要让这两个人互相交谈 所有的战争都部署在ApacheTomee上 例如,我有这样的情况 端点类 @Path("/somepath") @Stateless public class Endpoint { @EJB private ServiceBean bean; @Since(CommonParams.VERSION_1) @GET @Pro
@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);
}
}
@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");
}
}
Bean类
@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);
}
}
@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");
}
}
问题在于,每当我尝试调用GET endpoint时,都会出现以下异常情况:
javax.ejb.EJBAccessException: Unauthorized Access by Principal Denied
我试图实现一些Servlet过滤器来管理身份验证(BasicAuth),但是即使我能够通过这种方式进行身份验证,上面提到的错误仍然存在
验证过滤器类
@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);
}
}
@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");
}
}
你们知道这有什么不对吗?我遗漏了什么吗?您的EJB由管理员角色保护。您确定要与具有此角色的用户进行身份验证吗?