We have a widlfy REST API jaxrs and we want to secure it with keycloak.
The problem is the integration with #SecurityDomain("keycloak") is working only with an EJB entry-point. it is ignored on class with no #Stateless annotation
The issue is the entry point become an EJB and EJB poolManaged what is not really a good thing for a stateless application.
Moreover all methods in EJB are transactional and we do not want this behavior. So yes we can add an annotation transactional to specify to not use transaction in the method, but i think it is a workaround.
We want to work the most we can with CDI. and have entry point with ejb pool management with in wildlfy 20 EJB in same time can be a bottleneck in a big application.
Any idea ? or proper way to implement keycloak security with CDI ?
If you mean declarative security using #RolesAllowed annotation this is not supported on all CDI beans, is only supported by EJBs and Servlets.
As JAX-RS will run on a webapp, you can use declarative security based on url-patterns and HTTP methods using security-constraints in web.xml
You can also implement programmatic security in the JAX-RS methods (or in a filter), using the SecurityContext.
#Context
SecurityContext securityContext;
#GET
public Response get() {
if (securityContext.isUserInRole("ROLE")) {
....
}
....
}
Although not and standard feature, Wildfly JAX-RS implementation, RestEasy, can be configured to support #RolesAllowed annotations. See:
https://docs.jboss.org/resteasy/docs/4.4.2.Final/userguide/html/Securing_JAX-RS_and_RESTeasy.html
Related
I know that EntityManager instantiated by myself is not thread-safe.
I know that EntityManager injected via #PersistenceContext in EJB behaves like hread-safe, because EJB container serializes access to EJB beans.
I know that in EJB injected EntityManager is really a proxy.
I know that when I inject EntityManager via #PersistenceContext to #Dependent CDI bean and inject that bean to EJB, it behaves like thread-safe because of covering EJB (I believe that in this case EntityManager is proxy too).
But:
What happens when I inject EntityManager via #PersistenceContext to CDI bean and use this bean directly for example in Servlet? I believe that this EntityManager is a proxy, so does this proxy guarantee thread safety?
Edit: Similar question Java CDI #PersistenceContext and thread safety does't solve my problem, because accepted answer shows EJB examples, not CDI examples.
Edit: I checked source code of WildFly application server and it looks that WildFly uses thread-safe proxy in CDI. This proxy selects real EntityManager when needed. Real EntityManagers are kept in special structure - stack of maps of EntityManagers in ThreadLocal.
https://www.javacodegeeks.com/2013/06/jpa-2-entitymanagers-transactions-and-everything-around-it.html says:
The biggest benefit of using Transaction Scoped Entity Manager is that
it is stateless. This also makes the Transaction Scoped EntityManager
threadsafe and thus virtually maintenance free
also pro JPA book says:
a transaction-scoped entity manager is stateless, meaning that it can
be safely stored on any Java EE component
I have demo application with JPA 2.1 and weblogic 12.1.3 deployment works fine and am able to get EntityManager which is annotated on the stateless bean.
I have application where I have ejb-jar.xml, on this file we have configured all MDB and session beans, Note: application is not using annotation.
And ejb-jar.xml uses http://java.sun.com/dtd/ejb-jar_2_0.dtd(ejb 2), but our application is running on weblogic 12.1.3. On this configuration, I tried to get EntityManager with the help of annotation in MDB, but am getting null object.
Question.
1. Is it possible to annotate EntityManager, with above configuration.
2. If not possible what are alternative ways. meaning I need to move all the configuration of ejb-jar.xml to annotation.
Thanks
Daya
I enabled LTW for my Spring application and as long as the advised bean in question is free of Spring's AOP features, the classes are woven properly - that is, in-method bytecode modification rather than proxies.
However, once I add tx:annotation-driven and #Transactional to that bean, all methods, even those having nothing to do with Spring features, that previously were woven with proper bytecode, now all get called via JDK proxy.
Which probably means I have to let go of tx:annotation-driven and configure AspectJ to use Spring's tx:advice for methods annotated with Spring's #Transactional.
But how do I access Spring beans from AspectJ configuration?
The only solution I found is to add AspectJ compiler to the build toolchain and implement the AbstractTransactionAspect.aj aspect and on Spring startup call TheImplementedAspect.aspectOf().setTransactionManager().
First I will describe what I am trying to accomplish here. I have a Java application that periodically reads data and calls stateless EJB on JBoss AS 7.1.1 for further operations (computing data and saving it into the DB). Then I have front end which uses JSF 2.0. In controller which is a #ApplicationScoped CDI bean and resides in JSF project I inject EJB into it. Now I need EJB for getting data from the DB. I am using #ApplicationScoped CDI bean because of this reason:
The application context is shared between all servlet requests, web service invocations, EJB remote method invocations, EJB asynchronous method invocations, EJB timeouts and message deliveries to message-driven beans that execute within the same application. The application context is destroyed when the application is shut down.
I want only one CDI bean for all the clients, because the data is independent of the user.
Now I want to update data in #ApplicationScoped CDI bean, which is defined under JSF project with the help of EJB bean, which method is executed when new data arrives. I have already successfully used #Inject in #ApplicationScoped CDI bean, where I have injected EJB from EJB project. Now I want to do the other way around. I tried to inject ApplicationScoped CDI bean from JSF project into EJB bean. But when I wrote this I got #Inject underline as warning:
#Inject
private CurrentDataController currentDataController;
The warning is:
No bean is eligible for injection to the injection point [JSR-299 ยง5.2.1]
When I try to publish project I get error about class not found exception for CurrentDataController.
Caused by: java.lang.ClassNotFoundException: controllers.CurrentDataController from [Module "deployment.TestEAR.ear.TestEJB.jar:main" from Service Module Loader]
It seems that the EJB project can't reference class in JSF project. Also it is looking for CurentDataController class in TestEJB.jar instead of in the TestJSF.jar. What I am missing here?
The structure of my whole project is as follow:
TestEAR
TestEJB
TestEJBClient
TestJPA
TestJSF
Now I reckon that after I will fix the error about no class definition found I will have another problem connected with the warning I have posted.
In an EAR the EJB modules (jar) don't have visibility on the Web modules (war). EJB module is UI agnostic so it's normal to have this layer decoupling.
To resolve you issue you have two options.
Move the bean that need to be injected in your EJB in one EJB module (the war would also be able to inject that bean)
Refactor your app to have only a war (yes you can have EJB in war now). Architecture would be simplier and full EJB will work under JBoss (remote EJB too)
is it possible to create something like static object using EJB3 in Jboss. in other words i need to create something like a static object using singleton pattern or something like that, that is because i need to preload a configuration from database and i want that every bean that jboss creates uses this class to read this configuration instead of that every bean load it from the database.
Cheers,
EJB 3.1 does have a standard #Singleton annotation but EJB 3.0 doesn't. However, JBoss offers a JBoss extension to the EJB 3.0 spec to create a singleton with the #Service annotation.
From the JBoss EJB 3.0 Reference Documentation:
Chapter 6. JBoss EJB 3.0 extensions
JBoss provides a few extensions to the
EJB 3.0 spec. This chapter describes
those features here.
6.1. #Service EJBs
An extension offered by JBoss EJB 3.0
is the notion of a
#org.jboss.annotation.ejb.Service
annotated bean. They are singleton
beans and are not pooled, so only one
instance of the bean exists in the
server. They can have both #Remote and
#Local interfaces so they can be
accessed by java clients. When
different clients look up the
interfaces for #Service beans, all
clients will work on the same instance
of the bean on the server. When
installing the bean it gets given a
JMX ObjectName in the MBean server it
runs on. The default is
jboss.j2ee:service=EJB3,name=<Fully qualified name of #Service bean>,type=service
You can override this default
ObjectName by specifying the
objectName attribute of the
#Service annotation.
References
JBoss EJB 3.0 Reference Documentation
6.1. #Service EJBs
JBoss EJB3 Tutorials
Chapter 28. Service POJOs (JBoss extension of EJB3)
Bean with #Singleton annotation should work. Place your database initialize code in #PostConstruct & can release/cleanup in #PreDestroy.