CDI doesn't inject a naked CDI bean as a dependency, but a proxy that redirects to the contextual object of the active scope. This proxy class does not have your annotation.
See https://issues.jboss.org/browse/CDI-10 for how to unwrap the proxy.
Question
I'm using a custom annotation security as described in this link. I'm upgrading my jsf managed beans from @ManagedBean to @Named (CDI). Since the CDI does not support the scope @ViewScoped, i'm using org.omnifaces.cdi.ViewScoped. However, in this case, this check fails if method.isAnnotationPresent(Permissao.class){}
. How should I adapt my security check to use with CDI + ViewScoped from Omnifaces?
Edit
Using @ManagedBean/ViewScoped(jsf) instead of @Named/ViewScoped(cdi + omnifaces) works.
The problem occurs in this line if (metodo.isAnnotationPresent(Permissao.class)) {}
public void verificaPermissaoAcesso(ActionEvent event) {
final FacesContext facesContext = FacesContext.getCurrentInstance();
UIComponent source = event.getComponent();
ActionSource2 actionSource = (ActionSource2) source;
MethodExpression methodExpression = actionSource.getActionExpression();
String expressao = methodExpression.getExpressionString(); // #{nomeManagedBean.nomeMetodo(param)}
String nomeManagedBean = expressao.substring(0, expressao.indexOf('.')).substring(2);
String nomeMetodoComParenteses = expressao.substring(expressao.indexOf('.') + 1);
String nomeMetodo = nomeMetodoComParenteses.substring(0, nomeMetodoComParenteses.indexOf("("));
ELContext elContext = facesContext.getELContext();
ExpressionFactory factory = facesContext.getApplication().getExpressionFactory();
ValueExpression ve = factory.createValueExpression(elContext, "#{" + nomeManagedBean + '}', Object.class);
//Object jsfManagedBean = ve.getValue(elContext);
Context ctx = bm.getContext(org.omnifaces.cdi.ViewScoped.class);
Bean bean = bm.resolve(bm.getBeans(nomeManagedBean));
Object jsfManagedBeanProxy = ctx.get(bean);
List<Method> listaMetodos = Arrays.asList(jsfManagedBeanProxy.getClass().getMethods());
for (Method metodo : listaMetodos) {
if (nomeMetodo.equals(metodo.getName())) {
if (metodo.isAnnotationPresent(Permissao.class)) {
Permissao anotacaoSeguranca = metodo.getAnnotation(Permissao.class);
SegurancaUtil.verificar(anotacaoSeguranca.acoes());
break;
}
}
}
}
My annotation class
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Permissao {
String[] acoes();
}
My annotated method in jsf managed bean
@Permissao(acoes={"permission1", "permission2"})
public void myMethod(long id) {}
Edit 2 - Solution by @meriton
Context ctx = bm.getContext(org.omnifaces.cdi.ViewScoped.class);
Bean bean = bm.resolve(bm.getBeans(nomeManagedBean));
Object jsfManagedBeanProxy = ctx.get(bean);
Solution
CDI doesn't inject a naked CDI bean as a dependency, but a proxy that redirects to the contextual object of the active scope. This proxy class does not have your annotation.
See https://issues.jboss.org/browse/CDI-10 for how to unwrap the proxy.