I've a Java GAE app that should clear the memcache whenever I deploy a new version of the app. I'm using static initializer, i.e.
static {
MemcacheServiceFactory.getMemcacheService().clearAll();
}
However, that would clear the memcache as well whenever a new instance is started, which is not desired behavior.
What is the proper way to execute initialization code?
TIA
I create my memcache keys using a factory and they always get appended with the version number of my app so when i upload a new version, the keys are new I forget about the old cached values, which will go away on their own.
I also have a servlet defined in web.xml with a security constraint for admin only, then I browse to it's URL (/admin/example) manually after an upgrade - logging in as as admin. The servlet has my run once code in it to kick off any tasks for upgrading store data and purging the cache.
<security-constraint>
<web-resource-collection>
<url-pattern>/admin/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
One time initializations of applications can be done in the init() method of the Servlet. Here is an example
public class CatalogServlet extends HttpServlet {
private BookDB bookDB;
public void init() throws ServletException {
bookDB = (BookDB)getServletContext().
getAttribute("bookDB");
}
In the above example, the ServletContext attribute is, of course, just a variable that exists between servlet calls (the normal way to maintain state). This, of course, assumes that you somewhere else stored this variable in the ServletContext. The other way is to create the variable in the deployment descriptor.
To set initialization parameters within your deployment descriptor (web.xml), here is an example:
<servlet
<servlet-name...
<servlet-class ...
<init-param>
<param-name>param1</param-name>
<param-value>value1</param-value>
</init-param>
</servlet>
If this doesn't answer it, please clarify "whenever a new instance is started".
Related
I'm implementing role-based authorization in my application following the structure of the java ee 8 jwt security sample: https://github.com/javaee-samples/javaee8-samples/tree/master/security/jwt.
I have a back-end application with session-based security and JSF. Authentication and Authorization is managed by a WebFilter:
#WebFilter(urlPatterns = "/faces/*")
public class AuthorizationFilter implements Filter {
}
I have a REST api with JWT token-based security where I want to implement HttpAuthenticationMechanism for managing authentication and authorization.
I want these two different security mechanisms to live next to each other for personal interest and to prove that I can implement both ways. However, the HttpAuthenticationMechanism gets called everytime, also when browsing my JSF application. This leads to triggering of both mechanisms that are conflicting.
Is it possible to apply the HttpAuthenticationMechanism to only a certain url path? Like the urlPattern that's used in WebFilter? If so, how does one?
I want to use the HttpAuthenticationMechanism only to be triggered in my rest application:
#ApplicationPath("rest")
public class RestApplication extends Application {
public RestApplication() {
}
}
There is a method "isProtected" in HttpMessageContext which will set to true/false depending on the security-constraints in web.xml
public AuthenticationStatus validateRequest(HttpServletRequest request,
HttpServletResponse response, HttpMessageContext httpMessageContext) throws AuthenticationException {
if (!httpMessageContext.isProtected()) {
return httpMessageContext.doNothing();
}
...
So the first thing to do is check isProtected and only continue if the resource is supposed to be protected.
Now you can use security-constraint in web.xml as usual:
...
<security-constraint>
<web-resource-collection>
<web-resource-name>Restricted</web-resource-name>
<description>Declarative security tests</description>
<url-pattern>/protected/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>somegroup</role-name>
</auth-constraint>
<user-data-constraint>
<description>no description</description>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
<security-role>
<description>Somegroup</description>
<role-name>somegroup</role-name>
</security-role>
...
Now authentication will only be done for URLs below the /protected/* pattern, anything else will be available unprotected
Wondering why this is not addressed in most of the tutorials/examples out there...
Credits goes to this link which seems to be the only one describing this (althoug there is a a missing "NOT" in the Listing No 16)
https://www.informatik-aktuell.de/entwicklung/programmiersprachen/authentication-mit-java-ee-8.html
I am not sure what I am doing wrong here but when I put the faces context twice in the URL it bypasses all of my Realm Securities.
My URL Pattern:
<servlet-mapping>
<servlet-name>Faces</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
Security Constraint
<security-constraint>
<display-name>ADMIN</display-name>
<web-resource-collection>
<web-resource-name>Protected Admin Area</web-resource-name>
<description/>
<url-pattern>/faces/admin/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<description/>
<role-name>ADMIN</role-name>
</auth-constraint>
<user-data-constraint>
<description/>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
So when i goto: http://domain.com/faces/admin/index.xthml i do get the proper response i am looking for.
But if i goto: http://domain.com/faces/faces/admin/index.xhtml it completely lets me in regardless of the fact that the servlet is slated to be at /admin* I am assuming the * at the end of admin is what is causing it. But how can I solve this to where domain.com/faces/faces is invalid, and only domain.com/faces is valid?
I cannot seem to find anyone else facing this issue. So i must be doing something wrong.
Thank you
First, the good news: You're not doing anything wrong.
To solve: Use the extension mapping variant on the FacesServlet
<servlet-mapping>
<servlet-name>Faces</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
The bad news: This might be a bit of an oversight (read:flaw) in the request matching model.
My hypothesis is that the URL matching model of the FacesServlet doesn't work well with the standard servlet container request matching model.
In an ideal situation (without JSF), /faces/faces/admin/index.xhtml must correspond either a servlet or a specific resource. The container will attempt to verify if it's a valid resource and then whether the resource is a constrained resource.
The problem here is that the container takes the resource constraints very literally, meaning that it looks for the closest literal match to that URL in the security table. If it doesn't resolve the resource as being restricted, it serves the resource without interfering.
When you define /faces/admin/* as a protected resource, request a /faces/faces/admin/admin.xhtml and then also have a /faces/* servlet mapping, the container attempts to verify that /faces/faces/admin/index.xhtml is a constrained resource (and it's not). Since the container has no reason to hold up the request any further, it hands the request over to FacesServlet and then FacesServlet appears to just blindly strip all references to faces in the requestURL (because you've said OK to /faces/*) and serve anything that's left.
This is the reason why the file-extension servlet definition appears to be immune to it; in the case of the file extension mapping, the FacesServlet must find a literal resource in your folder structure that corresponds to that URL even before the container gets to determine that the resource is constrained or not
Verify this theory and there might be a need to file a critical JIRA with the mojarra team.
Is it possible to use static variables in my project to store data for all Servlets (they are in one .war file) and different requests? (It's not data that belongs to a distinct session)
data for all Servlets
You can use ServletContext for this.
Defines a set of methods that a servlet uses to communicate with its servlet container, for example, to get the MIME type of a file, dispatch requests, or write to a log file.
There is one context per "web application" per Java Virtual Machine. (A "web application" is a collection of servlets and content installed under a specific subset of the server's URL namespace such as /catalog and possibly installed via a .war file.)
For example: in web.xml
<context-param>
<param-name>param</param-name>
<param-value>Myname is web xml</param-value>
</context-param>
In your servlet
public class ParameterServlet extends HttpServlet {
---
public void init(ServletConfig config) throws ServletException {
super.init(config);
ServletContext context = getServletContext();
name= context.getInitParameter("param");
}
A complete example here.
For Objects
setting
getServletContext().setAttribute("myObj", obj);
getting
MyObj attribute = (MyObj)getServletContext().getAttribute("myObj");
you can access those objects across servlets.
Yes you can do that.
However it is better to define these constants in your web.xml using the <context-param> tag.
Servlets can then retrieve constants defined using the <context-param> tag using the call:
context.getInitParameter()
Example of name-value pairs in web.xml:
<context-param>
<param-name>name</param-name>
<param-value>Joe</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>password</param-value>
</context-param>
in web.xml you can define
<context-param>
<description>My variable</description>
<param-name>variable.name</param-name>
<param-value>value</param-value>
</context-param>
And then access it from Servlet code:
String variable = getServletContext().getInitParameter("variable.name");
Yes you can, the static variable will be accessible for all the servlet threads. But about using the static variable, you should make a proper decision depending on the factors like the life time of the data you want to store and the amount of data you are going to store.
And since it is used in servlets context, make sure that its thread-safe.
I would like to implement a simple authentication in an JSF/Primefaces application. I have tried lots of different things, e.g. Dialog - Login Demo makes a simple test on a dialog, but it does not login a user or?
I also have taken a look at Java Security, like:
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<url-pattern>/protected/*</url-pattern>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>REGISTERED_USER</role-name>
</auth-constraint>
</security-constraint>
With this everything under /protected is protected, but as far as i understand i need to define a realm in the server for authentication. I do not want to specify this in the server but just have a simple lookup in the database for it.
Is there a way to authenticate a user without defining something in the application server? Or anonther simple solution to authenticate and protect different pages?
Is there a way to authenticate a user without defining something in the application server?
This is a long and very thorny story. It often comes up as one the main points of criticism against Java EE.
The core of the story is that traditionally Java EE applications are supposed to be deployed with "unresolved dependencies". Those dependencies have to be satisfied at the application server, typically by someone who is not a developer, often by using some kind of GUI or console.
Security configuration is one of those unresolved dependencies.
If the security configuration is done at the application server, this is by definition always not portable, e.g. it has to be done in an application server specific way. It completely rules out using application domain models (e.g. a JPA entity User) for this authentication.
Some servers (e.g. JBoss AS) allow configuring their proprietary security mechanisms from within the application, and additionally allow for 'custom login modules' (the term is different for pretty much every server) to be loaded from the application as well. With some small hacks, this will allow the usage of application domain models and the same data source that the application itself uses for authentication.
Finally, there's a relatively unknown portable way to do authentication from within an application. This is done via the JASPIC SPI, also known as JASPI or JSR 196. Basically, this JASPIC seems to be what you are looking for.
Unfortunately, JASPIC is not perfect and even though it's a technology from Java EE 6 and we're almost at Java EE 7, at the moment support for JASPIC in various application servers is still sketchy. On top of that, even though JASPIC is standardized, application server vendors still somehow require proprietary configuration to actually make it work.
I wrote an article about JASPIC that explains the current problems in more detail: Implementing container authentication in Java EE with JASPIC
I have found a for me suitable and easy solution by simply using Web Filters. I have added a filter to web.xml like
<!-- Authentication Filter -->
<filter>
<filter-name>AuthenticationFilter</filter-name>
<filter-class>org.example.filters.AuthenticationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthenticationFilter</filter-name>
<url-pattern>/protected/*</url-pattern>
</filter-mapping>
The filter looks something like this
#WebFilter(filterName="AuthenticationFilter")
public class AuthenticationFilter implements Filter {
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
Cookie[] cookies = ((HttpServletRequest)request).getCookies();
// Try to find a valid session cookie
if (cookies != null) {
String sessionId = null;
for (Cookie cookie : cookies) {
if ("sessionId".equals(cookie.getName())) {
sessionId = cookie.getValue();
}
}
// Check if we have a valid session
UserSession session = Backend.getInstance().getSessionGateway().getBySessionId(sessionId);
if (session != null) {
chain.doFilter(request, response);
return;
} else if (sessionId != null) {
// Remove the cookie
Cookie cookie = new Cookie("sessionId", null);
cookie.setMaxAge(-1);
((HttpServletResponse)response).addCookie(cookie);
}
}
// Problem due to relative path!!
// ((HttpServletResponse)response).sendRedirect("../login.xhtml");
RequestDispatcher rd = request.getRequestDispatcher("/login.xhtml");
rd.forward(request, response);
}
}
So i had just to implement a Bean that authenticates and sets the session cookie. I will add the user agent to have additional security but it basically works.
The only problem i have that i can not do a redirect, cause it is not using context path but just redirects to /index.xhtml instead of /my_app_context/index.xhtml
I have implemented the OpenSessionInViewFilter for my MVC webapp and it works almost perfect. Only problem is that it also creates a session for every image, js, css etc that are requested from the webserver. This i dont want.
Im using struts2, spring and hibernate and this is my web.xml
<filter>
<filter-name>lazyLoadingFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>lazyLoadingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
So because i am mapping url-pattern /* it also takes all the images etc..
I tried setting it to *.jsp, and *.action, but then i get the lazyloading-exceptions again...
How should i do this? I've been looking for answers for 5 hours now and im getting a litle bit crazy in my head.
All i need to do is to make this filter IGNORE all the static resources. Thats it! And for everything else it can run. It sounds so simple, but its really really annoying me that i cant figure out how.
Any help would be greatly appriciated.
Do i need to extend the filter to write my own filter and exclude within it? And if so. How?
EDIT:
It seems like i could set up filter-mappings for my static files at the top of the filter-chain. And then send those to a "ByPassFilter", thus bypassing the filterchain for these static resources. Is this the way to go??
Thanks guys!
The general practice in such a scenario is to use the combination of Apache Web server with an application server (Tomcat/JBoss) with mod_jk module.
Here is link describing how to use this combination. (Another link)
The chief advantage of using this configuration is
Static content can be served by Apache web server.
The dynamic content requests (like *.jsp, *.action etc) are delegated to tomcat.
There are may other useful modules like content compression for static contents hence improving the response time.
Its more secure than the scenario wherein the app server is serving everything.
I understand this may not be precisely the solution you looking for, I suggested this as this is a general practice.
As far as your implementation of having a Bypassfilter is considered , if you have such a filter in front then once you skip the next filter in filter chain then basically the rest of filters in the chain will also get skipped (which doesn't seem to be a desirable thing to do in most situations ) . Also as the filter invocations for a request behave like
Filter1 -> Filter2 -->Struts Action/BL --> Filter 2 -->Filter 1
Hence the OpenSessionInViewFilter will kick in after the request is processed in your struts action ( which can be avoided by placing another bypass filter after open session in view filter in web.xml ) . However overall it has always appeared undesirable to me to skip the entire filter chain for skipping a single filter .
I haven't ever faced a need to skip OpenSessionInViewFilter ever , however if i had to do it then instead of having a Bypassfilter i would have a filter extending the OpenSessionInViewFilter filter which would be skipping my static resources from processing .
Include only those elements of the pattern that you need.
Something like this:
<filter-mapping>
<filter-name>lazyLoadingFilter</filter-name>
<url-pattern>*.html</url-pattern>
<url-pattern>/profile/edit</url-pattern>
<url-pattern>/cars/*</url-pattern>
</filter-mapping>
Just in case someone needs a solution with extending OpenSessionInViewFilter.
It prevents Hibernate session creation for pre-defined static resources.
/**
* Skips OpenSessionInViewFilter logic for static resources
*/
public class NonStaticOpenSessionInViewFilter extends OpenSessionInViewFilter {
static final Pattern STATIC_RESOURCES = Pattern.compile("(^/js/.*)|(^/css/.*)|(^/img/.*)|(^/fonts/.*)|(/favicon.ico)");
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String path = request.getServletPath();
if (STATIC_RESOURCES.matcher(path).matches()) {
filterChain.doFilter(request, response);
} else {
super.doFilterInternal(request, response, filterChain);
}
}
}
Basically Spring should have provided some property like excludePatterns for OpenSessionInViewFilter.
I totally agree with the answer from #Santosh.
the OpenSessionInViewFilter creates a resource and adds it the the ThreadLocal object, if the session is never used then the session is never actually created, this also means that a db connection is not used for that request. ( this is probably the answer to your question ).
If you still require to control things you can always create another filter extending the OpenSessionInViewFilter and execute the getSession method based on which resource is being called.