Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Info
titleVersion status: 0.6.1 for T5.4, 0.5.1 stable for T5.3, 0.4.6 stable for T5.2 and 0.2.2 for T5.1

tapestry-security module is based on and depends on Apache Shiro. 0.4.1 depends on Apache Shiro 1.2.0, earlier versions depend on 1.1.0

Source and issue management moved to Github!

Critical issues will be fixed for 0.4.x, feature development only for 0.56.x versions. Versions before 0.4.0 are not maintained anymore.
0.4.0 introduced fully Tapestry-style configuration and performance improvements.

...

Code Block
<dependency>
  <groupId>org.tynamo</groupId>
  <artifactId>tapestry-security</artifactId>
  <version>0.56.1</version>
</dependency>

...

Obviously, if your Realm needs to use other Tapestry services, you could let Tapestry build your Realm implementation with @Autobuild and inject it as an argument to your WebSecurityManager contribution method. If you create a first-class Tapestry IoC service out of your realm (you can but there should be very little need), make sure you identify your realm to the Tapestry with the right super interface. For example, if your realm is authorizing users, the interface to use is AuthorizingRealm  - if you claimed that the service implements Realm interface only, your realm wouldn't be allowed to participate in authorization, but only in authentication process. See an example of a simple, custom Hibernate JPA-based entity realm (service). Shiro provides an extensive set of interfaces, often providing different functionalities depending on which features are available.

Tip
titleStoring password

Apache Shiro is persistence agnostic so you need to decide yourself how to store the passwords and compare their equality. Shiro comes with several built-in matchers to make this simple. The User entity used by the realm sample referred to above also shows an example of storing an SHA-1 hash with per user salt.

...

For 0.3.x and earlier versions, you can use a standard Shiro INI configuration file (see Shiro's documentation for more info) with tapestry-security. All versions support annotation-based security. The simplest and most typical security models are based on url and role permissions, see the following version-specific sections for examples on them.

Configuration through contributions

...

Panel
titleContributing security configuration
Code Block
// Starting from 0.4.6, you can also use a marker annotation:
// @Contribute(HttpServletRequestFilter.class) @Security public static void securePaths(...)
public static void contributeSecurityConfiguration(Configuration<SecurityFilterChain> configuration,
			SecurityFilterChainFactory factory) {
		// /authc/** rule covers /authc , /authc?q=name /authc#anchor urls as well
		configuration.add(factory.createChain("/authc/signup").add(factory.anon()).build());
		configuration.add(factory.createChain("/authc/**").add(factory.authc()).build());
		configuration.add(factory.createChain("/contributed/**").add(factory.authc()).build());
		configuration.add(factory.createChain("/user/signup").add(factory.anon()).build());
		configuration.add(factory.createChain("/user/**").add(factory.user()).build());
		configuration.add(factory.createChain("/roles/user/**").add(factory.roles(), "user").build());
		configuration.add(factory.createChain("/roles/manager/**").add(factory.roles(), "manager").build());
		configuration.add(factory.createChain("/perms/view/**").add(factory.perms(), "news:view").build());
		configuration.add(factory.createChain("/perms/edit/**").add(factory.perms(), "news:edit").build());
	}

Note that above, a call to factory.<filtername>() gives you a new instance of the filter each time. In fact, you get a runtime error if you try to contribute the same filter instance to a different chain with a different configuration.

(Example taken from the AppModule of a security test application)

0.4.1 also introduced a dependency to tapestry-exceptionpage (a version of it is built-in to T5.4). The security exceptions thrown from the filters annotation handlers are all handled by the same exception handler assistant. You can also handle other generic exceptions in your application the same way, read more about it at tapestry-exceptionpage guide. Configuration via shiro.ini is possible for version before 0.4.0 but the support for it was removed an unanimous community vote. (or DefaultRequestExceptionHandler documentation for T5.4). anon() and authc() etc. above refer to the Shiro filter names. See all Shiro filters available by default.

Annotations

Routing error codes in your web.xml

In your web.xml, you most likely want to route 401 (Unauthorized) to your own error page instead of the container provided one, for example:

Code Block
...
    <error-page>
        <error-code>401</error-code>
        <location>/error401</location>
    </error-page>
    <error-page>
        <error-code>404</error-code>
        <location>/error404</location>
    </error-page>
</web-app>

Also, note that by the servlet spec, application filters don't handle error requests by default (Jetty, at least the old versions, didn't conform). So, to get the Tapestry filter to handle the ERROR request, you also need to configure:

Code Block
    <filter-mapping>
        <filter-name>vuact</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>

Security annotations

To declaratively secure your pages, you can use the following annotations:

...

Code Block
<t:security.user>
  Hello, ${username}
   // else only from 0.5.1 and up
   <p:else>
    Hello guest
   </p:else>
 </t:security.user>
Code Block
<t:security.guest>
  <t:actionlink t:id="createAccount">Create account</t:actionlink>
</t:security.guest>

...

For more extensive examples, take a look at our full-featured integration test web app. See for example the Index page template and class and the AlphaService. Also, check out tynamo-federatedaccounts, an add-on module to tapestry-security for remote & merged authentication use cases, such as Oauth. We have a live example available for federatedaccounts but the example application also demonstrates other useful capabilities of tapestry-security, such as realm as a service, contributing multiple realms, interoperability between them, creating and using a CurrentUser application state object and using permissions. In the example, one realm is responsible for only authenticating users while another one is responsible for authorizing them. Check out the source from http://svn.codehaus.org/tynamo/trunk/tynamoClone the tynamo-example-federatedaccounts repo or browse the sources online, starting from AppModule

Case study: Securing Javamelody - An example of integrating a non-Tapestry library using a standard ServletFilter

...