mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-05-31 01:02:14 +00:00
Extract architecture subsections
Issue: gh-2567
This commit is contained in:
parent
4152530e69
commit
cf4272ff64
@ -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 <<ns-auth-manager,the namespace chapter>>).
|
||||||
|
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]
|
||||||
|
----
|
||||||
|
|
||||||
|
<bean id="authenticationManager"
|
||||||
|
class="org.springframework.security.authentication.ProviderManager">
|
||||||
|
<constructor-arg>
|
||||||
|
<list>
|
||||||
|
<ref local="daoAuthenticationProvider"/>
|
||||||
|
<ref local="anonymousAuthenticationProvider"/>
|
||||||
|
<ref local="ldapAuthenticationProvider"/>
|
||||||
|
</list>
|
||||||
|
</constructor-arg>
|
||||||
|
</bean>
|
||||||
|
----
|
||||||
|
|
||||||
|
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]
|
||||||
|
----
|
||||||
|
|
||||||
|
<bean id="daoAuthenticationProvider"
|
||||||
|
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
|
||||||
|
<property name="userDetailsService" ref="inMemoryDaoImpl"/>
|
||||||
|
<property name="passwordEncoder" ref="passwordEncoder"/>
|
||||||
|
</bean>
|
||||||
|
----
|
||||||
|
|
||||||
|
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 <<core-services-password-encoding,below>>.
|
||||||
|
|
||||||
|
|
||||||
|
=== 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 <<ns-minimal,namespace>>:
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<user-service id="userDetailsService">
|
||||||
|
<!-- Password is prefixed with {noop} to indicate to DelegatingPasswordEncoder that
|
||||||
|
NoOpPasswordEncoder should be used. This is not safe for production, but makes reading
|
||||||
|
in samples easier. Normally passwords should be hashed using BCrypt -->
|
||||||
|
<user name="jimi" password="{noop}jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
|
||||||
|
<user name="bob" password="{noop}bobspassword" authorities="ROLE_USER" />
|
||||||
|
</user-service>
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
This also supports the use of an external properties file:
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<user-service id="userDetailsService" properties="users.properties"/>
|
||||||
|
----
|
||||||
|
|
||||||
|
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]
|
||||||
|
----
|
||||||
|
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||||
|
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
|
||||||
|
<property name="url" value="jdbc:hsqldb:hsql://localhost:9001"/>
|
||||||
|
<property name="username" value="sa"/>
|
||||||
|
<property name="password" value=""/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="userDetailsService"
|
||||||
|
class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
|
||||||
|
<property name="dataSource" ref="dataSource"/>
|
||||||
|
</bean>
|
||||||
|
----
|
||||||
|
|
||||||
|
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 <<appendix-schema,database schema appendix>>).
|
||||||
|
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[]
|
||||||
|
|
@ -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[]
|
@ -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]]
|
||||||
== 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.
|
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.
|
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 <<ns-auth-manager,the namespace chapter>>).
|
|
||||||
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]
|
|
||||||
----
|
|
||||||
|
|
||||||
<bean id="authenticationManager"
|
|
||||||
class="org.springframework.security.authentication.ProviderManager">
|
|
||||||
<constructor-arg>
|
|
||||||
<list>
|
|
||||||
<ref local="daoAuthenticationProvider"/>
|
|
||||||
<ref local="anonymousAuthenticationProvider"/>
|
|
||||||
<ref local="ldapAuthenticationProvider"/>
|
|
||||||
</list>
|
|
||||||
</constructor-arg>
|
|
||||||
</bean>
|
|
||||||
----
|
|
||||||
|
|
||||||
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]
|
|
||||||
----
|
|
||||||
|
|
||||||
<bean id="daoAuthenticationProvider"
|
|
||||||
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
|
|
||||||
<property name="userDetailsService" ref="inMemoryDaoImpl"/>
|
|
||||||
<property name="passwordEncoder" ref="passwordEncoder"/>
|
|
||||||
</bean>
|
|
||||||
----
|
|
||||||
|
|
||||||
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 <<core-services-password-encoding,below>>.
|
|
||||||
|
|
||||||
|
|
||||||
=== 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 <<ns-minimal,namespace>>:
|
|
||||||
|
|
||||||
[source,xml]
|
|
||||||
----
|
|
||||||
<user-service id="userDetailsService">
|
|
||||||
<!-- Password is prefixed with {noop} to indicate to DelegatingPasswordEncoder that
|
|
||||||
NoOpPasswordEncoder should be used. This is not safe for production, but makes reading
|
|
||||||
in samples easier. Normally passwords should be hashed using BCrypt -->
|
|
||||||
<user name="jimi" password="{noop}jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
|
|
||||||
<user name="bob" password="{noop}bobspassword" authorities="ROLE_USER" />
|
|
||||||
</user-service>
|
|
||||||
----
|
|
||||||
|
|
||||||
|
|
||||||
This also supports the use of an external properties file:
|
|
||||||
|
|
||||||
[source,xml]
|
|
||||||
----
|
|
||||||
<user-service id="userDetailsService" properties="users.properties"/>
|
|
||||||
----
|
|
||||||
|
|
||||||
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]
|
|
||||||
----
|
|
||||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
|
||||||
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
|
|
||||||
<property name="url" value="jdbc:hsqldb:hsql://localhost:9001"/>
|
|
||||||
<property name="username" value="sa"/>
|
|
||||||
<property name="password" value=""/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="userDetailsService"
|
|
||||||
class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
|
|
||||||
<property name="dataSource" ref="dataSource"/>
|
|
||||||
</bean>
|
|
||||||
----
|
|
||||||
|
|
||||||
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 <<appendix-schema,database schema appendix>>).
|
|
||||||
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[]
|
|
||||||
|
|
@ -8,7 +8,7 @@ It is the de-facto standard for securing Spring-based applications.
|
|||||||
|
|
||||||
include::{include-dir}/preface/index.adoc[]
|
include::{include-dir}/preface/index.adoc[]
|
||||||
|
|
||||||
include::{include-dir}/architecture.adoc[]
|
include::{include-dir}/architecture/index.adoc[]
|
||||||
|
|
||||||
include::{include-dir}/test.adoc[]
|
include::{include-dir}/test.adoc[]
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user