diff --git a/10-minute-tutorial.html b/10-minute-tutorial.html.vtl similarity index 90% rename from 10-minute-tutorial.html rename to 10-minute-tutorial.html.vtl index b3e42a654a..49dd68e60d 100644 --- a/10-minute-tutorial.html +++ b/10-minute-tutorial.html.vtl @@ -1,3 +1,5 @@ +#parse("templates/macros.vtl") +

10 Minute Tutorial on Apache Shiro

@@ -42,23 +44,7 @@

Overview

Ok. Now let's actually do something!

-
- - - - - - - - - -
Shiro can be run in any environment, from the simplest command line application - to the biggest enterprise web and clustered applications, but we'll use the simplest possible example in - a simple main method for this QuickStart so you can get a feel for the API. -
-
+#info('Note', 'Shiro can be run in any environment, from the simplest command line application to the biggest enterprise web and clustered applications, but we''ll use the simplest possible example in a simple main method for this QuickStart so you can get a feel for the API.')

Download

@@ -214,23 +200,7 @@

Quickstart.java

href="static/current/apidocs/org/apache/shiro/authc/AuthenticationException.html">AuthenticationException JavaDoc for more.

-
- - - - - - - - - -
Handy Hint
Security best practice is to give generic - login failure messages to users because you do not want to aid an attacker trying to break into your - system. -
-
+#tip('Handy Hint', 'Security best practice is to give generic login failure messages to users because you do not want to aid an attacker trying to break into your system.')

Ok, so by now, we have a logged in user. What else can we do?

diff --git a/about.html b/about.html.vtl similarity index 100% rename from about.html rename to about.html.vtl diff --git a/adoption.html b/adoption.html.vtl similarity index 100% rename from adoption.html rename to adoption.html.vtl diff --git a/architecture.html b/architecture.html.vtl similarity index 96% rename from architecture.html rename to architecture.html.vtl index 6fe931fd1e..c4b92583dc 100644 --- a/architecture.html +++ b/architecture.html.vtl @@ -101,7 +101,7 @@

Design

The SecurityManager implementations and are also JavaBeans compatible, which allows you (or a configuration mechanism) to easily customize the pluggable components via standard JavaBeans accessor/mutator methods (get*/set*). This means the Shiro's architectural modularity can translate into very easy configuration for custom behavior.

-
Easy Configuration
Because of JavaBeans compatibility, it is very easy to configure the SecurityManager with custom components via any mechanism that supports JavaBeans-style configuration, such as Spring, Guice, JBoss, etc.
+#tip('Easy Configuration', 'Because of JavaBeans compatibility, it is very easy to configure the SecurityManager with custom components via any mechanism that supports JavaBeans-style configuration, such as Spring, Guice, JBoss, etc.')

We will cover Configuration next.

diff --git a/articles.html b/articles.html.vtl similarity index 100% rename from articles.html rename to articles.html.vtl diff --git a/assets/css/gh-pages/gh-fork-ribbon.css b/assets/css/gh-pages/gh-fork-ribbon.css index c78dc1c85c..801c6334a7 100644 --- a/assets/css/gh-pages/gh-fork-ribbon.css +++ b/assets/css/gh-pages/gh-fork-ribbon.css @@ -31,6 +31,10 @@ top: 3.23em; right: -3.23em; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -ms-transform: rotate(45deg); diff --git a/authentication-guide.html b/authentication-guide.html deleted file mode 100644 index 3dee1f1cd5..0000000000 --- a/authentication-guide.html +++ /dev/null @@ -1,9 +0,0 @@ -

This page has been moved. You are being redirected.

- -

Redirection Notice
This page should redirect to Java Authentication Guide.
- - diff --git a/authentication-guide.html.vtl b/authentication-guide.html.vtl new file mode 100644 index 0000000000..fdf5bfa7fc --- /dev/null +++ b/authentication-guide.html.vtl @@ -0,0 +1,11 @@ +

This page has been moved. You are being redirected.

+ +

+ +#warning('Redirection Notice', 'This page should redirect to Java Authentication Guide.') + + diff --git a/authentication.html b/authentication.html.vtl similarity index 75% rename from authentication.html rename to authentication.html.vtl index f94d439b5a..db1b9c8c28 100644 --- a/authentication.html +++ b/authentication.html.vtl @@ -12,9 +12,10 @@

Apache Shiro Authenti + +#info("Primary Principal", "While Shiro can represent any number of principals, Shiro expects an application to have exactly one 'Primary' principal - a single value that uniquely identifies the Subject within the application. This is typically a username, email address or globally unique user id in most applications.") + +
  • Credentials are usually secret values known only by the Subject which are used as supporting evidence that they in fact 'own' the claimed identity. Some common examples of credentials are passwords, biometric data such as fingerprints and retina scans, and X.509 certificates.
  • The most common example of a principal/credential pairing is that of a username and password. The username is the claimed identity, and the password is the proof matching the claimed identity. If a submitted password matches what is expected by the application, the application can largely assume that the user really is who they say they are because no-one else should know the same password.

    @@ -60,13 +61,13 @@

    Step

    -

    After acquiring the currently-executing Subject, we make a single login call, passing in the AuthenticationToken instance we created earlier.

    +

    After acquiring the currently-executing Subject, we make a single login call, passing in the AuthenticationToken instance we created earlier.

    An invocation to the login method effectively represents an authentication attempt.

    Step 3: Handling Success or Failure

    -

    If the login method returns quietly, that's it - we're done! The Subject has been authenticated. The application thread can continue uninterrupted and all further calls to SecurityUtils.getSubject() will return the authenticated Subject instance, and any calls to subject.isAuthenticated() will return true.

    +

    If the login method returns quietly, that's it - we're done! The Subject has been authenticated. The application thread can continue uninterrupted and all further calls to SecurityUtils.getSubject() will return the authenticated Subject instance, and any calls to subject.isAuthenticated() will return true.

    But what happens if the login attempt failed? For example, what if the end-user supplied an incorrect password, or accessed the system too many times and maybe their account is locked?

    @@ -91,18 +92,18 @@

    Step 3: Handli

    If one of the existing exception classes do not meet your needs, custom AuthenticationExceptions can be created to represent specific failure scenarios.

    -
    Login Failure Tip
    While your code can react to specific exceptions and execute logic as necessary, a security best practice is to only show a generic failure message to an end user in the event of a failure, for example, "Incorrect username or password.". This ensures no specific information is available to hackers that may be attempting an attack vector.
    +#tip("Login Failure Tip", 'While your code can react to specific exceptions and execute logic as necessary, a security best practice is to only show a generic failure message to an end user in the event of a failure, for example, "Incorrect username or password.". This ensures no specific information is available to hackers that may be attempting an attack vector.')

    Remembered vs. Authenticated

    As shown in the example above, Shiro supports the notion of "remember me" in addition to the normal login process. It is worth pointing out at this time that Shiro makes a very precise distinction between a remembered Subject and an actual authenticated Subject:

    - -
    Mutually Exclusive
    Remembered and authenticated states are mutually exclusive - a true value for one indicates a false value for the other and vice versa.
    +#warning('Mutually Exclusive', 'Remembered and authenticated states are mutually exclusive - a true value for one indicates a false value for the other and vice versa.')

    Why the distinction?

    @@ -130,7 +131,7 @@

    An illustrating exampleLogging Out

    -

    The opposite of authenticating is releasing all known identifying state. When the Subject is done interacting with the application, you can call subject.logout() to relinquish all identifying information:

    +

    The opposite of authenticating is releasing all known identifying state. When the Subject is done interacting with the application, you can call subject.logout() to relinquish all identifying information:

    @@ -142,7 +143,7 @@ 

    Logging Out

    After a Subject logs-out, the Subject instance is considered anonymous again and, except for web applications, can be re-used for login again if desired.

    -
    Web Application Notice
    Because remembered identity in web applications is often persisted with cookies, and cookies can only be deleted before a Response body is committed, it is highly recommended to redirect the end-user to a new view or page immediately after calling subject.logout(). This guarantees that any security-related cookies are deleted as expected. This is a limitation of how HTTP cookies function and not a limitation of Shiro.
    +#danger('Web Application Notice', 'Because remembered identity in web applications is often persisted with cookies, and cookies can only be deleted before a Response body is committed, it is highly recommended to redirect the end-user to a new view or page immediately after calling subject.logout(). This guarantees that any security-related cookies are deleted as expected. This is a limitation of how HTTP cookies function and not a limitation of Shiro.')

    Authentication Sequence

    @@ -162,12 +163,12 @@

    Authentication Sequence< Step 2: The Subject instance, typically a DelegatingSubject (or a subclass) delegates to the application's SecurityManager by calling securityManager.login(token), where the actual authentication work begins.

    -Step 3: The SecurityManager, being a basic 'umbrella' component, receives the token and simply delegates to its internal Authenticator instance by calling authenticator.authenticate(token). This is almost always a ModularRealmAuthenticator instance, which supports coordinating one or more Realm instances during authentication. The ModularRealmAuthenticator essentially provides a PAM-style paradigm for Apache Shiro (where each Realm is a 'module' in PAM terminology). +Step 3: The SecurityManager, being a basic 'umbrella' component, receives the token and simply delegates to its internal Authenticator instance by calling authenticator.authenticate(token). This is almost always a ModularRealmAuthenticator instance, which supports coordinating one or more Realm instances during authentication. The ModularRealmAuthenticator essentially provides a PAM-style paradigm for Apache Shiro (where each Realm is a 'module' in PAM terminology).

    Step 4: If more than one Realm is configured for the application, the ModularRealmAuthenticator instance will initiate a multi-Realm authentication attempt utilizing its configured AuthenticationStrategy. Before, during and after the Realms are invoked for authentication, the AuthenticationStrategy will be called to allow it to react to each Realm's results. We will cover AuthenticationStrategies soon.

    -
    Single-Realm Application
    If only a single Realm is configured, it is called directly - there is no need for an AuthenticationStrategy in a single-Realm application.
    -

    Step 5: Each configured Realm is consulted to see if it supports the submitted AuthenticationToken. If so, the supporting Realm's getAuthenticationInfo method will be invoked with the submitted token. The getAuthenticationInfo method effectively represents a single authentication attempt for that particular Realm. We will cover the Realm authentication behavior shortly.

    +#warning('Single-Realm Application', 'If only a single Realm is configured, it is called directly - there is no need for an AuthenticationStrategy in a single-Realm application.') +

    Step 5: Each configured Realm is consulted to see if it supports the submitted AuthenticationToken. If so, the supporting Realm's getAuthenticationInfo method will be invoked with the submitted token. The getAuthenticationInfo method effectively represents a single authentication attempt for that particular Realm. We will cover the Realm authentication behavior shortly.

    Authenticator

    @@ -201,7 +202,7 @@

    Authenti

    Also an AuthenticationStrategy is responsible for aggregating the results from each successful Realm and 'bundling' them into a single AuthenticationInfo representation. This final aggregate AuthenticatinoInfo instance is what is returned by the Authenticator instance and is what Shiro uses to represent the Subject's final identity (aka Principals).

    -
    Subject Identity 'View'
    If you use more than one Realm in your application to acquire account data from multiple data sources, the AuthenticationStrategy is ultimately responsible for the final 'merged' view of the Subject's identity that is seen by the application.
    +#info("Subject Identity 'View'", "If you use more than one Realm in your application to acquire account data from multiple data sources, the AuthenticationStrategy is ultimately responsible for the final 'merged' view of the Subject's identity that is seen by the application.")

    Shiro has 3 concrete AuthenticationStrategy implementations:

    @@ -224,7 +225,7 @@

    Authenti

    -
    Custom AuthenticationStrategy
    If you wanted to create your own AuthenticationStrategy implementation yourself, you could use the org.apache.shiro.authc.pam.AbstractAuthenticationStrategy as a starting point. The AbstractAuthenticationStrategy class automatically implements the 'bundling'/aggregation behavior of merging the results from each Realm into a single AuthenticationInfo instance.
    +#tip('Custom AuthenticationStrategy', 'If you wanted to create your own AuthenticationStrategy implementation yourself, you could use the org.apache.shiro.authc.pam.AbstractAuthenticationStrategy as a starting point. The AbstractAuthenticationStrategy class automatically implements the ''bundling''/aggregation behavior of merging the results from each Realm into a single AuthenticationInfo instance.')

    Realm Authentication Order

    @@ -278,11 +279,11 @@

    Explicit Ordering

    -
    Explicit Realm Inclusion
    When you explicitly configure the securityManager.realms property, only the referenced realms will be configured on the SecurityManager. This means you could define 5 realms in INI, but only actually use 3 if 3 are referenced for the realms property. This is different than implicit realm ordering where all available realms will be used.
    +#warning('Explicit Realm Inclusion', 'When you explicitly configure the securityManager.realms property, only the referenced realms will be configured on the SecurityManager. This means you could define 5 realms in INI, but only actually use 3 if 3 are referenced for the realms property. This is different than implicit realm ordering where all available realms will be used.')

    Realm Authentication

    -

    This chapter covers Shiro's master workflow explaining how an authentication attempt occurs. The internal workflow of what happens in a single realm as it is consulted during authentication (i.e. 'Step 5' above) is covered in the Realm chapter's Realm Authentication section.

    +

    This chapter covers Shiro's master workflow explaining how an authentication attempt occurs. The internal workflow of what happens in a single realm as it is consulted during authentication (i.e. 'Step 5' above) is covered in the Realm chapter's Realm Authentication section.

    Lend a hand with documentation

    diff --git a/authenticator.html.vtl b/authenticator.html.vtl new file mode 100644 index 0000000000..3599defae9 --- /dev/null +++ b/authenticator.html.vtl @@ -0,0 +1 @@ +#todoAddDoc() \ No newline at end of file diff --git a/authorization.html b/authorization.html.vtl similarity index 81% rename from authorization.html rename to authorization.html.vtl index d5cea21091..66ee4b5bdf 100644 --- a/authorization.html +++ b/authorization.html.vtl @@ -25,7 +25,7 @@

    Permissions

    When looking at permissions, probably the most important thing to realize is that permission statements have no representation of who can perform the represented behavior. They are only statements of what can be done in an application.

    -
    Permissions represent behavior only
    Permission statements reflect behavior (actions associated with resource types) only. They do not reflect who is able to perform such behavior.
    +#info('Permissions represent behavior only', 'Permission statements reflect behavior (actions associated with resource types) only. They do not reflect who is able to perform such behavior.')

    Defining who (users) is allowed to do what (permissions) is an exercise of assigning permissions to users in some way. This is always done by the application's data model and can vary greatly across applications.

    @@ -50,19 +50,16 @@

    Roles

    +#warning('Potentially Brittle Security', 'While the simpler and most common approach, implicit roles potentially impose a lot of software maintenance and management problems. +

    For example, what if you just want to add or remove a role, or redefine a role''s behavior later? You''ll have to go back into your source code and change all your role checks to reflect the change in your security model, every time such a change is required! Not to mention the operational costs this would incur (re-test, go through QA, shut down the app, upgrade the software with the new role checks, restart the app, etc).

    +

    This is probably ok for very simple applications (e.g. maybe there is an ''admin'' role and ''everyone else''). But for more complicated or configurable applications, this can be a major major problem throughout the life of your application and drive a large maintenance cost for your software.

    ') + +
  • Excplict Roles: An explicit role however is essentially a named collection of actual permission statements. In this form, the application (and Shiro) knows exactly what it means to have a particular role or not. Because it is known the exact behavior that can be performed or not, there is no guessing or implying what a particular role can or can not do.
  • The Shiro team advocates using permissions and explicit roles instead of the older implicit approach. You will have much greater control over your application's security experience.

    -
    Resource-Based Access Control
    Be sure to read Les Hazlewood's article, The New RBAC: Resource-Based Access Control, which covers in-depth the benefits of using permissions and explicit roles (and their positive impact on source code) instead of the older implicit role approach.
    +#tip('Resource-Based Access Control', 'Be sure to read Les Hazlewood''s article, The New RBAC: Resource-Based Access Control, which covers in-depth the benefits of using permissions and explicit roles (and their positive impact on source code) instead of the older implicit role approach.')

    Users

    @@ -74,7 +71,7 @@

    Users

    Your data model defines exactly how authorization will function. Shiro relies on a Realm implementation to translate your data model association details into a format Shiro understands. We'll cover how Realms do this a little later.

    -
    Ultimately, your Realm implementation is what communicates with your data source (RDBMS, LDAP, etc). So your realm is what will tell Shiro whether or not roles or permissions exist. You have full control over how your authorization model is structured and defined.
    +#info('Note', 'Ultimately, your Realm implementation is what communicates with your data source (RDBMS, LDAP, etc). So your realm is what will tell Shiro whether or not roles or permissions exist. You have full control over how your authorization model is structured and defined.')

    Authorizing Subjects

    @@ -95,7 +92,7 @@
    Role Checks

    If you want to simply check to see if the current Subject has a role or not, you can call the variant hasRole* methods on the Subject instance.

    -

    For example, to see if a Subject has a particular (single) role, you can call the subject. hasRole(roleName) method, and react accordingly:

    +

    For example, to see if a Subject has a particular (single) role, you can call the subject. hasRole(roleName) method, and react accordingly:

    @@ -114,7 +111,7 @@ 
    Role Checks

    -
    Subject Method Description
    hasRole(String roleName) Returns true if the Subject is assigned the specified role, false otherwise.
    hasRoles(List<String> roleNames) Returns a array of hasRole results corresponding to the indices in the method argument. Useful as a performance enhancement if many role checks need to be performed (e.g. when customizing a complex view)
    hasAllRoles(Collection<String> roleNames) Returns true if the Subject is assigned all of the specified roles, false otherwise.
    +
    Subject Method Description
    hasRole(String roleName) Returns true if the Subject is assigned the specified role, false otherwise.
    hasRoles(List<String> roleNames) Returns a array of hasRole results corresponding to the indices in the method argument. Useful as a performance enhancement if many role checks need to be performed (e.g. when customizing a complex view)
    hasAllRoles(Collection<String> roleNames) Returns true if the Subject is assigned all of the specified roles, false otherwise.
    + + + + + - - diff --git a/templates/macros.vtl b/templates/macros.vtl new file mode 100644 index 0000000000..7d9b83edc9 --- /dev/null +++ b/templates/macros.vtl @@ -0,0 +1,6 @@ +#parse( "templates/macros/danger.vtl" ) +#parse( "templates/macros/info.vtl" ) +#parse( "templates/macros/tip.vtl" ) +#parse( "templates/macros/warning.vtl" ) +#parse( "templates/macros/lend-a-hand.vtl" ) +#parse( "templates/macros/redirect.vtl" ) \ No newline at end of file diff --git a/templates/macros/danger.vtl b/templates/macros/danger.vtl new file mode 100644 index 0000000000..6fd069f994 --- /dev/null +++ b/templates/macros/danger.vtl @@ -0,0 +1,7 @@ +#macro(danger $title, $message) + +#end \ No newline at end of file diff --git a/templates/macros/info.vtl b/templates/macros/info.vtl new file mode 100644 index 0000000000..805e1dcec7 --- /dev/null +++ b/templates/macros/info.vtl @@ -0,0 +1,7 @@ +#macro(info $title, $message) + +#end \ No newline at end of file diff --git a/authenticator.html b/templates/macros/lend-a-hand.vtl similarity index 85% rename from authenticator.html rename to templates/macros/lend-a-hand.vtl index 0dea336f38..f734534455 100644 --- a/authenticator.html +++ b/templates/macros/lend-a-hand.vtl @@ -1,7 +1,9 @@ +#macro(todoAddDoc)

    TODO

    -

    Lend a hand with documentation

    +

    Lend a hand with documentation

    While we hope this documentation helps you with the work you're doing with Apache Shiro, the community is improving and expanding the documentation all the time. If you'd like to help the Shiro project, please consider corrected, expanding, or adding documentation where you see a need. Every little bit of help you provide expands the community and in turn improves Shiro.

    -

    The easiest way to contribute your documentation is to send it to the User Forum or the User Mailing List.

    \ No newline at end of file +

    The easiest way to contribute your documentation is to send it to the User Forum or the User Mailing List.

    +#end \ No newline at end of file diff --git a/templates/macros/redirect.vtl b/templates/macros/redirect.vtl new file mode 100644 index 0000000000..08e0fdae1d --- /dev/null +++ b/templates/macros/redirect.vtl @@ -0,0 +1,11 @@ +#macro(redirect $newHref, $title) +

    This page has been moved. You are being redirected.

    + +#warning('Redirection Notice', "This page should redirect to $title.") + + +#end \ No newline at end of file diff --git a/templates/macros/tip.vtl b/templates/macros/tip.vtl new file mode 100644 index 0000000000..e8046ad2ea --- /dev/null +++ b/templates/macros/tip.vtl @@ -0,0 +1,7 @@ +#macro(tip $title, $message) + +#end \ No newline at end of file diff --git a/templates/macros/warning.vtl b/templates/macros/warning.vtl new file mode 100644 index 0000000000..7fb43100b0 --- /dev/null +++ b/templates/macros/warning.vtl @@ -0,0 +1,7 @@ +#macro(warning $title, $message) + +#end \ No newline at end of file diff --git a/testing.html b/testing.html.vtl similarity index 93% rename from testing.html rename to testing.html.vtl index 33fa61e1d5..a186294129 100644 --- a/testing.html +++ b/testing.html.vtl @@ -11,7 +11,7 @@

    What to know for tests

    1. A Subject instance must be created
    2. The Subject instance must be bound to the currently executing thread.
    3. After the thread is finished executing (or if the thread's execution results in a Throwable), the Subject must be unbound to ensure that the thread remains 'clean' in any thread-pooled environment.
    -

    Shiro has architectural components that perform this bind/unbind logic automatically for a running application. For example, in a web application, the root Shiro Filter performs this logic when filtering a request. But as test environments and frameworks differ, we need to perform this bind/unbind logic ourselves for our chosen test framework.

    +

    Shiro has architectural components that perform this bind/unbind logic automatically for a running application. For example, in a web application, the root Shiro Filter performs this logic when filtering a request. But as test environments and frameworks differ, we need to perform this bind/unbind logic ourselves for our chosen test framework.

    Test Setup

    @@ -101,9 +101,8 @@

    AbstractShiroTest

    -
    Testing & Frameworks
    The code in the AbstractShiroTest class uses Shiro's ThreadState concept and a static SecurityManager. These techniques are useful in tests and in framework code, but rarely ever used in application code. - -

    Most end-users working with Shiro who need to ensure thread-state consistency will almost always use Shiro's automatic management mechanisms, namely the Subject.associateWith and the Subject.execute methods. These methods are covered in the reference on Subject thread association.

    +#warning('Testing & Frameworks', 'The code in the AbstractShiroTest class uses Shiro''s ThreadState concept and a static SecurityManager. These techniques are useful in tests and in framework code, but rarely ever used in application code. +

    Most end-users working with Shiro who need to ensure thread-state consistency will almost always use Shiro''s automatic management mechanisms, namely the Subject.associateWith and the Subject.execute methods. These methods are covered in the reference on Subject thread association.

    ')

    Unit Testing

    diff --git a/tutorial.html b/tutorial.html.vtl similarity index 94% rename from tutorial.html rename to tutorial.html.vtl index de022470e3..0e164bd392 100644 --- a/tutorial.html +++ b/tutorial.html.vtl @@ -31,9 +31,9 @@

    Your First Apache Shi

    Setup

    In this simple example, we'll create a very simple command-line application that will run and quickly exit, just so you can get a feel for Shiro's API.

    +

    -
    Any Application
    Apache Shiro was designed from day one to support any application - from the smallest command-line applications to the largest clustered web applications. Even though we're creating a simple app for this tutorial, know that the same usage patterns apply no matter how your application is created or where it is deployed.
    - +#info('Any Application', 'Apache Shiro was designed from day one to support any application - from the smallest command-line applications to the largest clustered web applications. Even though we''re creating a simple app for this tutorial, know that the same usage patterns apply no matter how your application is created or where it is deployed.')

    This tutorial requires Java 1.5 or later. We'll also be using Apache Maven as our build tool, but of course this is not required to use Apache Shiro. You may acquire Shiro's .jars and incorporate them in any way you like into your application, for example maybe using Apache Ant and Ivy.

    For this tutorial, please ensure that you are using Maven 2.2.1 or later. You should be able to type mvn --version in a command prompt and see something similar to the following:

    @@ -186,7 +186,7 @@

    Configuration

    To that end, Shiro provides a default ‘common denominator’ solution via text-based INI configuration. People are pretty tired of using bulky XML files these days, and INI is easy to read, simple to use, and requires very few dependencies. You’ll also see later that with a simple understanding of object graph navigation, INI can be used effectively to configure simple object graphs like the SecurityManager.

    -
    Many Configuration Options
    Shiro's SecurityManager implementations and all supporting components are all JavaBeans compatible. This allows Shiro to be configured with practically any configuration format such as XML (Spring, JBoss, Guice, etc), YAML, JSON, Groovy Builder markup, and more. INI is just Shiro's 'common denominator' format that allows configuration in any environment in case other options are not available.
    +#tip('Many Configuration Options', 'Shiro''s SecurityManager implementations and all supporting components are all JavaBeans compatible. This allows Shiro to be configured with practically any configuration format such as XML (Spring, JBoss, Guice, etc), YAML, JSON, Groovy Builder markup, and more. INI is just Shiro''s ''common denominator'' format that allows configuration in any environment in case other options are not available.')
    shiro.ini
    @@ -339,7 +339,7 @@

    Using Shiro

    There are many different types of exceptions you can check, or throw your own for custom conditions Shiro might not account for. See the AuthenticationException JavaDoc for more.

    -
    Handy Hint
    Security best practice is to give generic login failure messages to users because you do not want to aid an attacker trying to break into your system.
    +#tip('Handy Hint', 'Security best practice is to give generic login failure messages to users because you do not want to aid an attacker trying to break into your system.')

    Ok, so by now, we have a logged in user. What else can we do?

    diff --git a/web.html b/web.html.vtl similarity index 91% rename from web.html rename to web.html.vtl index 7e9aaebd5f..c398f88dd7 100644 --- a/web.html +++ b/web.html.vtl @@ -35,9 +35,9 @@

    Java Authorization Guide

    Configuration

    -

    The simplest way to integrate Shiro into any web application is to configure a Servlet ContextListener and Filter in web.xml that understands how to read Shiro's INI configuration. The bulk of the INI config format itself is defined in the Configuration pages's INI Sections section, but we'll cover some additional web-specific sections here.

    +

    The simplest way to integrate Shiro into any web application is to configure a Servlet ContextListener and Filter in web.xml that understands how to read Shiro's INI configuration. The bulk of the INI config format itself is defined in the Configuration pages's INI Sections section, but we'll cover some additional web-specific sections here.

    -
    Using Spring?
    Spring Framework users will not perform this setup. If you use Spring, you will want to read about Spring-specific web configuration instead.
    +#info('Using Spring?', 'Spring Framework users will not perform this setup. If you use Spring, you will want to read about Spring-specific web configuration instead.')

    web.xml

    @@ -82,7 +82,7 @@

    Shiro 1.2 and later


  • Finally, the filter-mapping definition ensures that all requests are filtered by the ShiroFilter, recommended for most web applications to ensure that any request can be secured.
  • -
    ShiroFilter filter-mapping
    It is usually desirable to define the ShiroFilter filter-mapping before any other filter-mapping declarations to ensure that Shiro can function in those filters as well.
    +#tip('ShiroFilter filter-mapping', 'It is usually desirable to define the ShiroFilter filter-mapping before any other filter-mapping declarations to ensure that Shiro can function in those filters as well.')
    Custom WebEnvironment Class
    @@ -119,7 +119,7 @@
    Custom Configuration Location -

    By default, the param-value is expected to be resolvable by the rules defined by ServletContext.getResource method. For example, /WEB-INF/some/path/shiro.ini

    +

    By default, the param-value is expected to be resolvable by the rules defined by ServletContext.getResource method. For example, /WEB-INF/some/path/shiro.ini

    But you may also specify specific file-system, classpath or URL locations by using an appropriate resource prefix supported by Shiro's ResourceUtils class, for example:

    @@ -174,9 +174,9 @@
    Custom Path

    Unqualified (schemeless or 'non-prefixed') configPath values are assumed to be ServletContext resource paths, resolvable via the rules defined by the
    -ServletContext.getResource method.

    +ServletContext.getResource method.

    -
    ServletContext resource paths - Shiro 1.2+
    ServletContext resource paths are available in Shiro 1.2 and later. In 1.1 and earlier, all configPath definitions must specify a classpath:, file: or url: prefix.
    +#warning('ServletContext resource paths - Shiro 1.2+', 'ServletContext resource paths are available in Shiro 1.2 and later. In 1.1 and earlier, all configPath definitions must specify a classpath:, file: or url: prefix.')

    You may also specify other non-ServletContext resource locations by using classpath:, url:, or file: prefixes indicating classpath, url, or filesystem locations respectively. For example:

    @@ -273,10 +273,10 @@
    URL Path Expressions

    This line states that "Any request to my application's path of /account or any of it's sub paths (/account/foo, /account/bar/baz, etc) will trigger the 'ssl, authc' filter chain". We'll cover filter chains below.

    -

    Note that all path expressions are relative to your application's context root. This means that if you deploy your application one day to, say, www.somehost.com/myapp and then later deploy it to www.anotherhost.com (no 'myapp' sub-path), the pattern matching will still work. All paths are relative to the HttpServletRequest.getContextPath() value.

    +

    Note that all path expressions are relative to your application's context root. This means that if you deploy your application one day to, say, www.somehost.com/myapp and then later deploy it to www.anotherhost.com (no 'myapp' sub-path), the pattern matching will still work. All paths are relative to the HttpServletRequest.getContextPath() value.

    -
    Order Matters!
    URL path expressions are evaluated against an incoming request in the order they are defined and the FIRST MATCH WINS. For example, let's asume that there are the following chain definitions: +#warning('Order Matters!', 'URL path expressions are evaluated against an incoming request in the order they are defined and the FIRST MATCH WINS. For example, let''s asume that there are the following chain definitions:
    @@ -285,9 +285,9 @@ 
    URL Path Expressions
    -

    If an incoming request is intended to reach /account/signup/index.html (accessible by all 'anon'ymous users), it will never be handled!. The reason is that the /account/** pattern matched the incoming request first and 'short-circuited' all remaining definitions.

    +

    If an incoming request is intended to reach /account/signup/index.html (accessible by all ''anon''ymous users), it will never be handled!. The reason is that the /account/** pattern matched the incoming request first and ''short-circuited'' all remaining definitions.

    -

    Always remember to define your filter chains based on a FIRST MATCH WINS policy!

    +

    Always remember to define your filter chains based on a FIRST MATCH WINS policy!

    ')
    Filter Chain Definitions
    @@ -305,9 +305,8 @@
    Filter Chain Definitions

    Finally, each filter is free to handle the response however it wants if its necessary conditions are not met (e.g. perform a redirect, respond with an HTTP error code, direct rendering, etc). Otherwise it is expected to allow the request to continue through the chain on to the final destination view.

    -
    Being able to react to path specific configuration, i.e. the [optional_configN] part of a filter token, is a unique feature available to Shiro filters. - -

    If you want to create your own javax.servlet.Filter implementation that can also do this, make sure your filter subclasses org.apache.shiro.web.filter.PathMatchingFilter

    +#tip('Tip', 'Being able to react to path specific configuration, i.e. the [optional_configN] part of a filter token, is a unique feature available to Shiro filters. +

    If you want to create your own javax.servlet.Filter implementation that can also do this, make sure your filter subclasses org.apache.shiro.web.filter.PathMatchingFilter

    ')
    Available Filters
    @@ -455,15 +454,14 @@

    DefaultWebSession
    Native Session Timeout
    -

    After configuring the DefaultWebSessionManager instance, session timeout is configured as described in Session Management: Session Timeout

    +

    After configuring the DefaultWebSessionManager instance, session timeout is configured as described in Session Management: Session Timeout

    Session Cookie

    The DefaultWebSessionManager supports two web-specific configuration properties:

    • sessionIdCookieEnabled (a boolean)
    • sessionIdCookie, a Cookie instance.
    - -
    Cookie as a template
    The sessionIdCookie property is essentially a template - you configure the Cookie instance properties, and this template will be used to set the actual HTTP Cookie header at runtime with an appropriate session ID value.
    +#info('Cookie as a template', 'The sessionIdCookie property is essentially a template - you configure the Cookie instance properties, and this template will be used to set the actual HTTP Cookie header at runtime with an appropriate session ID value.')
    Session Cookie Configuration
    @@ -483,7 +481,7 @@
    Session Cookie ConfigurationThe cookie's default name is JSESSIONID in accordance with the servlet specification. Additionally, Shiro's cookie supports the HttpOnly flag. The sessionIdCookie sets HttpOnly to true by default for extra security.

    -
    Shiro's Cookie concept supports the HttpOnly flag even in Servlet 2.4 and 2.5 environments (whereas the Servlet API only supports it natively in 2.6 or later).
    +#info('Note', 'Shiro''s Cookie concept supports the HttpOnly flag even in Servlet 2.4 and 2.5 environments (whereas the Servlet API only supports it natively in 2.6 or later).')
    Disabling the Session Cookie
    @@ -510,7 +508,7 @@

    Remember Me Services

    If this method returns true, Shiro will remember the end-user's identity across sessions.

    -
    UsernamePasswordToken and RememberMe
    The frequently-used UsernamePasswordToken already implements the RememberMeAuthenticationToken interface and supports rememberMe logins.
    +#tip('UsernamePasswordToken and RememberMe', 'The frequently-used UsernamePasswordToken already implements the RememberMeAuthenticationToken interface and supports rememberMe logins.')

    Programmatic Support

    @@ -691,7 +689,7 @@

    The notAuthenticate

    The principal tag

    -

    The principal tag will output the Subject's principal (identifying attribute) or a property of that principal.

    +

    The principal tag will output the Subject's principal (identifying attribute) or a property of that principal.

    Without any tag attributes, the tag will render the toString() value of the principal. For example (assuming the principal is a String username):

    @@ -711,7 +709,7 @@

    The principal tag

    Typed principal

    -

    The principal tag assumes by default that the principal to print is the subject.getPrincipal() value. But if you wanted to print a value that is not the primary principal, but another in the Subject's {principal collection, you can acquire that principal by type and print that value instead.

    +

    The principal tag assumes by default that the principal to print is the subject.getPrincipal() value. But if you wanted to print a value that is not the primary principal, but another in the Subject's {principal collection, you can acquire that principal by type and print that value instead.

    For example, printing the Subject's user ID (and not the username), assuming the ID was in the principal collection: