Question
How do I allow unauthenticated users to be served a login.xhtml JSF2.0 Facelet page over https when attempting access to security constrained resources or otherwise requiring login authentication.
Current Implementation
I'm developing with NetBeans 7.3. Server is GlassFigh 3.1.2.2. Using PrimeFaces 3.5 components. Security is container managed under JDBCRealm. I have followed the pattern described very helpfully by BalusC's answer at Performing user authentication in Java EE / JSF using j_security_check.
Basically:
- Declarative Security using Deployment Descriptor
- Form based authentication (Full JSF component Facelet login.xhtml using @ViewScoped @ManagedBean for programmatic login using Servlet 3.0 HttpServletRequest.login())
- JDBC Realm
Everything works great and as required when I run the program from the localhost machine or any machine over my LAN. The index.xhtml is the welcome file under my web.xml and it is also protected under a security constraint. Thus my
<form-login-page>/login.xhtml</form-login-page>
is presented when context root is hit from browser. The login.xhtml is also under a security constraint for the purpose of requiring CONFIDENTIAL under user-data-constraint. This successfully applies https for the login form which is how I'm answering my own question above.
Problem
Whenever I try to load the page from my iPhone using standard Safari browser from outside my LAN (from the internet) i get a server stopped responding error after i see it switch my url from the http 8080 port to the https 8181 port. I also get a
INFO: JACC Policy Provider:Failed Permission Check: context (" WebApplication2/WebApplication2 ") , permission (" ("javax.security.jacc.WebUserDataPermission" "/login.xhtml" "GET") ")
message in the netbeans glassfigh output window. Why does this not work the same as over a LAN?
Thoughts
This current web.xml does not specify an auth-constraint element for the "secure login" security-constraint because the Java EE 6 Tutorial says "If there is no authorization constraint, the container must accept the request without requiring user authentication". If i specify an auth-constraint with a * role-name the application still behaves the same (same problem). Obviously if i give it an application role name the user could never be resolved to a role in the first place. Is this implementation pattern entirely wrong to begin with?
Code
My web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<param-name>primefaces.THEME</param-name>
<param-value>#{loggedInUser.preferences.theme}</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>10</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
<security-constraint>
<display-name>index</display-name>
<web-resource-collection>
<web-resource-name>index</web-resource-name>
<description/>
<url-pattern>/index.xhtml</url-pattern>
</web-resource-collection>
<auth-constraint>
<description/>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<display-name>secure login</display-name>
<web-resource-collection>
<web-resource-name>login.xhtml</web-resource-name>
<description/>
<url-pattern>/login.xhtml</url-pattern>
</web-resource-collection>
<user-data-constraint>
<description/>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>jdbc-realm</realm-name>
<form-login-config>
<form-login-page>/login.xhtml</form-login-page>
<form-error-page>/loginError.xhtml</form-error-page>
</form-login-config>
</login-config>
<security-role>
<description/>
<role-name>admin</role-name>
</security-role>
</web-app>