Equivalent Spring #Controller with #RequestMapping("/endpoint"), but using Java EE 8 only - jsf

So I'm working on implementing Oath2 authentication to allow my app to access Intuit Quickbooks company resources (items, customers, etc).
Intuit provides working examples using Spring, but I'm developing my app using JavaEE 8 with GlassFish5.
The Spring sample app callback contoller is structured as follows:
#Controller
public class CallbackController {
...
#RequestMapping("/oauth2redirect")
public String callBackFromOAuth(#RequestParam("code") String authCode, #RequestParam("state") String state, #RequestParam(value = "realmId", required = false) String realmId, HttpSession session) {
...
//after successful validation
return "connected";
This is the redirect handler controller; which address it's configured at the intuit portal (in this case, http://localhost:8080/oauth2redirect) that will be called after user approves the app and intuit will send back authorization code to this url.
So I'm a bit stuck finding what's the equivalent Spring callback redirect handler in JavaEE.
Is a #WebServlet or #WebService needed here? But then it wouldn't integrate nicely with JSF to just return the "connected" string so that it redirects to desired page (in this case connected.xhtml).
Not looking for workarounds, but the correct and standard way of implementing this on JavaEE. If you can point me to some sample apps out there or tutorials I would greatly appreciate it.
Thanks a lot in advance!
Here's full source code for callback handler controller and the full sample app.

There is at least not a really good alternative in JSF. Yes, you could 'abuse' JSF but there are other, better standards for this and this is (almost) what Spring also does. If you read the Spring Specs , you'll see the word 'Rest' being used a lot.
Well, there is a real java standard called 'Jax-RS' that is the standardized counterpart of what you do in spring.
This provides a decent analysis of the two So Jax-RS is the way to go.
But a #WebServlet or #WebService integrate perfectly with JSF. You can store any authentication information in the session and use that from JSF. No problem at all.

Related

OpenNTF Domino API: "org.openntf.domino.utils.Factory is not initialized for this thread"

I'm trying to implement OpenNTF Domino API as a replacement in our project but it fails with this message:
"OpenNTF Domino API: org.openntf.domino.utils.Factory is not initialized for this thread!"
Code snippet:
boolean init = Factory.isInitialized(); // false
Database db = Factory.getSession().getCurrentDatabase(); // This fails of course because no Session
I'm implementing the call in a JAVA DAO behind a EXTLib Servlet in XPages.
So it's not called by an XPage but as an REST API call.
The Domino API Demo DB is working so the server install seems to be OK.
Is there a setup, properties I'm missing to init it ?
Yes, there is specific setup require for non-XPages access, as done in OsgiWorlds on OpenNTF. Nathan has added a DAS extension specifically for REST access from Graph database. You basically need to initialise the session for the Factory before trying to access it, generally done in the Servlet when it initiates the HTTP connection. Please contact me on Twitter (Paulswithers) so the team can work with you. Also it's worth you having a look at the OsgiWorlds source code. Although that's for a Vaadin servlet and allows defining a development user to run as, in production mode it also uses the logged on user name and the configuration class and calls to it from the servlet are effectively what you need from the REST servlet.

Liferay Spring Rest services

Is there a way to expose a Java rest web service in Liferay but not in a portlet, that can receive JSON request and store the data in Journal Article?
Therefore when a user logs into Liferay they will be see web content
Yes there is : JSONWebServiceActionsManagerUtil.registerJSONWebServiceAction
For instance :
Class<?> serviceImplClass;
Method serviceMethod;
Object serviceImpl;
String path = jsonWebServiceMappingResolver.resolvePath(serviceImplClass, serviceMethod);
String method = jsonWebServiceMappingResolver.resolveHttpMethod(serviceMethod);
JSONWebServiceActionsManagerUtil.registerJSONWebServiceAction("/yourwspath", serviceImpl, serviceImplClass, serviceMethod, path, method);
You should then be able to see the new web service in http://SERVER/api/jsonws
Well yes, Liferay has a full API (even JSON-based, SOAP optional, no classic REST though) that you can use. A simple Stackoverflow answer is not the right place to give a full introduction on how to work with Liferay's API, but you might want to look up Servicebuilder (which is used to create Liferay's API) and then look at JournalArticleService and related services: The Web Content Management API is called "Journal" in Liferay (for historical reasons)

Are jaxrs 1.1 (WLP 8.5) annotated methods thread safe?

I am using jaxrs1.1 jar shipped with Websphere liberty profile 8.5 for creating REST WebService.
Lets suppose we have a method addNewProject as shown below :
If many people call this webservice method to add project concurrently. using link below , are there any concurrency issue? In servlet, each request is a separate thread , is it the same case here or should we handle concurrency by ourselves ?
endpointLink: http://somehost.com/path1/path2/addprojectdetails and POST the JSON object.
#POST
#Path("addprojectdetails")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response addNewProject(ProjectDetails projectdetailsObj) {
return Response.status(200).entity("Project"+projectdetailsObj.getProjectname()+"successfully added").build();
}
I'm not sure what kind of concurrency issues you might be thinking of. The object itself can be either a singleton or request scoped (if using CDI) or a stateless session bean (if using EJB). If you're using a singleton, then you may need to be thread aware and not store state within the class.
It would probably help to understand what kind of concurrency issues you had in mind to answer more thoroughly.

JSF: Authentication & Authorization, best way forward

I've spent all day Googling and looking at various questions on here, trying to come up with the best solution for implementing authentication and authorization. I've come up with part of the solution now, but am hoping someone can fill in the gaps. I realise there is a lot of text below, but please bear with me :O)
Background
I have inherited a part completed CRM application which currently uses JSF 2.0, JavaEE 6, JPA and a PostgreSQL database. Unfortunately, the guys who originally started building this web app in their infinite wisdom decided that it would be best to leave authentication/authorization to the end - I've now got to put it in.
The application is essentially split into three layers - the views, the managed beans and the DAO's. This means that the managed beans are particularly 'fat' since they contain all of the business logic, validation and navigation logic.
Authentication/Authorization requirements
Forms based authentication, validating against credentials stored in the PostgreSQL database.
The only page that will be publicly accessible (by anonymous users) will be the login page.
I need to prevent access to certain areas of the application based on a users role. For example, only users with the 'Admin' role should be able to access the create/edit user page.
I also need to be able to restrict access to certain area's of a page. For example, a user with the 'Sales Rep' role should be able to view a customers details, but the save/edit button should only be displayed if the user has the 'Customer Service' role.
Where I'm at
The first thing I plan on doing is to follow this User Authentication and Authorization using JAAS and Servlet 3.0 Login example. This I believe will fulfil my first 3 requirements.
In order to show/hide save buttons etc on pages, I can use the technique described in this SO answer. This will partly solve requirement 4, however I think that I still need to secure the action methods and or the managed beans themselves. For example, I would like to be able to add an annotation or something to the save() method on the customer bean to ensure that only users with the 'Customer Service' role can call it - this is where I begin to run into issues.
I guess one option would be to do something similar to what I am proposing to do in the view and use facesContext to check if the current user "is in role". I'm not keen on this as it will just clutter up my code and would rather use annotations instead. If I did go down this route however, how would I return a http 403 status?
The javax.annotation.security.* annotations seem to be a good fit for declaritively defininig access to areas of the application, however as far as I understand, they can only be added to EJB's. This would mean that I would need to move all of my business logic out of the managed beans where it currently resides to new EJB's. I think this would have the added benefit of separating the business logic out into it's own set of classes (delegates, services or whatever you chooses to call them). This would be quite a large refactor however which isn't going to be aided by a lack of unit test or integration tests. I'm not sure whether the responsibility of access control should be at this new service level either - I think it should be on the managed beans.
Other alternatives
During my research I have found lots of people mentioning frameworks such as Spring and Seam. I have some limited experience with Seam, I think it would have been a good fit for this project and from what I recall I believe it solves the authorization issues I am having, but I think it is too late in the day to introduce it now.
I have also seen Shiro mentioned in various places. Having looked at the 10 minute tutorial this seemed like a good fit, especially in conjunction with Deluan Quintao's taglib but I have been unable to find any tutorials or examples of how to integrate it with a JSF web app.
The other alternative I have come across surprisingly regularly is implementing a custom solution - this seems crazy to me!
Summary
In summary then, I'd really like some guidance on whether I'm heading down the right path in terms of implementing authentication and authorization and how I fill in that missing piece of securing individual methods and/or managed beans (or at least the code they delegate to) and/or how I can manually return a HTTP Status 403.
Have you tried anything with Spring Security - Latest being version 3
http://janistoolbox.typepad.com/blog/2010/03/j2ee-security-java-serverfaces-jsf-spring-security.html
http://ocpsoft.org/java/jsf-java/spring-security-what-happens-after-you-log-in/
rather than using a request filter or using JAAS, spring security is a comprehensive security framework that will resolve most of your security concerns .
You can use it to authenticate a user using a db realm, authorize him and redirect as necessary based on the provided authentication information.
you can secure the methods that you have written
http://blog.solidcraft.eu/2011/03/spring-security-by-example-securing.html
#PreAuthorize("hasRole('ROLE_XXX')") is the way
to make certain elements of a page secure..
//content
more reading and examples
http://static.springsource.org/spring-security/site/petclinic-tutorial.html
After carrying out a lot of research I have come to the conclusion that firstly the requirements of my application would benefit from being deployed to an application server that fully implements the Java EE specification, rather than a servlet container like Tomcat. As the project I am working on uses Maven, the key thing here was getting the dependencies set up correctly - this wasn't easy and took a fair bit of googling and trial and error: I'm sure there is a more scientific approach that could be taken.
I then had to create a mysql module to get my application to talk to the database properly and then remove the factory that had been implemented to create DAO's and convert them to EJB's instead. I also had to update hibernate.cfg.xml to reference the datasource I added and persistence.xml to set the transaction type to JTA and also reference the JTA data source. The only other complication was that the Open Session In View pattern was being used which meant I ended up with hibernate lazy initialization errors when entities were accessed in the views. I reimplemented the filter as shown at the bottom of this answer, to get around this. I see this as a temporary measure to get things working again before I can hopefully refactor this area and remove the need for the filter.
Moving to JBoss took just over a day and I'm sure it could have been done much quicker if I was more experienced with Java EE and Maven. Now that I'm at that point I'm in a good position to be able to drop seam 3 security into the project and utilise that, rather than trying to hack together a solution which is essentially the direction I was going to take. The nice thing about Seam 3 is that you can to a certain extent pick and choose which modules you use rather than having to add the entire framework (like Seam 2). I think a number of the other modules are going to be helpful as well however and will help me amongst other things get rid of the open session in view pattern.
One thing that did concern me with using Seam was that I was told about DeltaSpike. This seems as though it will probably replace seam and there are no plans for any more versions of seam. I have decided that since seam is still being supported and if DeltaSpike takes as long to come to fruition as seam 3, then it is pretty safe to use seam 3.
I will hopefully get round to writing a proper blog post describing this migration in proper detail.
public class OSVRequestFilter implements Filter {
private static final String UserTransaction = "java:comp/UserTransaction";
private static Logger logger = LoggerFactory.getLogger(EntityManagerRequestFilter.class);
public void init(FilterConfig config) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if (request instanceof HttpServletRequest) {
doFilter(request, response, chain, getUserTransaction());
}
}
private UserTransaction getUserTransaction() throws ServletException {
try {
Context ctx = new InitialContext();
return (UserTransaction)PortableRemoteObject.narrow(ctx.lookup(UserTransaction), UserTransaction.class);
}
catch (NamingException ex) {
logger.error("Failed to get " + UserTransaction, ex);
throw new ServletException(ex);
}
}
private void doFilter(ServletRequest request, ServletResponse response, FilterChain chain, UserTransaction utx) throws IOException, ServletException {
try {
utx.begin();
chain.doFilter(request, response);
if (utx.getStatus() == Status.STATUS_ACTIVE)
utx.commit();
else
utx.rollback();
}
catch (ServletException ex) {
onError(utx);
throw ex;
}
catch (IOException ex) {
onError(utx);
throw ex;
}
catch (RuntimeException ex) {
onError(utx);
throw ex;
}
catch (Throwable ex){
onError(utx);
throw new ServletException(ex);
}
}
private void onError(UserTransaction utx) throws IOException, ServletException {
try {
if ((utx != null) && (utx.getStatus() == Status.STATUS_ACTIVE))
utx.rollback();
}
catch (Throwable e1) {
logger.error("Cannot rollback transaction", e1);
}
}
public void destroy() {
}
}

Render mobile version of login in Secure class Play! Framework

Is it possible to somehow override the login method of the Secure.java class of the Secure-Module in Play! Framework, so that another version of the login form is displayed?
In my case, i want to display a mobile version of the login-form if a mobile browser is detected.
I know i should not change the Secure.java class itself, but i don't really see any other solution to this problem.
As discussed in other posts you have the request in your Play! controller. So in this request you could ask which agent is trying to view your website:
String agentInfo = request.headers.get("user-agent");
The you can determine which template will be rendered for this agent:
if (agentType.isWhatEverHeIs) {
renderTemplate("Application\mobileTemplateForBadPractise.html");
} else {
render();
}
But what I would encourage you to do is responsive webdevelopment. Create your templates as smart as possible, let the template and css and javascript do this and keep your business logic in your controller.
You could use the Twitter Bootstrap to achieve this, but there are many more! Like Skeleton.
You even got the request object inside your templates so that you can optionally render things in your template (or not) based on the agent.
Even simpler, simply create/override the secure/login.html template and use responsive design : media queries. No need to change the controller or check agent or whatever.

Resources