diff --git a/docs/manual/src/docs/asciidoc/_includes/architecture/core-services.adoc b/docs/manual/src/docs/asciidoc/_includes/architecture/core-services.adoc new file mode 100644 index 0000000000..c050bcc283 --- /dev/null +++ b/docs/manual/src/docs/asciidoc/_includes/architecture/core-services.adoc @@ -0,0 +1,178 @@ + +[[core-services]] +== Core Services +Now that we have a high-level overview of the Spring Security architecture and its core classes, let's take a closer look at one or two of the core interfaces and their implementations, in particular the `AuthenticationManager`, `UserDetailsService` and the `AccessDecisionManager`. +These crop up regularly throughout the remainder of this document so it's important you know how they are configured and how they operate. + + +[[core-services-authentication-manager]] +=== The AuthenticationManager, ProviderManager and AuthenticationProvider +The `AuthenticationManager` is just an interface, so the implementation can be anything we choose, but how does it work in practice? What if we need to check multiple authentication databases or a combination of different authentication services such as a database and an LDAP server? + +The default implementation in Spring Security is called `ProviderManager` and rather than handling the authentication request itself, it delegates to a list of configured `AuthenticationProvider` s, each of which is queried in turn to see if it can perform the authentication. +Each provider will either throw an exception or return a fully populated `Authentication` object. +Remember our good friends, `UserDetails` and `UserDetailsService`? If not, head back to the previous chapter and refresh your memory. +The most common approach to verifying an authentication request is to load the corresponding `UserDetails` and check the loaded password against the one that has been entered by the user. +This is the approach used by the `DaoAuthenticationProvider` (see below). +The loaded `UserDetails` object - and particularly the `GrantedAuthority` s it contains - will be used when building the fully populated `Authentication` object which is returned from a successful authentication and stored in the `SecurityContext`. + +If you are using the namespace, an instance of `ProviderManager` is created and maintained internally, and you add providers to it by using the namespace authentication provider elements (see <>). +In this case, you should not declare a `ProviderManager` bean in your application context. +However, if you are not using the namespace then you would declare it like so: + +[source,xml] +---- + + + + + + + + + + +---- + +In the above example we have three providers. +They are tried in the order shown (which is implied by the use of a `List`), with each provider able to attempt authentication, or skip authentication by simply returning `null`. +If all implementations return null, the `ProviderManager` will throw a `ProviderNotFoundException`. +If you're interested in learning more about chaining providers, please refer to the `ProviderManager` Javadoc. + +Authentication mechanisms such as a web form-login processing filter are injected with a reference to the `ProviderManager` and will call it to handle their authentication requests. +The providers you require will sometimes be interchangeable with the authentication mechanisms, while at other times they will depend on a specific authentication mechanism. +For example, `DaoAuthenticationProvider` and `LdapAuthenticationProvider` are compatible with any mechanism which submits a simple username/password authentication request and so will work with form-based logins or HTTP Basic authentication. +On the other hand, some authentication mechanisms create an authentication request object which can only be interpreted by a single type of `AuthenticationProvider`. +An example of this would be JA-SIG CAS, which uses the notion of a service ticket and so can therefore only be authenticated by a `CasAuthenticationProvider`. +You needn't be too concerned about this, because if you forget to register a suitable provider, you'll simply receive a `ProviderNotFoundException` when an attempt to authenticate is made. + + +[[core-services-erasing-credentials]] +==== Erasing Credentials on Successful Authentication +By default (from Spring Security 3.1 onwards) the `ProviderManager` will attempt to clear any sensitive credentials information from the `Authentication` object which is returned by a successful authentication request. +This prevents information like passwords being retained longer than necessary. + +This may cause issues when you are using a cache of user objects, for example, to improve performance in a stateless application. +If the `Authentication` contains a reference to an object in the cache (such as a `UserDetails` instance) and this has its credentials removed, then it will no longer be possible to authenticate against the cached value. +You need to take this into account if you are using a cache. +An obvious solution is to make a copy of the object first, either in the cache implementation or in the `AuthenticationProvider` which creates the returned `Authentication` object. +Alternatively, you can disable the `eraseCredentialsAfterAuthentication` property on `ProviderManager`. +See the Javadoc for more information. + + +[[core-services-dao-provider]] +==== DaoAuthenticationProvider +The simplest `AuthenticationProvider` implemented by Spring Security is `DaoAuthenticationProvider`, which is also one of the earliest supported by the framework. +It leverages a `UserDetailsService` (as a DAO) in order to lookup the username, password and `GrantedAuthority` s. +It authenticates the user simply by comparing the password submitted in a `UsernamePasswordAuthenticationToken` against the one loaded by the `UserDetailsService`. +Configuring the provider is quite simple: + +[source,xml] +---- + + + + + +---- + +The `PasswordEncoder` is optional. +A `PasswordEncoder` provides encoding and decoding of passwords presented in the `UserDetails` object that is returned from the configured `UserDetailsService`. +This will be discussed in more detail <>. + + +=== UserDetailsService Implementations +As mentioned in the earlier in this reference guide, most authentication providers take advantage of the `UserDetails` and `UserDetailsService` interfaces. +Recall that the contract for `UserDetailsService` is a single method: + +[source,java] +---- +UserDetails loadUserByUsername(String username) throws UsernameNotFoundException; +---- + +The returned `UserDetails` is an interface that provides getters that guarantee non-null provision of authentication information such as the username, password, granted authorities and whether the user account is enabled or disabled. +Most authentication providers will use a `UserDetailsService`, even if the username and password are not actually used as part of the authentication decision. +They may use the returned `UserDetails` object just for its `GrantedAuthority` information, because some other system (like LDAP or X.509 or CAS etc) has undertaken the responsibility of actually validating the credentials. + +Given `UserDetailsService` is so simple to implement, it should be easy for users to retrieve authentication information using a persistence strategy of their choice. +Having said that, Spring Security does include a couple of useful base implementations, which we'll look at below. + + +[[core-services-in-memory-service]] +==== In-Memory Authentication +Is easy to use create a custom `UserDetailsService` implementation that extracts information from a persistence engine of choice, but many applications do not require such complexity. +This is particularly true if you're building a prototype application or just starting integrating Spring Security, when you don't really want to spend time configuring databases or writing `UserDetailsService` implementations. +For this sort of situation, a simple option is to use the `user-service` element from the security <>: + +[source,xml] +---- + + + + + +---- + + +This also supports the use of an external properties file: + +[source,xml] +---- + +---- + +The properties file should contain entries in the form + +[source,txt] +---- +username=password,grantedAuthority[,grantedAuthority][,enabled|disabled] +---- + +For example + +[source,txt] +---- +jimi=jimispassword,ROLE_USER,ROLE_ADMIN,enabled +bob=bobspassword,ROLE_USER,enabled +---- + +[[core-services-jdbc-user-service]] +==== JdbcDaoImpl +Spring Security also includes a `UserDetailsService` that can obtain authentication information from a JDBC data source. +Internally Spring JDBC is used, so it avoids the complexity of a fully-featured object relational mapper (ORM) just to store user details. +If your application does use an ORM tool, you might prefer to write a custom `UserDetailsService` to reuse the mapping files you've probably already created. +Returning to `JdbcDaoImpl`, an example configuration is shown below: + +[source,xml] +---- + + + + + + + + + + +---- + +You can use different relational database management systems by modifying the `DriverManagerDataSource` shown above. +You can also use a global data source obtained from JNDI, as with any other Spring configuration. + +===== Authority Groups +By default, `JdbcDaoImpl` loads the authorities for a single user with the assumption that the authorities are mapped directly to users (see the <>). +An alternative approach is to partition the authorities into groups and assign groups to the user. +Some people prefer this approach as a means of administering user rights. +See the `JdbcDaoImpl` Javadoc for more information on how to enable the use of group authorities. +The group schema is also included in the appendix. + +include::password-encoder.adoc[leveloffset=+2] + +include::jackson.adoc[] + diff --git a/docs/manual/src/docs/asciidoc/_includes/architecture/index.adoc b/docs/manual/src/docs/asciidoc/_includes/architecture/index.adoc new file mode 100644 index 0000000000..47590edfe7 --- /dev/null +++ b/docs/manual/src/docs/asciidoc/_includes/architecture/index.adoc @@ -0,0 +1,9 @@ +[[overall-architecture]] += Architecture and Implementation +Once you are familiar with setting up and running some namespace-configuration based applications, you may wish to develop more of an understanding of how the framework actually works behind the namespace facade. +Like most software, Spring Security has certain central interfaces, classes and conceptual abstractions that are commonly used throughout the framework. +In this part of the reference guide we will look at some of these and see how they work together to support authentication and access-control within Spring Security. + +include::technical-overview.adoc[] + +include::core-services.adoc[] diff --git a/docs/manual/src/docs/asciidoc/_includes/jackson.adoc b/docs/manual/src/docs/asciidoc/_includes/architecture/jackson.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/jackson.adoc rename to docs/manual/src/docs/asciidoc/_includes/architecture/jackson.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/password-encoder.adoc b/docs/manual/src/docs/asciidoc/_includes/architecture/password-encoder.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/password-encoder.adoc rename to docs/manual/src/docs/asciidoc/_includes/architecture/password-encoder.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/architecture.adoc b/docs/manual/src/docs/asciidoc/_includes/architecture/technical-overview.adoc similarity index 74% rename from docs/manual/src/docs/asciidoc/_includes/architecture.adoc rename to docs/manual/src/docs/asciidoc/_includes/architecture/technical-overview.adoc index 5073d61539..6dfb93bece 100644 --- a/docs/manual/src/docs/asciidoc/_includes/architecture.adoc +++ b/docs/manual/src/docs/asciidoc/_includes/architecture/technical-overview.adoc @@ -1,9 +1,3 @@ -[[overall-architecture]] -= Architecture and Implementation -Once you are familiar with setting up and running some namespace-configuration based applications, you may wish to develop more of an understanding of how the framework actually works behind the namespace facade. -Like most software, Spring Security has certain central interfaces, classes and conceptual abstractions that are commonly used throughout the framework. -In this part of the reference guide we will look at some of these and see how they work together to support authentication and access-control within Spring Security. - [[technical-overview]] == Technical Overview @@ -466,182 +460,3 @@ You can either do this in a filter yourself (which must come before the Spring S Please refer to the Spring Framework documentation for further details on using localization with Spring. The "contacts" sample application is set up to use localized messages. - - -[[core-services]] -== Core Services -Now that we have a high-level overview of the Spring Security architecture and its core classes, let's take a closer look at one or two of the core interfaces and their implementations, in particular the `AuthenticationManager`, `UserDetailsService` and the `AccessDecisionManager`. -These crop up regularly throughout the remainder of this document so it's important you know how they are configured and how they operate. - - -[[core-services-authentication-manager]] -=== The AuthenticationManager, ProviderManager and AuthenticationProvider -The `AuthenticationManager` is just an interface, so the implementation can be anything we choose, but how does it work in practice? What if we need to check multiple authentication databases or a combination of different authentication services such as a database and an LDAP server? - -The default implementation in Spring Security is called `ProviderManager` and rather than handling the authentication request itself, it delegates to a list of configured `AuthenticationProvider` s, each of which is queried in turn to see if it can perform the authentication. -Each provider will either throw an exception or return a fully populated `Authentication` object. -Remember our good friends, `UserDetails` and `UserDetailsService`? If not, head back to the previous chapter and refresh your memory. -The most common approach to verifying an authentication request is to load the corresponding `UserDetails` and check the loaded password against the one that has been entered by the user. -This is the approach used by the `DaoAuthenticationProvider` (see below). -The loaded `UserDetails` object - and particularly the `GrantedAuthority` s it contains - will be used when building the fully populated `Authentication` object which is returned from a successful authentication and stored in the `SecurityContext`. - -If you are using the namespace, an instance of `ProviderManager` is created and maintained internally, and you add providers to it by using the namespace authentication provider elements (see <>). -In this case, you should not declare a `ProviderManager` bean in your application context. -However, if you are not using the namespace then you would declare it like so: - -[source,xml] ----- - - - - - - - - - - ----- - -In the above example we have three providers. -They are tried in the order shown (which is implied by the use of a `List`), with each provider able to attempt authentication, or skip authentication by simply returning `null`. -If all implementations return null, the `ProviderManager` will throw a `ProviderNotFoundException`. -If you're interested in learning more about chaining providers, please refer to the `ProviderManager` Javadoc. - -Authentication mechanisms such as a web form-login processing filter are injected with a reference to the `ProviderManager` and will call it to handle their authentication requests. -The providers you require will sometimes be interchangeable with the authentication mechanisms, while at other times they will depend on a specific authentication mechanism. -For example, `DaoAuthenticationProvider` and `LdapAuthenticationProvider` are compatible with any mechanism which submits a simple username/password authentication request and so will work with form-based logins or HTTP Basic authentication. -On the other hand, some authentication mechanisms create an authentication request object which can only be interpreted by a single type of `AuthenticationProvider`. -An example of this would be JA-SIG CAS, which uses the notion of a service ticket and so can therefore only be authenticated by a `CasAuthenticationProvider`. -You needn't be too concerned about this, because if you forget to register a suitable provider, you'll simply receive a `ProviderNotFoundException` when an attempt to authenticate is made. - - -[[core-services-erasing-credentials]] -==== Erasing Credentials on Successful Authentication -By default (from Spring Security 3.1 onwards) the `ProviderManager` will attempt to clear any sensitive credentials information from the `Authentication` object which is returned by a successful authentication request. -This prevents information like passwords being retained longer than necessary. - -This may cause issues when you are using a cache of user objects, for example, to improve performance in a stateless application. -If the `Authentication` contains a reference to an object in the cache (such as a `UserDetails` instance) and this has its credentials removed, then it will no longer be possible to authenticate against the cached value. -You need to take this into account if you are using a cache. -An obvious solution is to make a copy of the object first, either in the cache implementation or in the `AuthenticationProvider` which creates the returned `Authentication` object. -Alternatively, you can disable the `eraseCredentialsAfterAuthentication` property on `ProviderManager`. -See the Javadoc for more information. - - -[[core-services-dao-provider]] -==== DaoAuthenticationProvider -The simplest `AuthenticationProvider` implemented by Spring Security is `DaoAuthenticationProvider`, which is also one of the earliest supported by the framework. -It leverages a `UserDetailsService` (as a DAO) in order to lookup the username, password and `GrantedAuthority` s. -It authenticates the user simply by comparing the password submitted in a `UsernamePasswordAuthenticationToken` against the one loaded by the `UserDetailsService`. -Configuring the provider is quite simple: - -[source,xml] ----- - - - - - ----- - -The `PasswordEncoder` is optional. -A `PasswordEncoder` provides encoding and decoding of passwords presented in the `UserDetails` object that is returned from the configured `UserDetailsService`. -This will be discussed in more detail <>. - - -=== UserDetailsService Implementations -As mentioned in the earlier in this reference guide, most authentication providers take advantage of the `UserDetails` and `UserDetailsService` interfaces. -Recall that the contract for `UserDetailsService` is a single method: - -[source,java] ----- -UserDetails loadUserByUsername(String username) throws UsernameNotFoundException; ----- - -The returned `UserDetails` is an interface that provides getters that guarantee non-null provision of authentication information such as the username, password, granted authorities and whether the user account is enabled or disabled. -Most authentication providers will use a `UserDetailsService`, even if the username and password are not actually used as part of the authentication decision. -They may use the returned `UserDetails` object just for its `GrantedAuthority` information, because some other system (like LDAP or X.509 or CAS etc) has undertaken the responsibility of actually validating the credentials. - -Given `UserDetailsService` is so simple to implement, it should be easy for users to retrieve authentication information using a persistence strategy of their choice. -Having said that, Spring Security does include a couple of useful base implementations, which we'll look at below. - - -[[core-services-in-memory-service]] -==== In-Memory Authentication -Is easy to use create a custom `UserDetailsService` implementation that extracts information from a persistence engine of choice, but many applications do not require such complexity. -This is particularly true if you're building a prototype application or just starting integrating Spring Security, when you don't really want to spend time configuring databases or writing `UserDetailsService` implementations. -For this sort of situation, a simple option is to use the `user-service` element from the security <>: - -[source,xml] ----- - - - - - ----- - - -This also supports the use of an external properties file: - -[source,xml] ----- - ----- - -The properties file should contain entries in the form - -[source,txt] ----- -username=password,grantedAuthority[,grantedAuthority][,enabled|disabled] ----- - -For example - -[source,txt] ----- -jimi=jimispassword,ROLE_USER,ROLE_ADMIN,enabled -bob=bobspassword,ROLE_USER,enabled ----- - -[[core-services-jdbc-user-service]] -==== JdbcDaoImpl -Spring Security also includes a `UserDetailsService` that can obtain authentication information from a JDBC data source. -Internally Spring JDBC is used, so it avoids the complexity of a fully-featured object relational mapper (ORM) just to store user details. -If your application does use an ORM tool, you might prefer to write a custom `UserDetailsService` to reuse the mapping files you've probably already created. -Returning to `JdbcDaoImpl`, an example configuration is shown below: - -[source,xml] ----- - - - - - - - - - - ----- - -You can use different relational database management systems by modifying the `DriverManagerDataSource` shown above. -You can also use a global data source obtained from JNDI, as with any other Spring configuration. - -===== Authority Groups -By default, `JdbcDaoImpl` loads the authorities for a single user with the assumption that the authorities are mapped directly to users (see the <>). -An alternative approach is to partition the authorities into groups and assign groups to the user. -Some people prefer this approach as a means of administering user rights. -See the `JdbcDaoImpl` Javadoc for more information on how to enable the use of group authorities. -The group schema is also included in the appendix. - -include::password-encoder.adoc[leveloffset=+2] - -include::jackson.adoc[] - diff --git a/docs/manual/src/docs/asciidoc/index.adoc b/docs/manual/src/docs/asciidoc/index.adoc index 9648eeadaa..b463e34ca6 100644 --- a/docs/manual/src/docs/asciidoc/index.adoc +++ b/docs/manual/src/docs/asciidoc/index.adoc @@ -8,7 +8,7 @@ It is the de-facto standard for securing Spring-based applications. include::{include-dir}/preface/index.adoc[] -include::{include-dir}/architecture.adoc[] +include::{include-dir}/architecture/index.adoc[] include::{include-dir}/test.adoc[]