Question

I use Primefaces 4.0 and Shiro 1.2.2 in a website that I currently developed. My forms are interpreted and Primefaces components are displayed without problem. But when I enable the security on my application, my forms, at least login page, don't displays ​​with Primefaces rendering. I know that Shiro has intercepted all HTTP requests in order to control the access but why my form appears as if I did't use Primefaces? Please, do you have an idea of ​​solution to my problem? Is it possible to integrate Shiro and Primefaces?

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>
<welcome-file-list>
    <welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
<listener>
    <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>
<filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>
<resource-ref>
    <res-ref-name>connectionPool</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
<context-param>
    <param-name>primefaces.THEME</param-name>
    <param-value>redmond</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>/faces/*</url-pattern>
</servlet-mapping>
</web-app>

shiro.ini:

[main]
authc.loginUrl = /faces/login.xhtml
authc.usernameParam = login:username
authc.passwordParam = login:password
authc.rememberMeParam = login:rememberMe
user.loginUrl = /faces/login.xhtml

jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
# Configure JDBC realm password hashing.
redentialsMatcher = org.apache.shiro.authc.credential.HashedCredentialsMatcher
credentialsMatcher.hashAlgorithmName = SHA-256
jdbcRealm.credentialsMatcher = $credentialsMatcher

# Configure JDBC realm SQL queries.
jdbcRealm.authenticationQuery = SELECT password FROM USER WHERE username = ?
dbcRealm.userRolesQuery = SELECT role FROM ROLE WHERE userId = (SELECT id FROM USER     WHERE username = ?)

# Configure JDBC realm datasource. DataSource properties
dataSource = org.apache.derby.jdbc.ClientDataSource
dataSource.serverName = localhost
dataSource.portNumber = 1527
dataSource.databaseName = testdb
dataSource.user = admin
dataSource.password = admin
jdbcRealm.dataSource = $dataSource


[users]
admin = password

[urls]
/faces/login.xhtml = authc
/faces/** = authc

I'm a beginner in web development with JSF, Primefaces and Shiro.

Thanks for your help.

Was it helpful?

Solution

Here in the last entry,

[urls]
/faces/login.xhtml = authc
/faces/** = authc

you've told Shiro to authenticate every single unmapped URL matching /faces/**. This thus also covers JSF resources such as CSS/JS/image files which are auto-included by JSF components (as in PrimeFaces). In effects, when the browser wants to download e.g. the CSS file, it receives a login page instead of the actual CSS content and is hence unable to apply the definied CSS styles. You can see it yourself by entering the URL to the CSS file in the browser's address bar yourself. Instead of the CSS file content, you'll see a login page. The webbrowser is "under the covers" facing exactly that problem.

You need to explicitly tell Shiro to allow unauthenticated (anonymous) access to JSF resources. Those resources are identified by an additional /javax.faces.resource path (as definied by the ResourceHandler#RESOURCE_IDENTIFIER constant in JSF API).

[urls]
/faces/login.xhtml = authc
/faces/javax.faces.resource/** = anon
/faces/** = authc

See also:

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top