diff --git a/docs/manual/src/docbook/common-auth-services.xml b/docs/manual/src/docbook/common-auth-services.xml index 1b5f1b2ff0..9007a578a4 100644 --- a/docs/manual/src/docbook/common-auth-services.xml +++ b/docs/manual/src/docbook/common-auth-services.xml @@ -1,139 +1,71 @@ - - Common Authentication Services - + + + Common Authentication Services +
Mechanisms, Providers and Entry Points - - To use Spring Security's authentication services, - you'll usually need to configure a web filter, together - with an AuthenticationProvider and - AuthenticationEntryPoint. In this section we are - going to explore an example application that needs to support both - form-based authentication (so a nice HTML page is presented to a - user for them to login) and BASIC authentication (so a web service - or similar can access protected resources). - - In the web.xml, this application will need a single Spring - Security filter in order to use the FilterChainProxy. Nearly every - Spring Security application will have such an entry, and it looks like - this: - - - filterChainProxy - org.springframework.web.filter.DelegatingFilterProxy - - - - filterChainProxy - /* -]]> - - - The above declarations will cause every web request to be passed - through to the bean called filterChainProxy - which will usually be an instance of Spring Security's - FilterChainProxy. - As explained in the filters section of this reference guide, the - FilterChainProxy is a generally-useful class - that enables web requests to be passed to different filters based on - URL patterns. Those delegated filters are managed inside the - application context, so they can benefit from dependency injection. - Let's have a look at what the FilterChainProxy bean definition would - look like inside your application context: - - - - - -]]> - - The filter-chain-map syntax from the security namespace - allows you to define the mapping from URLs to filter chains, using a sequence of - filter-chain child elements. Each of these defines a set of URLs using - the pattern attribute and a chain of filters using the filters - attribute.What's important to note at this stage is that a series of filters will be - run - in the order specified by the declaration - and each of those - filters are actually the id of another - bean in the application context. So, in our case some extra beans - will also appear in the application context, and they'll be named - httpSessionContextIntegrationFilter, - logoutFilter and so on. The order that the filters - should appear is discussed in the filters section of the reference - guide - although they are correct in the above example. - + To use Spring Security's authentication services, you'll usually need to configure a web + filter, together with an AuthenticationProvider and + AuthenticationEntryPoint. In this section we are going to + explore an example application that needs to support both form-based authentication (so a nice + HTML page is presented to a user for them to login) and BASIC authentication (so a web service + or similar can access protected resources). + The filter-chain-map syntax from the security namespace allows you to + define the mapping from URLs to filter chains, using a sequence of + filter-chain child elements. Each of these defines a set of URLs using + the pattern attribute and a chain of filters using the + filters attribute.What's important to note at this stage is that a series + of filters will be run - in the order specified by the declaration - and each of those filters + are actually the id of another bean in the application context. So, in our + case some extra beans will also appear in the application context, and they'll be named + httpSessionContextIntegrationFilter, logoutFilter and + so on. The order that the filters should appear is discussed in the filters section of the + reference guide - although they are correct in the above example. In our example we have the - UsernamePasswordAuthenticationProcessingFilter and - BasicProcessingFilter being used. These are the - "authentication mechanisms" that respond to form-based authentication - and BASIC HTTP header-based authentication respectively (we discussed - the role of authentication mechanisms earlier in this reference - guide). If you weren't using form or BASIC authentication, neither of - these beans would be defined. You'd instead define filters applicable - to your desired authentication environment, such as - DigestProcessingFilter or - CasProcessingFilter. Refer to the individual - chapters of this part of the reference guide to learn how to configure - each of these authentication mechanisms. - - Recall that - HttpSessionContextIntegrationFilter keeps the - contents of the SecurityContext between invocations - inside an HTTP session. This means the authentication mechanisms are - only used once, being when the principal initially tries to - authenticate. The rest of the time the authentication mechanisms sit - there and silently pass the request through to the next filter in the - chain. That is a practical requirement due to the fact that few - authentication approaches present credentials on each and every call - (BASIC authentication being a notable exception), but what happens if - a principal's account gets cancelled or disabled or otherwise changed - (eg an increase or decrease in GrantedAuthority[]s) - after the initial authentication step? Let's look at how that is - handled now. - - The major authorization provider for secure objects has - previously been introduced as - AbstractSecurityInterceptor. This class needs to - have access to an AuthenticationManager. It also - has configurable settings to indicate whether an - Authentication object should be re-authenticated on - each secure object invocation. By default it just accepts any - Authentication inside the - SecurityContextHolder is authenticated if - Authentication.isAuthenticated() returns true. This - is great for performance, but not ideal if you want to ensure - up-to-the-moment authentication validity. For such cases you'll - probably want to set the - AbstractSecurityInterceptor.alwaysReauthenticate - property to true. - + UsernamePasswordAuthenticationProcessingFilter and + BasicProcessingFilter being used. These are the "authentication + mechanisms" that respond to form-based authentication and BASIC HTTP header-based + authentication respectively (we discussed the role of authentication mechanisms earlier in + this reference guide). If you weren't using form or BASIC authentication, neither of these + beans would be defined. You'd instead define filters applicable to your desired authentication + environment, such as DigestProcessingFilter or + CasProcessingFilter. Refer to the individual chapters of this part of the + reference guide to learn how to configure each of these authentication mechanisms. + Recall that HttpSessionContextIntegrationFilter keeps the contents + of the SecurityContext between invocations inside an HTTP + session. This means the authentication mechanisms are only used once, being when the principal + initially tries to authenticate. The rest of the time the authentication mechanisms sit there + and silently pass the request through to the next filter in the chain. That is a practical + requirement due to the fact that few authentication approaches present credentials on each and + every call (BASIC authentication being a notable exception), but what happens if a principal's + account gets cancelled or disabled or otherwise changed (eg an increase or decrease in + GrantedAuthority[]s) after the initial authentication step? Let's look at + how that is handled now. + The major authorization provider for secure objects has previously been introduced as + AbstractSecurityInterceptor. This class needs to have access to an + AuthenticationManager. It also has configurable settings to + indicate whether an Authentication object should be + re-authenticated on each secure object invocation. By default it just accepts any + Authentication inside the + SecurityContextHolder is authenticated if + Authentication.isAuthenticated() returns true. This is great for + performance, but not ideal if you want to ensure up-to-the-moment authentication validity. For + such cases you'll probably want to set the + AbstractSecurityInterceptor.alwaysReauthenticate property to true. You might be asking yourself, "what's this - AuthenticationManager?". We haven't explored it - before, but we have discussed the concept of an - AuthenticationProvider. Quite simply, an - AuthenticationManager is responsible - for passing requests through a chain of AuthenticationProviders. It's - a little like the filter chain we discussed earlier, although there - are some differences. There is only one - AuthenticationManager implementation - shipped with Spring Security, so let's look at how it's configured for - the example we're using in this chapter: - - AuthenticationManager?". We haven't explored it before, but + we have discussed the concept of an AuthenticationProvider. Quite + simply, an AuthenticationManager is responsible for passing + requests through a chain of AuthenticationProviders. It's a little like the filter chain we + discussed earlier, although there are some differences. There is only one + AuthenticationManager implementation shipped with Spring + Security, so let's look at how it's configured for the example we're using in this + chapter: + + @@ -143,60 +75,47 @@ -]]> - - It's probably worth mentioning at this point that your - authentication mechanisms (which are usually filters) are also - injected with a reference to the - AuthenticationManager. So both - AbstractSecurityInterceptor as well as the - authentication mechanisms will use the above - ProviderManager to poll a list of - AuthenticationProviders. - - In our example we have three providers. They are tried in the - order shown (which is implied by the use of a List - instead of a Set), with each provider able to - attempt authentication, or skip authentication by simply returning - null. If all implementations return null, the - ProviderManager will throw a suitable exception. If - you're interested in learning more about chaining providers, please - refer to the ProviderManager JavaDocs. - - The providers to use will sometimes be interchangeable with the - authentication mechanisms, whilst at other times they will depend on a - specific authentication mechanism. For example, the - DaoAuthenticationProvider just needs a string-based - username and password. Various authentication mechanisms result in the - collection of a string-based username and password, including (but not - limited to) BASIC and form authentication. Equally, some - authentication mechanisms create an authentication request object - which can only be interpreted by a single type of - AuthenticationProvider. An example of this - one-to-one mapping would be JA-SIG CAS, which uses the notion of a - service ticket which can therefore only be authenticated by - CasAuthenticationProvider. A further example of a - one-to-one mapping would be the LDAP authentication mechanism, which - can only be processed an the - LdapAuthenticationProvider. The specifics of such - relationships are detailed in the JavaDocs for each class, plus the - authentication approach-specific chapters of this reference guide. You - need not be terribly concerned about this implementation detail, - because if you forget to register a suitable provider, you'll simply - receive a ProviderNotFoundException when an attempt - to authenticate is made. - +]]> + + It's probably worth mentioning at this point that your authentication mechanisms (which + are usually filters) are also injected with a reference to the + AuthenticationManager. So both + AbstractSecurityInterceptor as well as the authentication mechanisms + will use the above ProviderManager to poll a list of + AuthenticationProviders. + In our example we have three providers. They are tried in the order shown (which is + implied by the use of a List instead of a Set), with + each provider able to attempt authentication, or skip authentication by simply returning + null. If all implementations return null, the + ProviderManager will throw a suitable exception. If you're interested in + learning more about chaining providers, please refer to the ProviderManager + JavaDocs. + The providers to use will sometimes be interchangeable with the authentication mechanisms, + whilst at other times they will depend on a specific authentication mechanism. For example, + the DaoAuthenticationProvider just needs a string-based username and + password. Various authentication mechanisms result in the collection of a string-based + username and password, including (but not limited to) BASIC and form authentication. Equally, + some authentication mechanisms create an authentication request object which can only be + interpreted by a single type of AuthenticationProvider. An example of + this one-to-one mapping would be JA-SIG CAS, which uses the notion of a service ticket which + can therefore only be authenticated by CasAuthenticationProvider. A further + example of a one-to-one mapping would be the LDAP authentication mechanism, which can only be + processed an the LdapAuthenticationProvider. The specifics of such + relationships are detailed in the JavaDocs for each class, plus the authentication + approach-specific chapters of this reference guide. You need not be terribly concerned about + this implementation detail, because if you forget to register a suitable provider, you'll + simply receive a ProviderNotFoundException when an attempt to authenticate + is made. After configuring the correct authentication mechanisms in the - FilterChainProxy, and ensuring that a corresponding - AuthenticationProvider is registered in the - ProviderManager, your last step is to configure an - AuthenticationEntryPoint. Recall that earlier we - discussed the role of ExceptionTranslationFilter, - which is used when HTTP-based requests should receive back an HTTP - header or HTTP redirect in order to start authentication. Continuing - on with our earlier example: - - FilterChainProxy, and ensuring that a corresponding + AuthenticationProvider is registered in the + ProviderManager, your last step is to configure an + AuthenticationEntryPoint. Recall that earlier we discussed + the role of ExceptionTranslationFilter, which is used when HTTP-based + requests should receive back an HTTP header or HTTP redirect in order to start authentication. + Continuing on with our earlier example: + + @@ -211,132 +130,105 @@ class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"> -]]> - - Notice that the ExceptionTranslationFilter - requires two collaborators. The first, - AccessDeniedHandlerImpl, uses a - RequestDispatcher forward to display the specified - access denied error page. We use a forward so that the - SecurityContextHolder still contains details of the - principal, which may be useful for display to the user (in old - releases of Spring Security we relied upon the servlet container to - handle a 403 error message, which lacked this useful contextual - information). AccessDeniedHandlerImpl will also set - the HTTP header to 403, which is the official error code to indicate - access denied. In the case of the - AuthentionEntryPoint, here we're setting what - action we would like taken when an unauthenticated principal attempts - to perform a protected operation. Because in our example we're going - to be using form-based authentication, we specify - AuthenticationProcessinFilterEntryPoint and the URL - of the login page. Your application will usually only have one entry - point, and most authentication approaches define their own specific - AuthenticationEntryPoint. Details of which entry - point to use for each authentication approach is discussed in the - authentication approach-specific chapters of this reference - guide. +]]> + + Notice that the ExceptionTranslationFilter requires two + collaborators. The first, AccessDeniedHandlerImpl, uses a + RequestDispatcher forward to display the specified access denied error + page. We use a forward so that the SecurityContextHolder still contains + details of the principal, which may be useful for display to the user (in old releases of + Spring Security we relied upon the servlet container to handle a 403 error message, which + lacked this useful contextual information). AccessDeniedHandlerImpl will + also set the HTTP header to 403, which is the official error code to indicate access denied. + In the case of the AuthentionEntryPoint, here we're setting what action we + would like taken when an unauthenticated principal attempts to perform a protected operation. + Because in our example we're going to be using form-based authentication, we specify + AuthenticationProcessinFilterEntryPoint and the URL of the login page. + Your application will usually only have one entry point, and most authentication approaches + define their own specific AuthenticationEntryPoint. Details of + which entry point to use for each authentication approach is discussed in the authentication + approach-specific chapters of this reference guide.
-
- UserDetails and Associated Types - - - As mentioned in the first part of the reference guide, most - authentication providers take advantage of the - UserDetails and - UserDetailsService interfaces. The contract for - this latter interface consists of a single method: - - + + UserDetails and Associated Types + + As mentioned in the first part of the reference guide, most authentication providers take + advantage of the UserDetails and + UserDetailsService interfaces. The contract for this latter + interface consists of a single method: + + UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException; - - - The returned UserDetails is an interface that - provides getters that guarantee non-null provision of basic - authentication information such as the username, password, granted - authorities and whether the user 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. - Generally such providers will be using the returned - UserDetails object just for its - GrantedAuthority[] information, because some other - system (like LDAP or X509 or CAS etc) has undertaken the - responsibility of actually validating the credentials. - - A single concrete implementation of - UserDetails is provided with Spring Security, being - the User class. Spring Security users will need to - decide when writing their UserDetailsService what - concrete UserDetails class to return. In most cases - User will be used directly or subclassed, although - special circumstances (such as object relational mappers) may require - users to write their own UserDetails implementation - from scratch. This is not such an unusual situation, and users should - not hesitate to simply return their normal domain object that - represents a user of the system. This is especially common given that - UserDetails is often used to store additional - principal-related properties (such as their telephone number and email - address), so that they can be easily used by web views. - - 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. - + + + The returned UserDetails is an interface that provides + getters that guarantee non-null provision of basic authentication information such as the + username, password, granted authorities and whether the user 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. + Generally such providers will be using the returned UserDetails + object just for its GrantedAuthority[] information, because some other + system (like LDAP or X509 or CAS etc) has undertaken the responsibility of actually validating + the credentials. + A single concrete implementation of UserDetails is provided + with Spring Security, being the User class. Spring Security users will need + to decide when writing their UserDetailsService what concrete + UserDetails class to return. In most cases + User will be used directly or subclassed, although special circumstances + (such as object relational mappers) may require users to write their own + UserDetails implementation from scratch. This is not such an + unusual situation, and users should not hesitate to simply return their normal domain object + that represents a user of the system. This is especially common given that + UserDetails is often used to store additional + principal-related properties (such as their telephone number and email address), so that they + can be easily used by web views. + 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.
- In-Memory Authentication + + In-Memory Authentication + Whilst it is easy to use create a custom - UserDetailsService implementation that extracts - information from a persistence engine of choice, many applications - do not require such complexity. This is particularly true if you're - undertaking a rapid prototype 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 - namespace: -UserDetailsService implementation that extracts information + from a persistence engine of choice, many applications do not require such complexity. This + is particularly true if you're undertaking a rapid prototype 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 namespace: ]]> - - This also suppots the use of an external properties file: - This also suppots the use of an external properties file: - ]]> - The properties file should contain entries in the form - + ]]> The properties file should contain entries in the form + username=password,grantedAuthority[,grantedAuthority][,enabled|disabled] For example - + jimi=jimispassword,ROLE_USER,ROLE_ADMIN,enabled bob=bobspassword,ROLE_USER,enabled - - +
-
JDBC Authentication - 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: - - + 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: + + @@ -347,21 +239,17 @@ - ]]> - - 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 - per normal Spring options. + ]]> - + 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 per normal Spring options.
Default User Database Schema - - Irrespective of the database you are using and how - a DataSource is obtained, a standard schema must - be in place. The DDL for an HSQL database instance would be: - + Irrespective of the database you are using and how a DataSource is + obtained, a standard schema must be in place. The DDL for an HSQL database instance would + be: + CREATE TABLE users ( username VARCHAR(50) NOT NULL PRIMARY KEY, password VARCHAR(50) NOT NULL, @@ -375,66 +263,49 @@ ALTER TABLE authorities ADD CONSTRAINT fk_authorities_users \ foreign key (username) REFERENCES users(username); - - - - If the default schema is unsuitable for your needs, - JdbcDaoImpl provides properties that allow - customisation of the SQL statements. Please refer to the JavaDocs for - details, but note that the class is not intended for complex custom subclasses. - If you have a complex schema or would like a - custom UserDetails implementation returned, - you'd be better off writing your own - UserDetailsService. The base implementation - provided with Spring Security is intended for typical situations, - rather than catering for all possible requirements. + + If the default schema is unsuitable for your needs, JdbcDaoImpl + provides properties that allow customisation of the SQL statements. Please refer to the + JavaDocs for details, but note that the class is not intended for complex custom + subclasses. If you have a complex schema or would like a custom + UserDetails implementation returned, you'd be better off + writing your own UserDetailsService. The base + implementation provided with Spring Security is intended for typical situations, rather + than catering for all possible requirements.
-
- Concurrent Session Handling - - Spring Security is able to prevent a principal from concurrently - authenticating to the same application more than a specified number of - times. Many ISVs take advantage of this to enforce licensing, whilst - network administrators like this feature because it helps prevent - people from sharing login names. You can, for example, stop user - "Batman" from logging onto the web application from two different - sessions. - - To use concurrent session support, you'll need to add the - following to web.xml: - + Concurrent Session Handling + + Spring Security is able to prevent a principal from concurrently authenticating to the + same application more than a specified number of times. Many ISVs take advantage of this to + enforce licensing, whilst network administrators like this feature because it helps prevent + people from sharing login names. You can, for example, stop user "Batman" from logging onto + the web application from two different sessions. + To use concurrent session support, you'll need to add the following to + web.xml: org.springframework.security.web.session.HttpSessionEventPublisher ]]> - - - + In addition, you will need to add the - org.springframework.security.web.authentication.concurrent.ConcurrentSessionFilter - to your FilterChainProxy. The - ConcurrentSessionFilter requires two - properties, sessionRegistry, which generally points - to an instance of SessionRegistryImpl, and - expiredUrl, which points to the page to display - when a session has expired. - + org.springframework.security.web.authentication.concurrent.ConcurrentSessionFilter + to your FilterChainProxy. The + ConcurrentSessionFilter requires two properties, + sessionRegistry, which generally points to an instance of + SessionRegistryImpl, and expiredUrl, which points to + the page to display when a session has expired. The web.xml - HttpSessionEventPublisher causes an - ApplicationEvent to be published to the Spring - ApplicationContext every time a - HttpSession commences or terminates. This is - critical, as it allows the SessionRegistryImpl to - be notified when a session ends. - - You will also need to wire up the - ConcurrentSessionControllerImpl and refer to it - from your ProviderManager bean: - + HttpSessionEventPublisher causes an ApplicationEvent to + be published to the Spring ApplicationContext every time a + HttpSession commences or terminates. This is critical, as it allows the + SessionRegistryImpl to be notified when a session ends. + You will also need to wire up the ConcurrentSessionControllerImpl + and refer to it from your ProviderManager bean: -]]> +]]> +
-
- Authentication Tag Libraries - - AuthenticationTag is used to simply output a - property of the current Authentication object to the web - page. - + + Authentication Tag Libraries + + AuthenticationTag is used to simply output a property of the current + Authentication object to the web page. The following JSP fragment illustrates how to use the - AuthenticationTag: - - <security:authentication property="principal.username"/> - - This tag would cause the principal's name to be output. Here we - are assuming the Authentication.getPrincipal() is a - UserDetails object, which is generally the case - when using one of Spring Security's stadard AuthenticationProvider + AuthenticationTag: + + <security:authentication property="principal.username"/> + + This tag would cause the principal's name to be output. Here we are assuming the + Authentication.getPrincipal() is a + UserDetails object, which is generally the case when using + one of Spring Security's stadard AuthenticationProvider implementations.
-
\ No newline at end of file +
diff --git a/docs/manual/src/docbook/container-adapters.xml b/docs/manual/src/docbook/container-adapters.xml deleted file mode 100644 index 1d095802bb..0000000000 --- a/docs/manual/src/docbook/container-adapters.xml +++ /dev/null @@ -1,450 +0,0 @@ -Container Adapter Authentication - - -
- Overview - - - Very early versions of Spring Security exclusively used - Container Adapters for interfacing authentication with end users. - Whilst this worked well, it required considerable time to support - multiple container versions and the configuration itself was - relatively time-consuming for developers. For this reason the HTTP - Form Authentication and HTTP Basic Authentication approaches were - developed, and are today recommended for almost all - applications. - - Container Adapters enable Spring Security to integrate directly - with the containers used to host end user applications. This - integration means that applications can continue to leverage the - authentication and authorization capabilities built into containers - (such as isUserInRole() and form-based or basic - authentication), whilst benefiting from the enhanced security - interception capabilities provided by Spring Security (it should be - noted that Spring Security also offers - ContextHolderAwareRequestWrapper to deliver - isUserInRole() and similar Servlet Specification - compatibility methods). - - The integration between a container and Spring Security is - achieved through an adapter. The adapter provides a - container-compatible user authentication provider, and needs to return - a container-compatible user object. - - The adapter is instantiated by the container and is defined in a - container-specific configuration file. The adapter then loads a Spring - application context which defines the normal authentication manager - settings, such as the authentication providers that can be used to - authenticate the request. The application context is usually named - acegisecurity.xml and is placed in a - container-specific location. - - Spring Security currently supports Jetty, Catalina (Tomcat), - JBoss and Resin. Additional container adapters can easily be - written -
- -
Adapter Authentication Provider - - - As is always the case, the container adapter generated - Authentication object still needs to be - authenticated by an AuthenticationManager when - requested to do so by the - AbstractSecurityInterceptor. The - AuthenticationManager needs to be certain the - adapter-provided Authentication object is valid and - was actually authenticated by a trusted adapter. - - Adapters create Authentication objects which - are immutable and implement the AuthByAdapter - interface. These objects store the hash of a key that is defined by - the adapter. This allows the Authentication object - to be validated by the AuthByAdapterProvider. This - authentication provider is defined as follows: - - <bean id="authByAdapterProvider" - class="org.springframework.security.adapters.AuthByAdapterProvider"> -<property name="key"><value>my_password</value></property> -</bean> - - The key must match the key that is defined in the - container-specific configuration file that starts the adapter. The - AuthByAdapterProvider automatically accepts as - valid any AuthByAdapter implementation that returns - the expected hash of the key. - - To reiterate, this means the adapter will perform the initial - authentication using providers such as - DaoAuthenticationProvider, returning an - AuthByAdapter instance that contains a hash code of - the key. Later, when an application calls a security interceptor - managed resource, the AuthByAdapter instance in the - SecurityContext in the - SecurityContextHolder will be tested by the - application's AuthByAdapterProvider. There is no - requirement for additional authentication providers such as - DaoAuthenticationProvider within the - application-specific application context, as the only type of - Authentication instance that will be presented by - the application is from the container adapter. - - Classloader issues are frequent with containers and the use of - container adapters illustrates this further. Each container requires a - very specific configuration. The installation instructions are - provided below. Once installed, please take the time to try the sample - application to ensure your container adapter is properly - configured. - - When using container adapters with the - DaoAuthenticationProvider, ensure you set its - forcePrincipalAsString property to - true. -
- -
Jetty - - - The following was tested with Jetty 4.2.18. - - $JETTY_HOME refers to the root of your Jetty - installation. - - Edit your $JETTY_HOME/etc/jetty.xml file so - the <Configure class> section has a new - addRealm call: - - -<Call name="addRealm"> -<Arg> - <New class="org.springframework.security.adapters.jetty.JettySpringSecurityUserRealm"> - <Arg>Spring Powered Realm</Arg> - <Arg>my_password</Arg> - <Arg>etc/acegisecurity.xml</Arg> - </New> -</Arg> -</Call> - - - - Copy acegisecurity.xml into - $JETTY_HOME/etc. - - Copy the following files into - $JETTY_HOME/ext: - - aopalliance.jar - - - - commons-logging.jar - - - - spring.jar - - - - acegi-security-jetty-XX.jar - - - - commons-codec.jar - - - - burlap.jar - - - - hessian.jar - - - - None of the above JAR files (or - acegi-security-XX.jar) should be in your - application's WEB-INF/lib. The realm name indicated - in your web.xml does matter with Jetty. The - web.xml must express the same - <realm-name> as your - jetty.xml (in the example above, "Spring Powered - Realm"). -
- -
JBoss - - - The following was tested with JBoss 3.2.6. - - $JBOSS_HOME refers to the root of your JBoss - installation. - - There are two different ways of making spring context available - to the Jboss integration classes. - - The first approach is by editing your - $JBOSS_HOME/server/your_config/conf/login-config.xml - file so that it contains a new entry under the - <Policy> section: - - -<application-policy name = "SpringPoweredRealm"> -<authentication> - <login-module code = "org.springframework.security.adapters.jboss.JbossSpringSecurityLoginModule" - flag = "required"> - <module-option name = "appContextLocation">acegisecurity.xml</module-option> - <module-option name = "key">my_password</module-option> - </login-module> -</authentication> -</application-policy> - - - - Copy acegisecurity.xml into - $JBOSS_HOME/server/your_config/conf. - - In this configuration acegisecurity.xml - contains the spring context definition including all the - authentication manager beans. You have to bear in mind though, that - SecurityContext is created and destroyed on each - login request, so the login operation might become costly. - Alternatively, the second approach is to use Spring singleton - capabilities through - org.springframework.beans.factory.access.SingletonBeanFactoryLocator. - The required configuration for this approach is: - - -<application-policy name = "SpringPoweredRealm"> -<authentication> - <login-module code = "org.springframework.security.adapters.jboss.JbossSpringSecurityLoginModule" - flag = "required"> - <module-option name = "singletonId">springRealm</module-option> - <module-option name = "key">my_password</module-option> - <module-option name = "authenticationManager">authenticationManager</module-option> - </login-module> -</authentication> -</application-policy> - - - - In the above code fragment, - authenticationManager is a helper property that - defines the expected name of the - AuthenticationManager in case you have several - defined in the IoC container. The singletonId - property references a bean defined in a - beanRefFactory.xml file. This file needs to be - available from anywhere on the JBoss classpath, including - $JBOSS_HOME/server/your_config/conf. The - beanRefFactory.xml contains the following - declaration: - - -<beans> -<bean id="springRealm" singleton="true" lazy-init="true" class="org.springframework.context.support.ClassPathXmlApplicationContext"> -<constructor-arg> - <list> - <value>acegisecurity.xml</value> - </list> -</constructor-arg> -</bean> -</beans> - - - - Finally, irrespective of the configuration approach you need to - copy the following files into - $JBOSS_HOME/server/your_config/lib: - - aopalliance.jar - - - - spring.jar - - - - acegi-security-jboss-XX.jar - - - - commons-codec.jar - - - - burlap.jar - - - - hessian.jar - - - - None of the above JAR files (or - acegi-security-XX.jar) should be in your - application's WEB-INF/lib. The realm name indicated - in your web.xml does not matter with JBoss. - However, your web application's - WEB-INF/jboss-web.xml must express the same - <security-domain> as your - login-config.xml. For example, to match the above - example, your jboss-web.xml would look like - this: - - -<jboss-web> -<security-domain>java:/jaas/SpringPoweredRealm</security-domain> -</jboss-web> - - JBoss is a widely-used container adapter (mostly due to the need - to support legacy EJBs), so please let us know if you have any - difficulties. -
- -
Resin - - - The following was tested with Resin 3.0.6. - - $RESIN_HOME refers to the root of your Resin - installation. - - Resin provides several ways to support the container adapter. In - the instructions below we have elected to maximise consistency with - other container adapter configurations. This will allow Resin users to - simply deploy the sample application and confirm correct - configuration. Developers comfortable with Resin are naturally able to - use its capabilities to package the JARs with the web application - itself, and/or support single sign-on. - - Copy the following files into - $RESIN_HOME/lib: - - aopalliance.jar - - - - commons-logging.jar - - - - spring.jar - - - - acegi-security-resin-XX.jar - - - - commons-codec.jar - - - - burlap.jar - - - - hessian.jar - - - - Unlike the container-wide acegisecurity.xml - files used by other container adapters, each Resin web application - will contain its own - WEB-INF/resin-acegisecurity.xml file. Each web - application will also contain a resin-web.xml file - which Resin uses to start the container adapter: - - -<web-app> -<authenticator> -<type>org.springframework.security.adapters.resin.ResinAcegiAuthenticator</type> -<init> - <app-context-location>WEB-INF/resin-acegisecurity.xml</app-context-location> - <key>my_password</key> -</init> -</authenticator> -</web-app> - - - - With the basic configuration provided above, none of the JAR - files listed (or acegi-security-XX.jar) should be - in your application's WEB-INF/lib. The realm name - indicated in your web.xml does not matter with - Resin, as the relevant authentication class is indicated by the - <authenticator> setting -
- -
Tomcat - - - The following was tested with Jakarta Tomcat 4.1.30 and - 5.0.19. - - $CATALINA_HOME refers to the root of your - Catalina (Tomcat) installation. - - Edit your $CATALINA_HOME/conf/server.xml file - so the <Engine> section contains only one - active <Realm> entry. An example realm - entry: - - <Realm - className="org.springframework.security.adapters.catalina.CatalinaSpringSecurityUserRealm" - appContextLocation="conf/acegisecurity.xml" - key="my_password" /> - - Be sure to remove any other <Realm> - entry from your <Engine> section. - - Copy acegisecurity.xml into - $CATALINA_HOME/conf. - - Copy spring-security-catalina-XX.jar into - $CATALINA_HOME/server/lib. - - Copy the following files into - $CATALINA_HOME/common/lib: - - - - aopalliance.jar - - - - spring.jar - - - - commons-codec.jar - - - - burlap.jar - - - - hessian.jar - - - - None of the above JAR files (or - spring-security-XX.jar) should be in your - application's WEB-INF/lib. The realm name indicated - in your web.xml does not matter with - Catalina. - - We have received reports of problems using this Container - Adapter with Mac OS X. A work-around is to use a script such as - follows: - - #!/bin/sh -export CATALINA_HOME="/Library/Tomcat" -export JAVA_HOME="/Library/Java/Home" -cd / -$CATALINA_HOME/bin/startup.sh - - Finally, restart Tomcat. -
-
\ No newline at end of file diff --git a/docs/manual/src/docbook/namespace-config.xml b/docs/manual/src/docbook/namespace-config.xml index 19e6ebce6e..e74553a473 100644 --- a/docs/manual/src/docbook/namespace-config.xml +++ b/docs/manual/src/docbook/namespace-config.xml @@ -681,8 +681,8 @@ We've touched on the idea that the namespace configuration automatically registers an authentication manager bean for you. This is an instance of Spring Security's ProviderManager class, which you may already be familiar with if - you've used the framework before. You can't use a custom - AuthenticationManager if you are using either HTTP or method security + you've used the framework before. If not, it will be covered later, in . + You can't use a custom AuthenticationManager if you are using either HTTP or method security through the namespace, but this should not be a problem as you have full control over the AuthenticationProviders that are used. You may want to register additional AuthenticationProvider beans diff --git a/docs/manual/src/docbook/springsecurity.xml b/docs/manual/src/docbook/springsecurity.xml index fb1ece045a..69e8594907 100644 --- a/docs/manual/src/docbook/springsecurity.xml +++ b/docs/manual/src/docbook/springsecurity.xml @@ -86,7 +86,7 @@ - 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 @@ -97,23 +97,7 @@ Security. - - - - - - Web Application Security - - - Most Spring Security users will be using the framework in enterprise applications which - make user of the HTTP and the Servlet API. In this part we'll take a look at how Spring Security provides - authentication and access-control features for the web layer of an application. We'll look - behind the facade of the namespace and see which classes and interfaces are actually assembled to provide web-layer - security. In some situations it is necessary to use traditional bean configuration to provide full control over - the configuration, so we'll also see how to configure these classes directly without the namespace. - - - + Authentication @@ -138,16 +122,11 @@ - - - - + - - @@ -168,6 +147,23 @@ + + Advanced Topics + + + + In this part we cover some of the more advanced features of the framework. + + + + + + + + + diff --git a/docs/manual/src/docbook/supporting-infrastructure.xml b/docs/manual/src/docbook/supporting-infrastructure.xml deleted file mode 100644 index a005f9bf7c..0000000000 --- a/docs/manual/src/docbook/supporting-infrastructure.xml +++ /dev/null @@ -1,260 +0,0 @@ - - - Web Security Infrastructure - -
- Spring Security Filters - - Spring Security's web application features are implemented using standard servlet filters. It doesn't use - servlets or any other servlet-based frameworks (such as Spring MVC) internally. So it has no strong links to any - particular web technology - it deals in HttpServletRequests and HttpServletResponses - and doesn't care whether the requests come from a browser, a web service client, an HttpInvoker or an AJAX application. - - - Spring Security maintains a filter chain internally where each of the filters has a particular responsibility and filters are added or removed - depending on which services are required. The ordering of the filters is important as there are dependencies between them. - If you have been using namespace configuration, then the filters are automatically configured for you - and you don't have to define any Spring beans explicitly but here may be times when you want full control over the security filter chain, - either because you are using features which aren't supported in the namespace, or you are using your own customized versions of classes. - -
- <classname>DelegatingFilterProxy</classname> - - When using servlet filters, you obviously need to declare them in your web.xml, or they will be ignored - by the servlet container. In Spring Security, the filter classes are also Spring beans defined in the application context and thus able - to take advantage of Spring's rich dependency-injection facilities and lifecycle interfaces. Spring's DelegatingFilterProxy - provides the link between web.xml and the application context. - - When using DelegatingFilterProxy, you will see something like this in the web.xml file: - - - myFilter - org.springframework.web.filter.DelegatingFilterProxy - - - - myFilter - /* - ]]> - - Notice that the filter is actually a DelegatingFilterProxy, - and not the class that will actually implement the logic of the filter. What - DelegatingFilterProxy does is delegate the - Filter's methods through to a bean which is - obtained from the Spring application context. This enables the bean to - benefit from the Spring web application context lifecycle support and - configuration flexibility. The bean must implement - javax.servlet.Filter and it must have the same name as that in - the filter-name element. Read the Javadoc for DelegatingFilterProxy - for more information -
-
- <classname>FilterChainProxy</classname> - - It should now be clear that you can declare each Spring Security filter bean that you require in your application context file and add a corresponding - DelegatingFilterProxy entry to web.xml for each filter, making sure that they are ordered correctly. - This is a cumbersome approach and clutters up the web.xml file quickly if we have a lot of filters. We would prefer to just add - a single entry to web.xml and deal entirely with the application context file for managing our web security beans. - This is where Spring Secuiryt's FilterChainProxy comes in. It is wired using a DelegatingFilterProxy - (just like in the example above), but the target class is org.springframework.security.web.FilterChainProxy. - The filter chain is then declared in the application context. Here's an example: - - - - - - -]]> - - The namespace element filter-chain-map is used to set up the security filter chain(s) which are required - within the application. It maps a particular URL pattern to a chain of filters built up from the bean names - specified in the filters element. Both regular - expressions and Ant Paths are supported, and the most specific URIs - appear first. At runtime the FilterChainProxy will - locate the first URI pattern that matches the current web request and the list - of filter beans specified by the filters attribute - will be applied to that request. The filters will be invoked in the order - they are defined, so you have complete control over the filter chain - which is applied to a particular URL. - - You may have noticed we have declared two - SecurityContextPersistenceFilters in the filter - chain (ASC is short for - allowSessionCreation, a property of - SecurityContextPersistenceFilter). As web - services will never present a jsessionid on future - requests, creating HttpSessions for such user - agents would be wasteful. If you had a high-volume application which - required maximum scalability, we recommend you use the approach shown - above. For smaller applications, using a single - SecurityContextPersistenceFilter (with its - default allowSessionCreation as - true) would likely be sufficient. - - In relation to lifecycle issues, the - FilterChainProxy will always delegate - init(FilterConfig) and destroy() - methods through to the underlaying Filters if such - methods are called against FilterChainProxy itself. - In this case, FilterChainProxy guarantees to only - initialize and destroy each Filter bean once, - no matter how many times it is declared in the filter chain(s). You control the - overall choice as to whether these methods are called or not via the - targetFilterLifecycle initialization parameter of - DelegatingFilterProxy. By default this property - is false and servlet container lifecycle invocations are not delegated through - DelegatingFilterProxy. - - When we looked at how to set up web security using namespace configuration, - we used a DelegatingFilterProxy with the name springSecurityFilterChain. You should now be able to - see that this is the name of the FilterChainProxy which is created by the namespace. - -
- Bypassing the Filter Chain - - As with the namespace, you can use the attribute filters = "none" as an alternative to supplying a filter bean list. - This will omit the request pattern from the security filter chain entirely. Note that anything matching this path will then have - no authentication or authorization services applied and will be freely accessible. - -
-
- -
- Filter Ordering - The order that filters are defined in the chain - is very important. Irrespective of which filters you are actually - using, the order should be as follows: - - - - ChannelProcessingFilter, because it might - need to redirect to a different protocol - - - - ConcurrentSessionFilter, because it - doesn't use any SecurityContextHolder - functionality but needs to update the - SessionRegistry to reflect ongoing requests - from the principal - - - - SecurityContextPersistenceFilter, so a - SecurityContext can be setup in the - SecurityContextHolder at the beginning of a web - request, and any changes to the SecurityContext - can be copied to the HttpSession when the web - request ends (ready for use with the next web request) - - - - Authentication processing mechanisms - - UsernamePasswordAuthenticationProcessingFilter, - CasProcessingFilter, - BasicProcessingFilter etc - so that the - SecurityContextHolder can be modified to - contain a valid Authentication request - token - - - - The - SecurityContextHolderAwareRequestFilter, if you - are using it to install a Spring Security aware - HttpServletRequestWrapper into your servlet - container - - - - RememberMeProcessingFilter, so that if no - earlier authentication processing mechanism updated the - SecurityContextHolder, and the request presents - a cookie that enables remember-me services to take place, a - suitable remembered - Authentication object will - be put there - - - - AnonymousProcessingFilter, so that if no - earlier authentication processing mechanism updated the - SecurityContextHolder, an anonymous - Authentication object will be put there - - - - ExceptionTranslationFilter, to catch any - Spring Security exceptions so that either an HTTP error response - can be returned or an appropriate - AuthenticationEntryPoint can be launched - - - - FilterSecurityInterceptor, to protect web - URIs - - - -
- -
- Use with other Filter-Based Frameworks - If you're using SiteMesh, ensure Spring Security filters execute - before the SiteMesh filters are called. This enables the - SecurityContextHolder to be populated in time for - use by SiteMesh decorators. - -
- - -
-
- Tag Libraries - - Spring Security comes bundled with several JSP tag libraries which provide a range of different - services. - -
- Configuration - All taglib classes are included in the core - spring-security-xx.jar file, with the - security.tld located in the JAR's - META-INF directory. This means for JSP 1.2+ web - containers you can simply include the JAR in the WAR's - WEB-INF/lib directory and it will be available. If - you're using a JSP 1.1 container, you'll need to declare the JSP - taglib in your web.xml file, and include - security.tld in the WEB-INF/lib - directory. The following fragment is added to - web.xml: - - http://www.springframework.org/security/tags - /WEB-INF/security.tld - -]]> -
- -
- Usage - Now that you've configured the tag libraries, refer to the - individual reference guide sections for details on how to use them. - Note that when using the tags, you should include the taglib reference - in your JSP: - - <%@ taglib prefix='security' uri='http://www.springframework.org/security/tags' %> - -
-
-
\ No newline at end of file diff --git a/docs/manual/src/docbook/taglibs.xml b/docs/manual/src/docbook/taglibs.xml deleted file mode 100644 index 26040a7aa5..0000000000 --- a/docs/manual/src/docbook/taglibs.xml +++ /dev/null @@ -1,44 +0,0 @@ - - Tag Libraries - - -
- Overview - Spring Security comes bundled with several JSP tag libraries - that eases JSP writing. The tag libraries provide a range of different - services. -
- -
- Configuration - All taglib classes are included in the core - spring-security-xx.jar file, with the - security.tld located in the JAR's - META-INF directory. This means for JSP 1.2+ web - containers you can simply include the JAR in the WAR's - WEB-INF/lib directory and it will be available. If - you're using a JSP 1.1 container, you'll need to declare the JSP - taglib in your web.xml file, and include - security.tld in the WEB-INF/lib - directory. The following fragment is added to - web.xml: - - -<taglib> - <taglib-uri>http://www.springframework.org/security/tags</taglib-uri> - <taglib-location>/WEB-INF/security.tld</taglib-location> -</taglib> - -
- -
- Usage - Now that you've configured the tag libraries, refer to the - individual reference guide sections for details on how to use them. - Note that when using the tags, you should include the taglib reference - in your JSP: - <%@ taglib prefix='security' uri='http://www.springframework.org/security/tags' %> - - -
-
\ No newline at end of file diff --git a/docs/manual/src/docbook/technical-overview.xml b/docs/manual/src/docbook/technical-overview.xml index d98baa72fb..5e7c4a8224 100644 --- a/docs/manual/src/docbook/technical-overview.xml +++ b/docs/manual/src/docbook/technical-overview.xml @@ -1,4 +1,5 @@ - + Technical Overview @@ -98,18 +99,25 @@ if (principal instanceof UserDetails) { answer is that there is a special interface called UserDetailsService. The only method on this interface accepts a String-based username argument and returns a - UserDetails. Most authentication providers that ship with - Spring Security delegate to a UserDetailsService as part of - the authentication process. The UserDetailsService is used to + UserDetails: + + UserDetails loadUserByUsername(String username) throws UsernameNotFoundException; + + This is the most common approach to loading information for a user within Spring Security + and you will see it used throughout the framework whenever information on a user is + required.
+ On successful authentication, UserDetails is used to build the Authentication object that is stored in the - SecurityContextHolder. The good news is that we provide a number of - UserDetailsService implementations, including one that uses - an in-memory map and another that uses JDBC. Most users tend to write their own, though, - with their implementations often simply sitting on top of an existing Data Access Object - (DAO) that represents their employees, customers, or other users of the enterprise - application. Remember the advantage that whatever your UserDetailsService returns can always - be obtained from the SecurityContextHolder, as per the above code - fragment. + SecurityContextHolder (more on this in below). The good news is that we provide a + number of UserDetailsService implementations, including one + that uses an in-memory map (InMemoryDaoImpl) and another that uses + JDBC (JdbcDaoImpl). Most users tend to write their own, + though, with their implementations often simply sitting on top of an existing Data Access + Object (DAO) that represents their employees, customers, or other users of the application. + Remember the advantage that whatever your UserDetailsService + returns can always be obtained from the SecurityContextHolder using + the above code fragment.
GrantedAuthority @@ -222,8 +230,8 @@ if (principal instanceof UserDetails) { the returned authentication object. From that point on, the user is considered to be authenticated. Let's look at - some code as an - example.import org.springframework.security.authentication.*; + some code as an example. + import org.springframework.security.authentication.*; import org.springframework.security.core.*; import org.springframework.security.core.authority.GrantedAuthorityImpl; import org.springframework.security.core.context.SecurityContextHolder; @@ -268,8 +276,8 @@ class SampleAuthenticationManager implements AuthenticationManager { throw new BadCredentialsException("Bad Credentials"); } }Here - we have written a little program that asks the user to enter a username and password - and performs the above sequence. The AuthenticationManager which + we have written a little program that asks the user to enter a username and password and + performs the above sequence. The AuthenticationManager which we've implemented here will authenticate any user whose username and password are the same. It assigns a single role to every user. The output from the above will be something like: @@ -290,8 +298,8 @@ Successfully authenticated. Security context contains: \ Note that you don't normally need to write any code like this. The process will normally occur internally, in a web authentication filter for example. We've just included the code - here to show that the question of what actually constitutes authentication in Spring Security - has quite a simple answer. A user is authenticated when the + here to show that the question of what actually constitutes authentication in Spring + Security has quite a simple answer. A user is authenticated when the SecurityContextHolder contains a fully populated Authentiation object.
@@ -314,138 +322,141 @@ Successfully authenticated. Security context contains: \ Spring Security-specific Authentication object, and put it onto the SecurityContextHolder.
-
- The <interfacename>AuthenticationManager</interfacename> - 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? The default implementation in Spring - Security is called ProviderManager and rather than handling the - authentication request itself, it delegates to a list of configured - AuthenticationProviders, 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 - section and refresh your memory. Most AuthenticationProviders will - ask a UserDetailsService to provide a - UserDetails object. The resulting - UserDetails object - and particularly the - GrantedAuthoritys it contains - will be used when building the fully - populated Authentication object. -
+
+
+ The <interfacename>AuthenticationManager</interfacename> + 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? The default implementation in Spring Security is + called ProviderManager and rather than handling the authentication + request itself, it delegates to a list of configured + AuthenticationProviders, 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 + section 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, which is most commonly used to + wrap a UserDetailsService to implement an + AuthenticationProvider. The loaded + UserDetails object - and particularly the + GrantedAuthoritys it contains - will be used when building the fully + populated Authentication object which is returned from a + successful authentication and stored in the SecurityContext. +
+ +
+ Authentication in a Web Application + Now let's explore the situation where you are using Spring Security in a web application + (without web.xml security enabled). How is a user authenticated and the + security context established? + Consider a typical web application's authentication process: + + + You visit the home page, and click on a link. + + + A request goes to the server, and the server decides that you've asked for a protected + resource. + + + As you're not presently authenticated, the server sends back a response indicating + that you must authenticate. The response will either be an HTTP response code, or a + redirect to a particular web page. + + + Depending on the authentication mechanism, your browser will either redirect to the + specific web page so that you can fill out the form, or the browser will somehow retrieve + your identity (via a BASIC authentication dialogue box, a cookie, a X.509 certificate + etc.). + + + The browser will send back a response to the server. This will either be an HTTP POST + containing the contents of the form that you filled out, or an HTTP header containing your + authentication details. + + + Next the server will decide whether or not the presented credentials are valid. If + they're valid, the next step will happen. If they're invalid, usually your browser will be + asked to try again (so you return to step two above). + + + The original request that you made to cause the authentication process will be + retried. Hopefully you've authenticated with sufficient granted authorities to access the + protected resource. If you have sufficient access, the request will be successful. + Otherwise, you'll receive back an HTTP error code 403, which means "forbidden". + + + Spring Security has distinct classes responsible for most of the steps described above. + The main participants (in the order that they are used) are the + ExceptionTranslationFilter, an + AuthenticationEntryPoint and an authentication + mechanism, which is resposible for calling the + AuthenticationManager which we saw in the previous section. +
+ ExceptionTranslationFilter + ExceptionTranslationFilter is a Spring Security filter that has + responsibility for detecting any Spring Security exceptions that are thrown. Such exceptions + will generally be thrown by an AbstractSecurityInterceptor, which is + the main provider of authorization services. We will discuss + AbstractSecurityInterceptor in the next section, but for now we + just need to know that it produces Java exceptions and knows nothing about HTTP or how to go + about authenticating a principal. Instead the + ExceptionTranslationFilter offers this service, with specific + responsibility for either returning error code 403 (if the principal has been authenticated + and therefore simply lacks sufficient access - as per step seven above), or launching an + AuthenticationEntryPoint (if the principal has not been + authenticated and therefore we need to go commence step three). +
+
+ AuthenticationEntryPoint + The AuthenticationEntryPoint is responsible for step + three in the above list. As you can imagine, each web application will have a default + authentication strategy (well, this can be configured like nearly everything else in Spring + Security, but let's keep it simple for now). Each major authentication system will have its + own AuthenticationEntryPoint implementation, which typically + performs one of the actions described in step 3.
- Authentication in a Web Application - Now let's explore the situation where you are using Spring Security in a web - application (without web.xml security enabled). How is a user - authenticated and the security context established? - Consider a typical web application's authentication process: - - - You visit the home page, and click on a link. - - - A request goes to the server, and the server decides that you've asked for a - protected resource. - - - As you're not presently authenticated, the server sends back a response indicating - that you must authenticate. The response will either be an HTTP response code, or a - redirect to a particular web page. - - - Depending on the authentication mechanism, your browser will either redirect to the - specific web page so that you can fill out the form, or the browser will somehow - retrieve your identity (via a BASIC authentication dialogue box, a cookie, a X.509 - certificate etc.). - - - The browser will send back a response to the server. This will either be an HTTP - POST containing the contents of the form that you filled out, or an HTTP header - containing your authentication details. - - - Next the server will decide whether or not the presented credentials are valid. If - they're valid, the next step will happen. If they're invalid, usually your browser will - be asked to try again (so you return to step two above). - - - The original request that you made to cause the authentication process will be - retried. Hopefully you've authenticated with sufficient granted authorities to access - the protected resource. If you have sufficient access, the request will be successful. - Otherwise, you'll receive back an HTTP error code 403, which means "forbidden". - - - Spring Security has distinct classes responsible for most of the steps described above. - The main participants (in the order that they are used) are the - ExceptionTranslationFilter, an - AuthenticationEntryPoint and an authentication - mechanism, which is resposible for calling the - AuthenticationManager which we saw in the previous section. -
- ExceptionTranslationFilter - ExceptionTranslationFilter is a Spring Security filter that has - responsibility for detecting any Spring Security exceptions that are thrown. Such - exceptions will generally be thrown by an - AbstractSecurityInterceptor, which is the main provider of - authorization services. We will discuss AbstractSecurityInterceptor - in the next section, but for now we just need to know that it produces Java exceptions and - knows nothing about HTTP or how to go about authenticating a principal. Instead the - ExceptionTranslationFilter offers this service, with specific - responsibility for either returning error code 403 (if the principal has been - authenticated and therefore simply lacks sufficient access - as per step seven above), or - launching an AuthenticationEntryPoint (if the principal has - not been authenticated and therefore we need to go commence step three). -
-
- AuthenticationEntryPoint - The AuthenticationEntryPoint is responsible for step - three in the above list. As you can imagine, each web application will have a default - authentication strategy (well, this can be configured like nearly everything else in - Spring Security, but let's keep it simple for now). Each major authentication system will - have its own AuthenticationEntryPoint implementation, which - typically performs one of the actions described in step 3. -
-
- Authentication Mechanism - Once your browser submits your authentication credentials (either as an HTTP form post - or HTTP header) there needs to be something on the server that collects - these authentication details. By now we're at step six in the above list. In Spring - Security we have a special name for the function of collecting authentication details from - a user agent (usually a web browser), referring to it as the authentication - mechanism. Examples are form-base login and Basic authentication. Once the - authentication details have been collected from the user agent, an - Authentication - request object is built and then presented to the - AuthenticationManager. - After the authentication mechanism receives back the fully-populated - Authentication object, it will deem the request valid, - put the Authentication into the - SecurityContextHolder, and cause the original request to be - retried (step seven above). If, on the other hand, the - AuthenticationManager rejected the request, the authentication - mechanism will ask the user agent to retry (step two above). -
-
- Storing the <interfacename>SecurityContext</interfacename> between requests - Depending on the type of application, there may need to be a strategy in place to - store the security context between user operations. In a typical web application, a user - logs in once and is subsequently identified by their session Id. The server caches the - principal information for the duration session. In Spring Security, the responsibility for - storing the SecurityContext between requests falls to the - SecurityContextPersistenceFilter, which by default stores the - context as an HttpSession attribute between HTTP requests. It restores - the context to the SecurityContextHolder for each request and, - crucially, clears the SecurityContextHolder when the request - completes. You shouldn't interact directly with the HttpSession for - security purposes. There is simply no justification for doing so - always use the - SecurityContextHolder instead. - Many other types of application (for example, a stateless RESTful web service) do not - use HTTP sessions and will re-authenticate on every request. However, it is still - important that the SecurityContextPersistenceFilter is included in - the chain to make sure that the SecurityContextHolder is cleared - after each request. -
+ Authentication Mechanism + Once your browser submits your authentication credentials (either as an HTTP form post + or HTTP header) there needs to be something on the server that collects these + authentication details. By now we're at step six in the above list. In Spring Security we + have a special name for the function of collecting authentication details from a user agent + (usually a web browser), referring to it as the authentication mechanism. + Examples are form-base login and Basic authentication. Once the authentication details have + been collected from the user agent, an Authentication + request object is built and then presented to the + AuthenticationManager. + After the authentication mechanism receives back the fully-populated + Authentication object, it will deem the request valid, put + the Authentication into the + SecurityContextHolder, and cause the original request to be retried + (step seven above). If, on the other hand, the AuthenticationManager + rejected the request, the authentication mechanism will ask the user agent to retry (step + two above). +
+
+ Storing the <interfacename>SecurityContext</interfacename> between requests + Depending on the type of application, there may need to be a strategy in place to store + the security context between user operations. In a typical web application, a user logs in + once and is subsequently identified by their session Id. The server caches the principal + information for the duration session. In Spring Security, the responsibility for storing the + SecurityContext between requests falls to the + SecurityContextPersistenceFilter, which by default stores the + context as an HttpSession attribute between HTTP requests. It restores + the context to the SecurityContextHolder for each request and, + crucially, clears the SecurityContextHolder when the request + completes. You shouldn't interact directly with the HttpSession for + security purposes. There is simply no justification for doing so - always use the + SecurityContextHolder instead. + Many other types of application (for example, a stateless RESTful web service) do not + use HTTP sessions and will re-authenticate on every request. However, it is still important + that the SecurityContextPersistenceFilter is included in the chain to + make sure that the SecurityContextHolder is cleared after each + request.
@@ -470,9 +481,9 @@ Successfully authenticated. Security context contains: \ help you protect method invocations as well as web requests. Most people are interested in securing method invocations on their services layer. This is because the services layer is where most business logic resides in current-generation J2EE applications. If you just need - to secure method invocations in the services layer, Spring's standard AOP (otherwise known - as AOP Alliance) will be adequate. If you need to secure domain objects directly, you will - likely find that AspectJ is worth considering. + to secure method invocations in the services layer, Spring's standard AOP will be adequate. + If you need to secure domain objects directly, you will likely find that AspectJ is worth + considering. You can elect to perform method authorization using AspectJ or Spring AOP, or you can elect to perform web request authorization using filters. You can use zero, one, two or three of these approaches together. The mainstream usage pattern is to perform some web @@ -515,11 +526,12 @@ Successfully authenticated. Security context contains: \ the invocation has returned. -
+
What are Configuration Attributes? A configuration attribute can be thought of as a String that has special meaning to the classes used by AbstractSecurityInterceptor. - They may be simple role names or have more complex meaning, depending on the how + They are represented by the interface ConfigAttribute within + the framework. They may be simple role names or have more complex meaning, depending on the how sophisticated the AccessDecisionManager implementation is. The AbstractSecurityInterceptor is configured with a SecurityMetadataSource which it uses to look up the @@ -550,11 +562,11 @@ Successfully authenticated. Security context contains: \ AbstractSecurityInterceptor gets one final chance to handle the invocation. At this stage the AbstractSecurityInterceptor is interested in possibly modifying the return object. We might want this to happen because - an authorization decision couldn't be made on the way in to a secure object invocation. - Being highly pluggable, AbstractSecurityInterceptor will pass - control to an AfterInvocationManager to actually modify the object if - needed. This class can even entirely replace the object, or throw an exception, or not - change it in any way as it chooses. + an authorization decision couldn't be made on the way in to a secure object + invocation. Being highly pluggable, AbstractSecurityInterceptor + will pass control to an AfterInvocationManager to actually modify the + object if needed. This class can even entirely replace the object, or throw an exception, + or not change it in any way as it chooses. AbstractSecurityInterceptor and its related objects are shown in .
@@ -582,65 +594,48 @@ Successfully authenticated. Security context contains: \
Localization - Spring Security supports localization of exception messages that - end users are likely to see. If your application is designed for - English-speaking users, you don't need to do anything as by default all - Security Security messages are in English. If you need to support - other locales, everything you need to know is contained in this - section. - - All exception messages can be localized, including messages - related to authentication failures and access being denied - (authorization failures). Exceptions and logging that is focused on - developers or system deployers (including incorrect attributes, - interface contract violations, using incorrect constructors, startup - time validation, debug-level logging) etc are not localized and - instead are hard-coded in English within Spring Security's - code. - - Shipping in the spring-security-core-xx.jar you - will find an org.springframework.security package - that in turn contains a messages.properties file. - This should be referred to by your - ApplicationContext, as Spring Security classes - implement Spring's MessageSourceAware interface and - expect the message resolver to be dependency injected at application - context startup time. Usually all you need to do is register a bean - inside your application context to refer to the messages. An example - is shown below: - - Spring Security supports localization of exception messages that end users are likely to + see. If your application is designed for English-speaking users, you don't need to do anything + as by default all Security Security messages are in English. If you need to support other + locales, everything you need to know is contained in this section. + All exception messages can be localized, including messages related to authentication + failures and access being denied (authorization failures). Exceptions and logging that is + focused on developers or system deployers (including incorrect attributes, interface contract + violations, using incorrect constructors, startup time validation, debug-level logging) etc + are not localized and instead are hard-coded in English within Spring Security's code. + Shipping in the spring-security-core-xx.jar you will find an + org.springframework.security package that in turn contains a + messages.properties file. This should be referred to by your + ApplicationContext, as Spring Security classes implement Spring's + MessageSourceAware interface and expect the message resolver to be + dependency injected at application context startup time. Usually all you need to do is + register a bean inside your application context to refer to the messages. An example is shown + below: + + -]]> - - The messages.properties is named in - accordance with standard resource bundles and represents the default - language supported by Spring Security messages. This default file is - in English. If you do not register a message source, Spring Security - will still work correctly and fallback to hard-coded English versions - of the messages. - - If you wish to customize the - messages.properties file, or support other - languages, you should copy the file, rename it accordingly, and - register it inside the above bean definition. There are not a large - number of message keys inside this file, so localization should not be - considered a major initiative. If you do perform localization of this - file, please consider sharing your work with the community by logging - a JIRA task and attaching your appropriately-named localized version - of messages.properties. - - Rounding out the discussion on localization is the Spring - ThreadLocal known as - org.springframework.context.i18n.LocaleContextHolder. - You should set the LocaleContextHolder to represent - the preferred Locale of each user. Spring Security - will attempt to locate a message from the message source using the - Locale obtained from this - ThreadLocal. Please refer to the Spring Framework documentation - for further details on using LocaleContextHolder. -
+]]> + + The messages.properties is named in accordance with standard resource + bundles and represents the default language supported by Spring Security messages. This + default file is in English. If you do not register a message source, Spring Security will + still work correctly and fallback to hard-coded English versions of the messages. + If you wish to customize the messages.properties file, or support other + languages, you should copy the file, rename it accordingly, and register it inside the above + bean definition. There are not a large number of message keys inside this file, so + localization should not be considered a major initiative. If you do perform localization of + this file, please consider sharing your work with the community by logging a JIRA task and + attaching your appropriately-named localized version of + messages.properties. + Rounding out the discussion on localization is the Spring ThreadLocal + known as org.springframework.context.i18n.LocaleContextHolder. You + should set the LocaleContextHolder to represent the preferred + Locale of each user. Spring Security will attempt to locate a message + from the message source using the Locale obtained from this + ThreadLocal. Please refer to the Spring Framework documentation for + further details on using LocaleContextHolder. +
diff --git a/docs/manual/src/docbook/web-infrastructure.xml b/docs/manual/src/docbook/web-infrastructure.xml new file mode 100644 index 0000000000..001230582e --- /dev/null +++ b/docs/manual/src/docbook/web-infrastructure.xml @@ -0,0 +1,236 @@ + + + Web Application Infrastructure + + Most Spring Security users will be using the framework in applications which make user of + the HTTP and the Servlet API. In this and the following chapters, we'll take a look at how + Spring Security provides authentication and access-control features for the web layer of an + application. We'll look behind the facade of the namespace and see which classes and interfaces + are actually assembled to provide web-layer security. In some situations it is necessary to use + traditional bean configuration to provide full control over the configuration, so we'll also see + how to configure these classes directly without the namespace. +
+ Security Filter + Spring Security's web infrastructure is based entirely on standard servlet filters. It + doesn't use servlets or any other servlet-based frameworks (such as Spring MVC) internally, so + it has no strong links to any particular web technology. It deals in + HttpServletRequests and HttpServletResponses + and doesn't care whether the requests come from a browser, a web service client, an + HttpInvoker or an AJAX application. + Spring Security maintains a filter chain internally where each of the filters has a + particular responsibility and filters are added or removed from the configuration depending on + which services are required. The ordering of the filters is important as there are + dependencies between them. If you have been using namespace + configuration, then the filters are automatically configured for you and you don't + have to define any Spring beans explicitly but here may be times when you want full control + over the security filter chain, either because you are using features which aren't supported + in the namespace, or you are using your own customized versions of classes. +
+ <classname>DelegatingFilterProxy</classname> + When using servlet filters, you obviously need to declare them in your + web.xml, or they will be ignored by the servlet container. In Spring + Security, the filter classes are also Spring beans defined in the application context and + thus able to take advantage of Spring's rich dependency-injection facilities and lifecycle + interfaces. Spring's DelegatingFilterProxy provides the link between + web.xml and the application context. + When using DelegatingFilterProxy, you will see something like + this in the web.xml file: + myFilter + org.springframework.web.filter.DelegatingFilterProxy + + + + myFilter + /* + ]]> + Notice that the filter is actually a + DelegatingFilterProxy, and not the class that will actually implement + the logic of the filter. What DelegatingFilterProxy does is delegate + the Filter's methods through to a bean which is obtained from + the Spring application context. This enables the bean to benefit from the Spring web + application context lifecycle support and configuration flexibility. The bean must implement + javax.servlet.Filter and it must have the same name as that + in the filter-name element. Read the Javadoc for + DelegatingFilterProxy for more information +
+
+ <classname>FilterChainProxy</classname> + It should now be clear that you can declare each Spring Security filter bean that you + require in your application context file and add a corresponding + DelegatingFilterProxy entry to web.xml for + each filter, making sure that they are ordered correctly. This is a cumbersome approach and + clutters up the web.xml file quickly if we have a lot of filters. We + would prefer to just add a single entry to web.xml and deal entirely + with the application context file for managing our web security beans. This is where Spring + Secuiryt's FilterChainProxy comes in. It is wired using a + DelegatingFilterProxy, just like in the example above, but with the + filter-name set to the bean name filterChainProxy. The + filter chain is then declared in the application context with the same bean name. Here's an + example: + + + + + +]]> + The namespace element filter-chain-map is + used to set up the security filter chain(s) which are required within the application + Note that you'll need to include the security namespace in your application context + XML file in order to use this syntax. + . It maps a particular URL pattern to a chain of filters built up from the bean + names specified in the filters element. Both regular expressions and Ant + Paths are supported, and the most specific URIs appear first. At runtime the + FilterChainProxy will locate the first URI pattern that matches the + current web request and the list of filter beans specified by the filters + attribute will be applied to that request. The filters will be invoked in the order they are + defined, so you have complete control over the filter chain which is applied to a particular + URL. + You may have noticed we have declared two + SecurityContextPersistenceFilters in the filter chain + (ASC is short for allowSessionCreation, a property + of SecurityContextPersistenceFilter). As web services will never + present a jsessionid on future requests, creating + HttpSessions for such user agents would be wasteful. If you had a + high-volume application which required maximum scalability, we recommend you use the + approach shown above. For smaller applications, using a single + SecurityContextPersistenceFilter (with its default + allowSessionCreation as true) would likely be + sufficient. + In relation to lifecycle issues, the FilterChainProxy will always + delegate init(FilterConfig) and destroy() + methods through to the underlaying Filters if such methods + are called against FilterChainProxy itself. In this case, + FilterChainProxy guarantees to only initialize and destroy each + Filter bean once, no matter how many times it is declared in the filter + chain(s). You control the overall choice as to whether these methods are called or not via + the targetFilterLifecycle initialization parameter of + DelegatingFilterProxy. By default this property is + false and servlet container lifecycle invocations are not delegated + through DelegatingFilterProxy. + When we looked at how to set up web security using namespace configuration, we used a + DelegatingFilterProxy with the name + springSecurityFilterChain. You should now be able to see that this is the + name of the FilterChainProxy which is created by the namespace. +
+ Bypassing the Filter Chain + As with the namespace, you can use the attribute filters = "none" + as an alternative to supplying a filter bean list. This will omit the request pattern from + the security filter chain entirely. Note that anything matching this path will then have + no authentication or authorization services applied and will be freely accessible. If you + want to make use of the contents of the SecurityContext contents + during a request, then it must have passed through the security filter chain. Otherwise + the SecurityContextHolder will not have been populated and the + contents will be null. +
+
+
+ Filter Ordering + The order that filters are defined in the chain is very important. Irrespective of which + filters you are actually using, the order should be as follows: + + ChannelProcessingFilter, because it might need to redirect + to a different protocol + + + ConcurrentSessionFilter, because it doesn't use any + SecurityContextHolder functionality but needs to update the + SessionRegistry to reflect ongoing requests from the + principal + + + SecurityContextPersistenceFilter, so a + SecurityContext can be set up in the + SecurityContextHolder at the beginning of a web request, and + any changes to the SecurityContext can be copied to the + HttpSession when the web request ends (ready for use with the + next web request) + + + Authentication processing mechanisms - + UsernamePasswordAuthenticationProcessingFilter, + CasProcessingFilter, + BasicProcessingFilter etc - so that the + SecurityContextHolder can be modified to contain a valid + Authentication request token + + + The SecurityContextHolderAwareRequestFilter, if you are using + it to install a Spring Security aware HttpServletRequestWrapper + into your servlet container + + + RememberMeProcessingFilter, so that if no earlier + authentication processing mechanism updated the + SecurityContextHolder, and the request presents a cookie that + enables remember-me services to take place, a suitable remembered + Authentication object will be put there + + + AnonymousProcessingFilter, so that if no earlier + authentication processing mechanism updated the + SecurityContextHolder, an anonymous + Authentication object will be put there + + + ExceptionTranslationFilter, to catch any Spring Security + exceptions so that either an HTTP error response can be returned or an appropriate + AuthenticationEntryPoint can be launched + + + FilterSecurityInterceptor, to protect web URIs and raise + exceptions when access is denied + + +
+
+ Use with other Filter-Based Frameworks + If you're using some other framework that is also filter-based, then you need to make + sure that the Spring Security filters come first. This enables the + SecurityContextHolder to be populated in time for use by the other + filters. Examples are the use of SiteMesh to decorate your web pages or a web framework like + Wicket which uses a filter to handle its requests. +
+
+ +