shiro-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Les Hazlewood <>
Subject PasswordService and 1.2 Changes - review and feedback appreciated
Date Tue, 13 Dec 2011 01:03:16 GMT
Hi all,

After a lot of work, refinement and JavaDoc, the PasswordService and
supporting components (PasswordMatcher, HashService, HashFormat,
HashFormatFactory, and the Command Line Hasher) are all initially
complete.  This should make password management and comparisons MUCH
easier than before while still being highly customizable for more
complex environments.

Based on this work, I'd like to make the following change in Shiro 1.2:

A) As the large majority of Realms perform password comparisons,
change the AuthenticatingRealm's default CredentialsMatcher from a
SimpleCredentialsMatcher to the new PasswordMatcher.  I believe this
suits the 80/20 rule as I'm fairly confident that more than 80% of
Realms are password-based.  Any thoughts on this?

B) Deprecate the SaltedAuthenticationInfo concept and its usages.  The
new PasswordMatcher mechanism and the Hash interface changes now make
this superfluous.

===== Architectural Overview =====

Please do review the code and JavaDoc, but here is a cursory
architectural overview for your understanding:

In traditional Shiro fashion, the new components are highly modular
and consequently easily customized.  They all significantly favor OO
composition instead of inheritance.  They are:

- A new CredentialsMatcher implementation, called a PasswordMatcher,
has been introduced.  It is essentially a bridge between the generic
CredentialsMatcher interface and the new more password-specific
PasswordService interface.

- A new PasswordService interface has been introduced: it can both
encrypt plaintext passwords as well as compare plain-text submissions
against previously saved encrypted passwords.  The encryption
mechanism is not specified by this interface, and instead left to
sub-interfaces and implementations.

- A new HashedPasswordService interface has been introduced: it does
the same things as the above PasswordService, but accepts type-safe
Hash instances instead of only Strings.  This is useful if you don't
want to store all encrypted password bits in a single String and want
to split it up in a custom manner.

- A new DefaultPasswordService that implements both PasswordService
and HashedPasswordService.  This implementation uses best-practice
cryptographic hashing as its 'encryption' implementation (perhaps
another impl one day could use pub/priv keys, etc).  This
implementation uses OO delegation to interact with an internal
HashService to do the actual hashing and a HashFormat instance to do

- A new HashService interface that sits a higher level than the
standard Hash implementations.  It is basically a component that
allows for configuration of Hashing policies in a single place to be
used in multiple locations.

- A new org.apache.shiro.crypto.hash.format package with the
HashFormat and ModularCryptFormat interfaces and supporting
implementations (see next).

- A new HashFormat interface that represents Hash-to-String
conversion.  This is mandatory for supporting the Modular Crypt Format
(MCF) way of safely representing encrypted passwords as strings (e.g
as a database column or in shiro.ini).

- A new ParsableHashFormat interface that represents String-to-Hash
conversion (a sub-interface of HashFormat).  This was necessary as a
separate sub-interface as not all hash formats are reversible.

- A new Shiro1CryptFormat implementation which implements both
ModularCryptFormat and ParsableHashFormat.  This implements Shiro's
first fully-reversible and backwards-compatible MCF formatting
mechanism (most MCF formats are not reversible or backwards compatible
- this one is both).

- A new HashFormatFactory interface that accepts a String argument
(presumably an MCF format ID or an already-formatted encrypted
password string) and returns a corresponding HashFormat instance.
This is required during password comparisons to create the same format
for the plaintext as was used by the previously saved encrypted

- A new DefaultHashFormatFactory implementation of the above interface
that allows customization of the factory behavior if the default
heuristics are not suitable enough.

- A new ProvidedHashFormat enum that lists Shiro's out-of-the-box
HashFormat implementations (useful for reference, but it is used to
support HashFormatFactory behavior as well).

- A new command-line Hasher program that can easily encrypt passwords
using best practices as well as hash any string or resource (files,
urls, classpath locations, etc).  This will be useful to many people,
but especially useful to people adding user records in Shiro's INI
[users] section.  Initial documentation here:

Finally, a lot of tests were added to support these new
implementations.  All new components are at or near 100% method and
100% line coverage.

I apologize for the delay in getting this out - I know a lot of people
have been waiting on it.  As you can see from the list above, this was
a bigger effort than just whipping together a new CredentialsMatcher.
But now things are highly customizable and I believe much more in-line
with Shiro's goals of out-of-the-box simplicity (this part of our API
was lacking previously).

Comments and feedback are welcome.


Les Hazlewood
CTO, Katasoft | | 888.391.5282
twitter: @lhazlewood |
katasoft blog:
personal blog:

View raw message