diff --git a/docs/manual/src/docs/asciidoc/_includes/preface.adoc b/docs/manual/src/docs/asciidoc/_includes/preface.adoc deleted file mode 100644 index 9c409fc8de..0000000000 --- a/docs/manual/src/docs/asciidoc/_includes/preface.adoc +++ /dev/null @@ -1,3150 +0,0 @@ -[[preface]] -= Preface -Spring Security provides a comprehensive security solution for Java EE-based enterprise software applications. -As you will discover as you venture through this reference guide, we have tried to provide you a useful and highly configurable security system. - -Security is an ever-moving target, and it's important to pursue a comprehensive, system-wide approach. -In security circles we encourage you to adopt "layers of security", so that each layer tries to be as secure as possible in its own right, with successive layers providing additional security. -The "tighter" the security of each layer, the more robust and safe your application will be. -At the bottom level you'll need to deal with issues such as transport security and system identification, in order to mitigate man-in-the-middle attacks. -Next you'll generally utilise firewalls, perhaps with VPNs or IP security to ensure only authorised systems can attempt to connect. -In corporate environments you may deploy a DMZ to separate public-facing servers from backend database and application servers. -Your operating system will also play a critical part, addressing issues such as running processes as non-privileged users and maximising file system security. -An operating system will usually also be configured with its own firewall. -Hopefully somewhere along the way you'll be trying to prevent denial of service and brute force attacks against the system. -An intrusion detection system will also be especially useful for monitoring and responding to attacks, with such systems able to take protective action such as blocking offending TCP/IP addresses in real-time. -Moving to the higher layers, your Java Virtual Machine will hopefully be configured to minimize the permissions granted to different Java types, and then your application will add its own problem domain-specific security configuration. -Spring Security makes this latter area - application security - much easier. - -Of course, you will need to properly address all security layers mentioned above, together with managerial factors that encompass every layer. -A non-exhaustive list of such managerial factors would include security bulletin monitoring, patching, personnel vetting, audits, change control, engineering management systems, data backup, disaster recovery, performance benchmarking, load monitoring, centralised logging, incident response procedures etc. - -With Spring Security being focused on helping you with the enterprise application security layer, you will find that there are as many different requirements as there are business problem domains. -A banking application has different needs from an ecommerce application. -An ecommerce application has different needs from a corporate sales force automation tool. -These custom requirements make application security interesting, challenging and rewarding. - -Please read <>, in its entirety to begin with. -This will introduce you to the framework and the namespace-based configuration system with which you can get up and running quite quickly. -To get more of an understanding of how Spring Security works, and some of the classes you might need to use, you should then read <>. -The remaining parts of this guide are structured in a more traditional reference style, designed to be read on an as-required basis. -We'd also recommend that you read up as much as possible on application security issues in general. -Spring Security is not a panacea which will solve all security issues. -It is important that the application is designed with security in mind from the start. -Attempting to retrofit it is not a good idea. -In particular, if you are building a web application, you should be aware of the many potential vulnerabilities such as cross-site scripting, request-forgery and session-hijacking which you should be taking into account from the start. -The OWASP web site (http://www. -owasp. -org/) maintains a top ten list of web application vulnerabilities as well as a lot of useful reference information. - -We hope that you find this reference guide useful, and we welcome your feedback and <>. - -Finally, welcome to the Spring Security <>. - - -[[getting-started]] -== Getting Started -The later parts of this guide provide an in-depth discussion of the framework architecture and implementation classes, which you need to understand if you want to do any serious customization. -In this part, we'll introduce Spring Security 4. -0, give a brief overview of the project's history and take a slightly gentler look at how to get started using the framework. -In particular, we'll look at namespace configuration which provides a much simpler way of securing your application compared to the traditional Spring bean approach where you have to wire up all the implementation classes individually. - -We'll also take a look at the sample applications that are available. -It's worth trying to run these and experimenting with them a bit even before you read the later sections - you can dip back into them as your understanding of the framework increases. -Please also check out the http://spring. -io/spring-security[project website] as it has useful information on building the project, plus links to articles, videos and tutorials. - - -[[introduction]] -== Introduction - - -[[what-is-acegi-security]] -=== What is Spring Security? -Spring Security provides comprehensive security services for Java EE-based enterprise software applications. -There is a particular emphasis on supporting projects built using The Spring Framework, which is the leading Java EE solution for enterprise software development. -If you're not using Spring for developing enterprise applications, we warmly encourage you to take a closer look at it. -Some familiarity with Spring - and in particular dependency injection principles - will help you get up to speed with Spring Security more easily. - -People use Spring Security for many reasons, but most are drawn to the project after finding the security features of Java EE's Servlet Specification or EJB Specification lack the depth required for typical enterprise application scenarios. -Whilst mentioning these standards, it's important to recognise that they are not portable at a WAR or EAR level. -Therefore, if you switch server environments, it is typically a lot of work to reconfigure your application's security in the new target environment. -Using Spring Security overcomes these problems, and also brings you dozens of other useful, customisable security features. - -As you probably know two major areas of application security are "authentication" and "authorization" (or "access-control"). -These are the two main areas that Spring Security targets. -"Authentication" is the process of establishing a principal is who they claim to be (a "principal" generally means a user, device or some other system which can perform an action in your application). -"Authorization" refers to the process of deciding whether a principal is allowed to perform an action within your application. -To arrive at the point where an authorization decision is needed, the identity of the principal has already been established by the authentication process. -These concepts are common, and not at all specific to Spring Security. - -At an authentication level, Spring Security supports a wide range of authentication models. -Most of these authentication models are either provided by third parties, or are developed by relevant standards bodies such as the Internet Engineering Task Force. -In addition, Spring Security provides its own set of authentication features. -Specifically, Spring Security currently supports authentication integration with all of these technologies: - - -* HTTP BASIC authentication headers (an IETF RFC-based standard) - -* HTTP Digest authentication headers (an IETF RFC-based standard) - -* HTTP X.509 client certificate exchange (an IETF RFC-based standard) - -* LDAP (a very common approach to cross-platform authentication needs, especially in large environments) - -* Form-based authentication (for simple user interface needs) - -* OpenID authentication - -* Authentication based on pre-established request headers (such as Computer Associates Siteminder) - -* Jasig Central Authentication Service (otherwise known as CAS, which is a popular open source single sign-on system) - -* Transparent authentication context propagation for Remote Method Invocation (RMI) and HttpInvoker (a Spring remoting protocol) - -* Automatic "remember-me" authentication (so you can tick a box to avoid re-authentication for a predetermined period of time) - -* Anonymous authentication (allowing every unauthenticated call to automatically assume a particular security identity) - -* Run-as authentication (which is useful if one call should proceed with a different security identity) - -* Java Authentication and Authorization Service (JAAS) - -* Java EE container authentication (so you can still use Container Managed Authentication if desired) - -* Kerberos - -* Java Open Source Single Sign-On (JOSSO) * - -* OpenNMS Network Management Platform * - -* AppFuse * - -* AndroMDA * - -* Mule ESB * - -* Direct Web Request (DWR) * - -* Grails * - -* Tapestry * - -* JTrac * - -* Jasypt * - -* Roller * - -* Elastic Path * - -* Atlassian Crowd * - -* Your own authentication systems (see below) - - - -(* Denotes provided by a third party) - -Many independent software vendors (ISVs) adopt Spring Security because of this significant choice of flexible authentication models. -Doing so allows them to quickly integrate their solutions with whatever their end clients need, without undertaking a lot of engineering or requiring the client to change their environment. -If none of the above authentication mechanisms suit your needs, Spring Security is an open platform and it is quite simple to write your own authentication mechanism. -Many corporate users of Spring Security need to integrate with "legacy" systems that don't follow any particular security standards, and Spring Security is happy to "play nicely" with such systems. - -Irrespective of the authentication mechanism, Spring Security provides a deep set of authorization capabilities. -There are three main areas of interest: authorizing web requests, authorizing whether methods can be invoked and authorizing access to individual domain object instances. -To help you understand the differences, consider the authorization capabilities found in the Servlet Specification web pattern security, EJB Container Managed Security and file system security respectively. -Spring Security provides deep capabilities in all of these important areas, which we'll explore later in this reference guide. - - -[[history]] -=== History -Spring Security began in late 2003 as "The Acegi Security System for Spring". -A question was posed on the Spring Developers' mailing list asking whether there had been any consideration given to a Spring-based security implementation. -At the time the Spring community was relatively small (especially compared with the size today!), and indeed Spring itself had only existed as a SourceForge project from early 2003. -The response to the question was that it was a worthwhile area, although a lack of time currently prevented its exploration. - -With that in mind, a simple security implementation was built and not released. -A few weeks later another member of the Spring community inquired about security, and at the time this code was offered to them. -Several other requests followed, and by January 2004 around twenty people were using the code. -These pioneering users were joined by others who suggested a SourceForge project was in order, which was duly established in March 2004. - -In those early days, the project didn't have any of its own authentication modules. -Container Managed Security was relied upon for the authentication process, with Acegi Security instead focusing on authorization. -This was suitable at first, but as more and more users requested additional container support, the fundamental limitation of container-specific authentication realm interfaces became clear. -There was also a related issue of adding new JARs to the container's classpath, which was a common source of end user confusion and misconfiguration. - -Acegi Security-specific authentication services were subsequently introduced. -Around a year later, Acegi Security became an official Spring Framework subproject. -The 1. -0. -0 final release was published in May 2006 - after more than two and a half years of active use in numerous production software projects and many hundreds of improvements and community contributions. - -Acegi Security became an official Spring Portfolio project towards the end of 2007 and was rebranded as "Spring Security". - -Today Spring Security enjoys a strong and active open source community. -There are thousands of messages about Spring Security on the support forums. -There is an active core of developers who work on the code itself and an active community which also regularly share patches and support their peers. - - -[[release-numbering]] -=== Release Numbering -It is useful to understand how Spring Security release numbers work, as it will help you identify the effort (or lack thereof) involved in migrating to future releases of the project. -Each release uses a standard triplet of integers: MAJOR.MINOR.PATCH. -The intent is that MAJOR versions are incompatible, large-scale upgrades of the API. -MINOR versions should largely retain source and binary compatibility with older minor versions, thought there may be some design changes and incompatible updates. -PATCH level should be perfectly compatible, forwards and backwards, with the possible exception of changes which are to fix bugs and defects. - -The extent to which you are affected by changes will depend on how tightly integrated your code is. -If you are doing a lot of customization you are more likely to be affected than if you are using a simple namespace configuration. - -You should always test your application thoroughly before rolling out a new version. - - -[[get-spring-security]] -=== Getting Spring Security -You can get hold of Spring Security in several ways. -You can download a packaged distribution from the main http://spring. -io/spring-security[Spring Security] page, download individual jars from the Maven Central repository (or a Spring Maven repository for snapshot and milestone releases) or, alternatively, you can build the project from source yourself. - -[[maven]] -==== Usage with Maven - -A minimal Spring Security Maven set of dependencies typically looks like the following: - -.pom.xml -[source,xml] -[subs="verbatim,attributes"] ----- - - - - org.springframework.security - spring-security-web - {spring-security-version} - - - org.springframework.security - spring-security-config - {spring-security-version} - - ----- - -If you are using additional features like LDAP, OpenID, etc. you will need to also include the appropriate <>. - -[[maven-repositories]] -===== Maven Repositories -All GA releases (i.e. versions ending in .RELEASE) are deployed to Maven Central, so no additional Maven repositories need to be declared in your pom. - -If you are using a SNAPSHOT version, you will need to ensure you have the Spring Snapshot repository defined as shown below: - -.pom.xml -[source,xml] ----- - - - - spring-snapshot - Spring Snapshot Repository - http://repo.spring.io/snapshot - - ----- - -If you are using a milestone or release candidate version, you will need to ensure you have the Spring Milestone repository defined as shown below: - -.pom.xml -[source,xml] ----- - - - - spring-milestone - Spring Milestone Repository - http://repo.spring.io/milestone - - ----- - -[[maven-bom]] -===== Spring Framework Bom - -Spring Security builds against Spring Framework {spring-version}, but should work with 4.0.x. -The problem that many users will have is that Spring Security's transitive dependencies resolve Spring Framework {spring-version} which can cause strange classpath problems. - -One (tedious) way to circumvent this issue would be to include all the Spring Framework modules in a http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Management[] section of your pom. -An alternative approach is to include the `spring-framework-bom` within your `` section of your `pom.xml` as shown below: - -.pom.xml -[source,xml] -[subs="verbatim,attributes"] ----- - - - - org.springframework - spring-framework-bom - {spring-version} - pom - import - - - ----- - -This will ensure that all the transitive dependencies of Spring Security use the Spring {spring-version} modules. - -NOTE: This approach uses Maven's "bill of materials" (BOM) concept and is only available in Maven 2.0.9+. -For additional details about how dependencies are resolved refer to http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html[Maven's Introduction to the Dependency Mechanism documentation]. - -[[gradle]] -==== Gradle -A minimal Spring Security Gradle set of dependencies typically looks like the following: - -.build.gradle -[source,groovy] -[subs="verbatim,attributes"] ----- -dependencies { - compile 'org.springframework.security:spring-security-web:{spring-security-version}' - compile 'org.springframework.security:spring-security-config:{spring-security-version}' -} ----- - -If you are using additional features like LDAP, OpenID, etc. you will need to also include the appropriate <>. - -[[gradle-repositories]] -===== Gradle Repositories -All GA releases (i.e. versions ending in .RELEASE) are deployed to Maven Central, so using the mavenCentral() repository is sufficient for GA releases. - -.build.gradle -[source,groovy] ----- -repositories { - mavenCentral() -} ----- - -If you are using a SNAPSHOT version, you will need to ensure you have the Spring Snapshot repository defined as shown below: - -.build.gradle -[source,groovy] ----- -repositories { - maven { url 'https://repo.spring.io/snapshot' } -} ----- - -If you are using a milestone or release candidate version, you will need to ensure you have the Spring Milestone repository defined as shown below: - -.build.gradle -[source,groovy] ----- -repositories { - maven { url 'https://repo.spring.io/milestone' } -} ----- - -[[gradle-resolutionStrategy]] -===== Using Spring 4.0.x and Gradle - -By default Gradle will use the newest version when resolving transitive versions. -This means that often times no additional work is necessary when running Spring Security {spring-security-version} with Spring Framework {spring-version}. -However, at times there can be issues that come up so it is best to mitigate this using http://www.gradle.org/docs/current/dsl/org.gradle.api.artifacts.ResolutionStrategy.html[Gradle's ResolutionStrategy] as shown below: - -.build.gradle -[source,groovy] -[subs="verbatim,attributes"] ----- -configurations.all { - resolutionStrategy.eachDependency { DependencyResolveDetails details -> - if (details.requested.group == 'org.springframework') { - details.useVersion '{spring-version}' - } - } -} ----- - -This will ensure that all the transitive dependencies of Spring Security use the Spring {spring-version} modules. - -NOTE: This example uses Gradle 1.9, but may need modifications to work in future versions of Gradle since this is an incubating feature within Gradle. - -[[modules]] -==== Project Modules -In Spring Security 3.0, the codebase has been sub-divided into separate jars which more clearly separate different functionality areas and third-party dependencies. -If you are using Maven to build your project, then these are the modules you will add to your `pom.xml`. -Even if you're not using Maven, we'd recommend that you consult the `pom.xml` files to get an idea of third-party dependencies and versions. -Alternatively, a good idea is to examine the libraries that are included in the sample applications. - - -[[spring-security-core]] -===== Core - spring-security-core.jar -Contains core authentication and access-contol classes and interfaces, remoting support and basic provisioning APIs. -Required by any application which uses Spring Security. -Supports standalone applications, remote clients, method (service layer) security and JDBC user provisioning. -Contains the top-level packages: - -* `org.springframework.security.core` - -* `org.springframework.security.access` - -* `org.springframework.security.authentication` - -* `org.springframework.security.provisioning` - - - - - -[[spring-security-remoting]] -===== Remoting - spring-security-remoting.jar -Provides intergration with Spring Remoting. -You don't need this unless you are writing a remote client which uses Spring Remoting. -The main package is `org.springframework.security.remoting`. - - -[[spring-security-web]] -===== Web - spring-security-web.jar -Contains filters and related web-security infrastructure code. -Anything with a servlet API dependency. -You'll need it if you require Spring Security web authentication services and URL-based access-control. -The main package is `org.springframework.security.web`. - - -[[spring-security-config]] -===== Config - spring-security-config.jar -Contains the security namespace parsing code & Java configuration code. -You need it if you are using the Spring Security XML namespace for configuration or Spring Security's Java Configuration support. -The main package is `org.springframework.security.config`. -None of the classes are intended for direct use in an application. - - -[[spring-security-ldap]] -===== LDAP - spring-security-ldap.jar -LDAP authentication and provisioning code. -Required if you need to use LDAP authentication or manage LDAP user entries. -The top-level package is `org.springframework.security.ldap`. - - -[[spring-security-oauth2-core]] -===== OAuth 2.0 Core - spring-security-oauth2-core.jar -`spring-security-oauth2-core.jar` contains core classes and interfaces that provide support for the _OAuth 2.0 Authorization Framework_ and for _OpenID Connect Core 1.0_. -It is required by applications that use _OAuth 2.0_ or _OpenID Connect Core 1.0_, such as Client, Resource Server, and Authorization Server. -The top-level package is `org.springframework.security.oauth2.core`. - - -[[spring-security-oauth2-client]] -===== OAuth 2.0 Client - spring-security-oauth2-client.jar -`spring-security-oauth2-client.jar` is Spring Security's client support for _OAuth 2.0 Authorization Framework_ and _OpenID Connect Core 1.0_. -Required by applications leveraging *OAuth 2.0 Login* and/or OAuth Client support. -The top-level package is `org.springframework.security.oauth2.client`. - - -[[spring-security-oauth2-jose]] -===== OAuth 2.0 JOSE - spring-security-oauth2-jose.jar -`spring-security-oauth2-jose.jar` contains Spring Security's support for the _JOSE_ (Javascript Object Signing and Encryption) framework. -The _JOSE_ framework is intended to provide a method to securely transfer claims between parties. -It is built from a collection of specifications: - -* JSON Web Token (JWT) -* JSON Web Signature (JWS) -* JSON Web Encryption (JWE) -* JSON Web Key (JWK) - -It contains the top-level packages: - -* `org.springframework.security.oauth2.jwt` -* `org.springframework.security.oauth2.jose` - - -[[spring-security-acl]] -===== ACL - spring-security-acl.jar -Specialized domain object ACL implementation. -Used to apply security to specific domain object instances within your application. -The top-level package is `org.springframework.security.acls`. - - -[[spring-security-cas]] -===== CAS - spring-security-cas.jar -Spring Security's CAS client integration. -If you want to use Spring Security web authentication with a CAS single sign-on server. -The top-level package is `org.springframework.security.cas`. - - -[[spring-security-openid]] -===== OpenID - spring-security-openid.jar -OpenID web authentication support. -Used to authenticate users against an external OpenID server. -`org.springframework.security.openid`. -Requires OpenID4Java. - - -[[spring-security-test]] -===== Test - spring-security-test.jar -Support for testing with Spring Security. - - -[[get-source]] -==== Checking out the Source -Since Spring Security is an Open Source project, we'd strongly encourage you to check out the source code using git. -This will give you full access to all the sample applications and you can build the most up to date version of the project easily. -Having the source for a project is also a huge help in debugging. -Exception stack traces are no longer obscure black-box issues but you can get straight to the line that's causing the problem and work out what's happening. -The source is the ultimate documentation for a project and often the simplest place to find out how something actually works. - -To obtain the source for the project, use the following git command: - -[source,txt] ----- -git clone https://github.com/spring-projects/spring-security.git ----- - -This will give you access to the entire project history (including all releases and branches) on your local machine. - -[[new]] -== What's New in Spring Security 5.0 - -Spring Security 5.0 provides a number of new features as well as support for Spring Framework 5. -In total there were 400+ enhancements and bugs resolved. -You can find the change log at -https://github.com/spring-projects/spring-security/milestone/90?closed=1[5.0.0.M1] -https://github.com/spring-projects/spring-security/milestone/97?closed=1[5.0.0.M2] -https://github.com/spring-projects/spring-security/milestone/100?closed=1[5.0.0.M3] -https://github.com/spring-projects/spring-security/milestone/101?closed=1[5.0.0.M4] -https://github.com/spring-projects/spring-security/milestone/102?closed=1[5.0.0.M5] -https://github.com/spring-projects/spring-security/milestone/103?closed=1[5.0.0.RC1] -https://github.com/spring-projects/spring-security/milestone/98?closed=1[5.0.0.RELEASE]. -Below are the highlights of this milestone release. - -=== New Features - -* <> -* Reactive Support -** <> -** <> -** <> -* Modernized <> - -[[samples]] -== Samples and Guides (Start Here) - -If you are looking to get started with Spring Security, the best place to start is our Sample Applications. - -.Sample Applications -|=== -| Source | Description | Guide - -| {gh-samples-url}/javaconfig/helloworld[Hello Spring Security] -| Demonstrates how to integrate Spring Security with an existing application using Java-based configuration. -| link:../../guides/html5/helloworld-javaconfig.html[Hello Spring Security Guide] - -| {gh-samples-url}/boot/helloworld[Hello Spring Security Boot] -| Demonstrates how to integrate Spring Security with an existing Spring Boot application. -| link:../../guides/html5/helloworld-boot.html[Hello Spring Security Boot Guide] - -| {gh-samples-url}/xml/helloworld[Hello Spring Security XML] -| Demonstrates how to integrate Spring Security with an existing application using XML-based configuration. -| link:../../guides/html5/helloworld-xml.html[Hello Spring Security XML Guide] - -| {gh-samples-url}/javaconfig/hellomvc[Hello Spring MVC Security] -| Demonstrates how to integrate Spring Security with an existing Spring MVC application. -| link:../../guides/html5/hellomvc-javaconfig.html[Hello Spring MVC Security Guide] - -| {gh-samples-url}/javaconfig/form[Custom Login Form] -| Demonstrates how to create a custom login form. -| link:../../guides/html5/form-javaconfig.html[Custom Login Form Guide] - -| {gh-samples-url}/boot/oauth2login[OAuth 2.0 Login] -| Demonstrates how to integrate OAuth 2.0 Login with an OAuth 2.0 or OpenID Connect 1.0 Provider. -| link:{gh-samples-url}/boot/oauth2login/README.adoc[OAuth 2.0 Login Guide] - -|=== - -[[jc]] -== Java Configuration - -General support for http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/beans.html#beans-java[Java Configuration] was added to Spring Framework in Spring 3.1. -Since Spring Security 3.2 there has been Spring Security Java Configuration support which enables users to easily configure Spring Security without the use of any XML. - -If you are familiar with the <> then you should find quite a few similarities between it and the Security Java Configuration support. - -NOTE: Spring Security provides https://github.com/spring-projects/spring-security/tree/master/samples/javaconfig[lots of sample applications] which demonstrate the use of Spring Security Java Configuration. - -=== Hello Web Security Java Configuration - -The first step is to create our Spring Security Java Configuration. -The configuration creates a Servlet Filter known as the `springSecurityFilterChain` which is responsible for all the security (protecting the application URLs, validating submitted username and passwords, redirecting to the log in form, etc) within your application. -You can find the most basic example of a Spring Security Java Configuration below: - -[[jc-hello-wsca]] -[source,java] ----- -import org.springframework.beans.factory.annotation.Autowired; - -import org.springframework.context.annotation.*; -import org.springframework.security.config.annotation.authentication.builders.*; -import org.springframework.security.config.annotation.web.configuration.*; - -@EnableWebSecurity -public class WebSecurityConfig implements WebMvcConfigurer { - - @Bean - public UserDetailsService userDetailsService() throws Exception { - InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); - manager.createUser(User.withDefaultPasswordEncoder().username("user").password("password").roles("USER").build()); - return manager; - } -} ----- - -There really isn't much to this configuration, but it does a lot. -You can find a summary of the features below: - -* Require authentication to every URL in your application -* Generate a login form for you -* Allow the user with the *Username* _user_ and the *Password* _password_ to authenticate with form based authentication -* Allow the user to logout -* http://en.wikipedia.org/wiki/Cross-site_request_forgery[CSRF attack] prevention -* http://en.wikipedia.org/wiki/Session_fixation[Session Fixation] protection -* Security Header integration -** http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security[HTTP Strict Transport Security] for secure requests -** http://msdn.microsoft.com/en-us/library/ie/gg622941(v=vs.85).aspx[X-Content-Type-Options] integration -** Cache Control (can be overridden later by your application to allow caching of your static resources) -** http://msdn.microsoft.com/en-us/library/dd565647(v=vs.85).aspx[X-XSS-Protection] integration -** X-Frame-Options integration to help prevent http://en.wikipedia.org/wiki/Clickjacking[Clickjacking] -* Integrate with the following Servlet API methods -** http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#getRemoteUser()[HttpServletRequest#getRemoteUser()] -** http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#getUserPrincipal()[HttpServletRequest.html#getUserPrincipal()] -** http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#isUserInRole(java.lang.String)[HttpServletRequest.html#isUserInRole(java.lang.String)] -** http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#login(java.lang.String,%20java.lang.String)[HttpServletRequest.html#login(java.lang.String, java.lang.String)] -** http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#logout()[HttpServletRequest.html#logout()] - -==== AbstractSecurityWebApplicationInitializer - -The next step is to register the `springSecurityFilterChain` with the war. -This can be done in Java Configuration with http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-container-config[Spring's WebApplicationInitializer support] in a Servlet 3.0+ environment. -Not suprisingly, Spring Security provides a base class `AbstractSecurityWebApplicationInitializer` that will ensure the `springSecurityFilterChain` gets registered for you. -The way in which we use `AbstractSecurityWebApplicationInitializer` differs depending on if we are already using Spring or if Spring Security is the only Spring component in our application. - -* <> - Use these instructions if you are not using Spring already -* <> - Use these instructions if you are already using Spring - -==== AbstractSecurityWebApplicationInitializer without Existing Spring - -If you are not using Spring or Spring MVC, you will need to pass in the `WebSecurityConfig` into the superclass to ensure the configuration is picked up. -You can find an example below: - -[source,java] ----- -import org.springframework.security.web.context.*; - -public class SecurityWebApplicationInitializer - extends AbstractSecurityWebApplicationInitializer { - - public SecurityWebApplicationInitializer() { - super(WebSecurityConfig.class); - } -} ----- - -The `SecurityWebApplicationInitializer` will do the following things: - -* Automatically register the springSecurityFilterChain Filter for every URL in your application -* Add a ContextLoaderListener that loads the <>. - -==== AbstractSecurityWebApplicationInitializer with Spring MVC - -If we were using Spring elsewhere in our application we probably already had a `WebApplicationInitializer` that is loading our Spring Configuration. -If we use the previous configuration we would get an error. -Instead, we should register Spring Security with the existing `ApplicationContext`. -For example, if we were using Spring MVC our `SecurityWebApplicationInitializer` would look something like the following: - -[source,java] ----- -import org.springframework.security.web.context.*; - -public class SecurityWebApplicationInitializer - extends AbstractSecurityWebApplicationInitializer { - -} ----- - -This would simply only register the springSecurityFilterChain Filter for every URL in your application. -After that we would ensure that `WebSecurityConfig` was loaded in our existing ApplicationInitializer. -For example, if we were using Spring MVC it would be added in the `getRootConfigClasses()` - -[[message-web-application-inititializer-java]] -[source,java] ----- -public class MvcWebApplicationInitializer extends - AbstractAnnotationConfigDispatcherServletInitializer { - - @Override - protected Class[] getRootConfigClasses() { - return new Class[] { WebSecurityConfig.class }; - } - - // ... other overrides ... -} ----- - -[[jc-httpsecurity]] -=== HttpSecurity - -Thus far our <> only contains information about how to authenticate our users. -How does Spring Security know that we want to require all users to be authenticated? How does Spring Security know we want to support form based authentication? The reason for this is that the `WebSecurityConfigurerAdapter` provides a default configuration in the `configure(HttpSecurity http)` method that looks like: - -[source,java] ----- -protected void configure(HttpSecurity http) throws Exception { - http - .authorizeRequests() - .anyRequest().authenticated() - .and() - .formLogin() - .and() - .httpBasic(); -} ----- - -The default configuration above: - -* Ensures that any request to our application requires the user to be authenticated -* Allows users to authenticate with form based login -* Allows users to authenticate with HTTP Basic authentication - -You will notice that this configuration is quite similar the XML Namespace configuration: - -[source,xml] ----- - - - - - ----- - -The Java Configuration equivalent of closing an XML tag is expressed using the `and()` method which allows us to continue configuring the parent. -If you read the code it also makes sense. -I want to configure authorized requests __and__ configure form login __and__ configure HTTP Basic authentication. - -However, Java Configuration has different defaults URLs and parameters. -Keep this in mind when creating custom login pages. -The result is that our URLs are more RESTful. -Additionally, it is not quite so obvious we are using Spring Security which helps to prevent https://www.owasp.org/index.php/Information_Leak_(information_disclosure)[information leaks]. -For example: - -[[jc-form]] -=== Java Configuration and Form Login -You might be wondering where the login form came from when you were prompted to log in, since we made no mention of any HTML files or JSPs. -Since Spring Security's default configuration does not explicitly set a URL for the login page, Spring Security generates one automatically, based on the features that are enabled and using standard values for the URL which processes the submitted login, the default target URL the user will be sent to after logging in and so on. - -While the automatically generated log in page is convenient to get up and running quickly, most applications will want to provide their own log in page. -To do so we can update our configuration as seen below: - - -[source,java] ----- -protected void configure(HttpSecurity http) throws Exception { - http - .authorizeRequests() - .anyRequest().authenticated() - .and() - .formLogin() - .loginPage("/login") // <1> - .permitAll(); // <2> -} ----- - -<1> The updated configuration specifies the location of the log in page. -<2> We must grant all users (i.e. unauthenticated users) access to our log in page. -The `formLogin().permitAll()` method allows granting access to all users for all URLs associated with form based log in. - -An example log in page implemented with JSPs for our current configuration can be seen below: - -NOTE: The login page below represents our current configuration. -We could easily update our configuration if some of the defaults do not meet our needs. - -[source,html] ----- - -
<1> - <2> -

- Invalid username and password. -

-
- <3> -

- You have been logged out. -

-
-

- - <4> -

-

- - <5> -

- - name="${_csrf.parameterName}" - value="${_csrf.token}"/> - -
----- - -<1> A POST to the `/login` URL will attempt to authenticate the user -<2> If the query parameter `error` exists, authentication was attempted and failed -<3> If the query parameter `logout` exists, the user was successfully logged out -<4> The username must be present as the HTTP parameter named __username__ -<5> The password must be present as the HTTP parameter named __password__ -<6> We must <> To learn more read the <> section of the reference - -[[jc-authorize-requests]] -=== Authorize Requests -Our examples have only required users to be authenticated and have done so for every URL in our application. -We can specify custom requirements for our URLs by adding multiple children to our `http.authorizeRequests()` method. -For example: - - -[source,java] ----- -protected void configure(HttpSecurity http) throws Exception { - http - .authorizeRequests() <1> - .antMatchers("/resources/**", "/signup", "/about").permitAll() <2> - .antMatchers("/admin/**").hasRole("ADMIN") <3> - .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')") <4> - .anyRequest().authenticated() <5> - .and() - // ... - .formLogin(); -} ----- - -<1> There are multiple children to the `http.authorizeRequests()` method each matcher is considered in the order they were declared. -<2> We specified multiple URL patterns that any user can access. -Specifically, any user can access a request if the URL starts with "/resources/", equals "/signup", or equals "/about". -<3> Any URL that starts with "/admin/" will be restricted to users who have the role "ROLE_ADMIN". -You will notice that since we are invoking the `hasRole` method we do not need to specify the "ROLE_" prefix. -<4> Any URL that starts with "/db/" requires the user to have both "ROLE_ADMIN" and "ROLE_DBA". -You will notice that since we are using the `hasRole` expression we do not need to specify the "ROLE_" prefix. -<5> Any URL that has not already been matched on only requires that the user be authenticated - -[[jc-logout]] -=== Handling Logouts - -When using the `{security-api-url}org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurerAdapter.html[WebSecurityConfigurerAdapter]`, logout capabilities are automatically applied. -The default is that accessing the URL `/logout` will log the user out by: - -- Invalidating the HTTP Session -- Cleaning up any RememberMe authentication that was configured -- Clearing the `SecurityContextHolder` -- Redirect to `/login?logout` - -Similar to configuring login capabilities, however, you also have various options to further customize your logout requirements: - -[source,java] ----- -protected void configure(HttpSecurity http) throws Exception { - http - .logout() <1> - .logoutUrl("/my/logout") <2> - .logoutSuccessUrl("/my/index") <3> - .logoutSuccessHandler(logoutSuccessHandler) <4> - .invalidateHttpSession(true) <5> - .addLogoutHandler(logoutHandler) <6> - .deleteCookies(cookieNamesToClear) <7> - .and() - ... -} ----- - -<1> Provides logout support. -This is automatically applied when using `WebSecurityConfigurerAdapter`. -<2> The URL that triggers log out to occur (default is `/logout`). -If CSRF protection is enabled (default), then the request must also be a POST. -For more information, please consult the {security-api-url}org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.html#logoutUrl-java.lang.String-[JavaDoc]. -<3> The URL to redirect to after logout has occurred. -The default is `/login?logout`. -For more information, please consult the {security-api-url}org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.html#logoutSuccessUrl-java.lang.String-[JavaDoc]. -<4> Let's you specify a custom `LogoutSuccessHandler`. -If this is specified, `logoutSuccessUrl()` is ignored. -For more information, please consult the {security-api-url}org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.html#logoutSuccessHandler-org.springframework.security.web.authentication.logout.LogoutSuccessHandler-[JavaDoc]. -<5> Specify whether to invalidate the `HttpSession` at the time of logout. -This is *true* by default. -Configures the `SecurityContextLogoutHandler` under the covers. -For more information, please consult the {security-api-url}org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.html#invalidateHttpSession-boolean-[JavaDoc]. -<6> Adds a `LogoutHandler`. -`SecurityContextLogoutHandler` is added as the last `LogoutHandler` by default. -<7> Allows specifying the names of cookies to be removed on logout success. -This is a shortcut for adding a `CookieClearingLogoutHandler` explicitly. - -[NOTE] -==== -Logouts can of course also be configured using the XML Namespace notation. -Please see the documentation for the <> in the Spring Security XML Namespace section for further details. -==== - -Generally, in order to customize logout functionality, you can add -`{security-api-url}org/springframework/security/web/authentication/logout/LogoutHandler.html[LogoutHandler]` -and/or -`{security-api-url}org/springframework/security/web/authentication/logout/LogoutSuccessHandler.html[LogoutSuccessHandler]` -implementations. -For many common scenarios, these handlers are applied under the -covers when using the fluent API. - -[[jc-logout-handler]] -==== LogoutHandler - -Generally, `{security-api-url}org/springframework/security/web/authentication/logout/LogoutHandler.html[LogoutHandler]` -implementations indicate classes that are able to participate in logout handling. -They are expected to be invoked to perform necessary clean-up. -As such they should -not throw exceptions. -Various implementations are provided: - -- {security-api-url}org/springframework/security/web/authentication/rememberme/PersistentTokenBasedRememberMeServices.html[PersistentTokenBasedRememberMeServices] -- {security-api-url}org/springframework/security/web/authentication/rememberme/TokenBasedRememberMeServices.html[TokenBasedRememberMeServices] -- {security-api-url}org/springframework/security/web/authentication/logout/CookieClearingLogoutHandler.html[CookieClearingLogoutHandler] -- {security-api-url}org/springframework/security/web/csrf/CsrfLogoutHandler.html[CsrfLogoutHandler] -- {security-api-url}org/springframework/security/web/authentication/logout/SecurityContextLogoutHandler.html[SecurityContextLogoutHandler] - -Please see <> for details. - -Instead of providing `LogoutHandler` implementations directly, the fluent API also provides shortcuts that provide the respective `LogoutHandler` implementations under the covers. -E.g. `deleteCookies()` allows specifying the names of one or more cookies to be removed on logout success. -This is a shortcut compared to adding a `CookieClearingLogoutHandler`. - -[[jc-logout-success-handler]] -==== LogoutSuccessHandler - -The `LogoutSuccessHandler` is called after a successful logout by the `LogoutFilter`, to handle e.g. -redirection or forwarding to the appropriate destination. -Note that the interface is almost the same as the `LogoutHandler` but may raise an exception. - -The following implementations are provided: - -- {security-api-url}org/springframework/security/web/authentication/logout/SimpleUrlLogoutSuccessHandler.html[SimpleUrlLogoutSuccessHandler] -- HttpStatusReturningLogoutSuccessHandler - -As mentioned above, you don't need to specify the `SimpleUrlLogoutSuccessHandler` directly. -Instead, the fluent API provides a shortcut by setting the `logoutSuccessUrl()`. -This will setup the `SimpleUrlLogoutSuccessHandler` under the covers. -The provided URL will be redirected to after a logout has occurred. -The default is `/login?logout`. - -The `HttpStatusReturningLogoutSuccessHandler` can be interesting in REST API type scenarios. -Instead of redirecting to a URL upon the successful logout, this `LogoutSuccessHandler` allows you to provide a plain HTTP status code to be returned. -If not configured a status code 200 will be returned by default. - -[[jc-logout-references]] -==== Further Logout-Related References - -- <> -- <> -- <> -- <> -- <> in section CSRF Caveats -- Section <> (CAS protocol) -- Documentation for the <> in the Spring Security XML Namespace section - -[[jc-webflux]] -=== WebFlux Security - -Spring Security's WebFlux support relies on a `WebFilter` and works the same for Spring WebFlux and Spring WebFlux.Fn. -You can find a few sample applications that demonstrate the code below: - -* Hello WebFlux {gh-samples-url}/javaconfig/hellowebflux[hellowebflux] -* Hello WebFlux.Fn {gh-samples-url}/javaconfig/hellowebfluxfn[hellowebfluxfn] -* Hello WebFlux Method {gh-samples-url}/javaconfig/hellowebflux-method[hellowebflux-method] - - -==== Minimal WebFlux Security Configuration - -You can find a minimal WebFlux Security configuration below: - -[source,java] ------ -@EnableWebFluxSecurity -public class HelloWebfluxSecurityConfig { - - @Bean - public MapReactiveUserDetailsService userDetailsService() { - UserDetails user = User.withDefaultPasswordEncoder() - .username("user") - .password("user") - .roles("USER") - .build(); - return new MapReactiveUserDetailsService(user); - } -} ------ - -This configuration provides form and http basic authentication, sets up authorization to require an authenticated user for accessing any page, sets up a default log in page and a default log out page, sets up security related HTTP headers, CSRF protection, and more. - -==== Explicit WebFlux Security Configuration - -You can find an explicit version of the minimal WebFlux Security configuration below: - -[source,java] ------ -@EnableWebFluxSecurity -public class HelloWebfluxSecurityConfig { - - @Bean - public MapReactiveUserDetailsService userDetailsService() { - UserDetails user = User.withDefaultPasswordEncoder() - .username("user") - .password("user") - .roles("USER") - .build(); - return new MapReactiveUserDetailsService(user); - } - - @Bean - public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { - http - .authorizeExchange() - .anyExchange().authenticated() - .and() - .httpBasic().and() - .formLogin(); - return http.build(); - } -} ------ - -This configuration explicitly sets up all the same things as our minimal configuration. -From here you can easily make the changes to the defaults. - -[[jc-oauth2login]] -=== OAuth 2.0 Login - -The OAuth 2.0 Login feature provides an application with the capability to have users log in to the application by using their existing account at an OAuth 2.0 Provider (e.g. -GitHub) or OpenID Connect 1.0 Provider (such as Google). -OAuth 2.0 Login implements the use cases: "Login with Google" or "Login with GitHub". - -NOTE: OAuth 2.0 Login is implemented by using the *Authorization Code Grant*, as specified in the https://tools.ietf.org/html/rfc6749#section-4.1[OAuth 2.0 Authorization Framework] and http://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth[OpenID Connect Core 1.0]. - -[[jc-oauth2login-sample-boot]] -==== Spring Boot 2.0 Sample - -Spring Boot 2.0 brings full auto-configuration capabilities for OAuth 2.0 Login. - -This section shows how to configure the {gh-samples-url}/boot/oauth2login[*OAuth 2.0 Login sample*] using _Google_ as the _Authentication Provider_ and covers the following topics: - -* <> -* <> -* <> -* <> - - -[[jc-oauth2login-sample-initial-setup]] -===== Initial setup - -To use Google's OAuth 2.0 authentication system for login, you must set up a project in the Google API Console to obtain OAuth 2.0 credentials. - -NOTE: https://developers.google.com/identity/protocols/OpenIDConnect[Google's OAuth 2.0 implementation] for authentication conforms to the http://openid.net/connect/[OpenID Connect 1.0] specification and is http://openid.net/certification/[OpenID Certified]. - -Follow the instructions on the https://developers.google.com/identity/protocols/OpenIDConnect[OpenID Connect] page, starting in the section, "Setting up OAuth 2.0". - -After completing the "Obtain OAuth 2.0 credentials" instructions, you should have a new OAuth Client with credentials consisting of a Client ID and a Client Secret. - -[[jc-oauth2login-sample-redirect-uri]] -===== Setting the redirect URI - -The redirect URI is the path in the application that the end-user's user-agent is redirected back to after they have authenticated with Google and have granted access to the OAuth Client _(<>)_ on the Consent page. - -In the "Set a redirect URI" sub-section, ensure that the *Authorized redirect URIs* field is set to `http://localhost:8080/login/oauth2/code/google`. - -TIP: The default redirect URI template is `{baseUrl}/login/oauth2/code/{registrationId}`. -The *_registrationId_* is a unique identifier for the <>. - -[[jc-oauth2login-sample-application-config]] -===== Configure `application.yml` - -Now that you have a new OAuth Client with Google, you need to configure the application to use the OAuth Client for the _authentication flow_. -To do so: - -. Go to `application.yml` and set the following configuration: -+ -[source,yaml] ----- -spring: - security: - oauth2: - client: - registration: <1> - google: <2> - client-id: google-client-id - client-secret: google-client-secret ----- -+ -.OAuth Client properties -==== -<1> `spring.security.oauth2.client.registration` is the base property prefix for OAuth Client properties. -<2> Following the base property prefix is the ID for the <>, such as google. -==== - -. Replace the values in the `client-id` and `client-secret` property with the OAuth 2.0 credentials you created earlier. - - -[[jc-oauth2login-sample-boot-application]] -===== Boot up the application - -Launch the Spring Boot 2.0 sample and go to `http://localhost:8080`. -You are then redirected to the default _auto-generated_ login page, which displays a link for Google. - -Click on the Google link, and you are then redirected to Google for authentication. - -After authenticating with your Google account credentials, the next page presented to you is the Consent screen. -The Consent screen asks you to either allow or deny access to the OAuth Client you created earlier. -Click *Allow* to authorize the OAuth Client to access your email address and basic profile information. - -At this point, the OAuth Client retrieves your email address and basic profile information from the http://openid.net/specs/openid-connect-core-1_0.html#UserInfo[UserInfo Endpoint] and establishes an authenticated session. - -[[jc-oauth2login-client-registration]] -==== ClientRegistration - -`ClientRegistration` is a representation of a client registered with an OAuth 2.0 or OpenID Connect 1.0 Provider. - -A client registration holds information, such as client id, client secret, -authorization grant type, redirect URI, scope(s), authorization URI, token URI, and other details. - -`ClientRegistration` and its properties are defined as follows: - -[source,java] ----- -public final class ClientRegistration { - private String registrationId; <1> - private String clientId; <2> - private String clientSecret; <3> - private ClientAuthenticationMethod clientAuthenticationMethod; <4> - private AuthorizationGrantType authorizationGrantType; <5> - private String redirectUriTemplate; <6> - private Set scopes; <7> - private ProviderDetails providerDetails; - private String clientName; <8> - - public class ProviderDetails { - private String authorizationUri; <9> - private String tokenUri; <10> - private UserInfoEndpoint userInfoEndpoint; - private String jwkSetUri; <11> - - public class UserInfoEndpoint { - private String uri; <12> - private String userNameAttributeName; <13> - - } - } -} ----- -<1> `registrationId`: The ID that uniquely identifies the `ClientRegistration`. -<2> `clientId`: The client identifier. -<3> `clientSecret`: The client secret. -<4> `clientAuthenticationMethod`: The method used to authenticate the Client with the Provider. -The supported values are *basic* and *post*. -<5> `authorizationGrantType`: The OAuth 2.0 Authorization Framework defines four https://tools.ietf.org/html/rfc6749#section-1.3[Authorization Grant] types. - The supported values are authorization_code and implicit. -<6> `redirectUriTemplate`: The client's registered redirect URI that the _Authorization Server_ redirects the end-user's user-agent - to after the end-user has authenticated and authorized access to the client. - The default redirect URI template is `{baseUrl}/login/oauth2/code/{registrationId}`, which supports URI template variables. -<7> `scopes`: The scope(s) requested by the client during the Authorization Request flow, such as openid, email, or profile. -<8> `clientName`: A descriptive name used for the client. -The name may be used in certain scenarios, such as when displaying the name of the client in the auto-generated login page. -<9> `authorizationUri`: The Authorization Endpoint URI for the Authorization Server. -<10> `tokenUri`: The Token Endpoint URI for the Authorization Server. -<11> `jwkSetUri`: The URI used to retrieve the https://tools.ietf.org/html/rfc7517[JSON Web Key (JWK)] Set from the Authorization Server, - which contains the cryptographic key(s) used to verify the https://tools.ietf.org/html/rfc7515[JSON Web Signature (JWS)] of the ID Token and optionally the UserInfo Response. -<12> `(userInfoEndpoint)uri`: The UserInfo Endpoint URI used to access the claims/attributes of the authenticated end-user. -<13> `userNameAttributeName`: The name of the attribute returned in the UserInfo Response that references the Name or Identifier of the end-user. - -[[jc-oauth2login-boot-property-mappings]] -==== Spring Boot 2.0 Property Mappings - -The following table outlines the mapping of the Spring Boot 2.0 OAuth Client properties to the `ClientRegistration` properties. - -|=== -|Spring Boot 2.0 |ClientRegistration - -|`spring.security.oauth2.client.registration._[registrationId]_` -|`registrationId` - -|`spring.security.oauth2.client.registration._[registrationId]_.client-id` -|`clientId` - -|`spring.security.oauth2.client.registration._[registrationId]_.client-secret` -|`clientSecret` - -|`spring.security.oauth2.client.registration._[registrationId]_.client-authentication-method` -|`clientAuthenticationMethod` - -|`spring.security.oauth2.client.registration._[registrationId]_.authorization-grant-type` -|`authorizationGrantType` - -|`spring.security.oauth2.client.registration._[registrationId]_.redirect-uri-template` -|`redirectUriTemplate` - -|`spring.security.oauth2.client.registration._[registrationId]_.scope` -|`scopes` - -|`spring.security.oauth2.client.registration._[registrationId]_.client-name` -|`clientName` - -|`spring.security.oauth2.client.provider._[providerId]_.authorization-uri` -|`providerDetails.authorizationUri` - -|`spring.security.oauth2.client.provider._[providerId]_.token-uri` -|`providerDetails.tokenUri` - -|`spring.security.oauth2.client.provider._[providerId]_.jwk-set-uri` -|`providerDetails.jwkSetUri` - -|`spring.security.oauth2.client.provider._[providerId]_.user-info-uri` -|`providerDetails.userInfoEndpoint.uri` - -|`spring.security.oauth2.client.provider._[providerId]_.userNameAttribute` -|`providerDetails.userInfoEndpoint.userNameAttributeName` -|=== - -[[jc-oauth2login-client-registration-repo]] -==== ClientRegistrationRepository - -The `ClientRegistrationRepository` serves as a repository for OAuth 2.0 / OpenID Connect 1.0 `ClientRegistration`(s). - -[NOTE] -Client registration information is ultimately stored and owned by the associated Authorization Server. -This repository provides the ability to retrieve a sub-set of the primary client registration information, -which is stored with the Authorization Server. - -Spring Boot 2.0 auto-configuration binds each of the properties under `spring.security.oauth2.client.registration._[registrationId]_` -to an instance of `ClientRegistration` and then composes each of the `ClientRegistration` instance(s) within a `ClientRegistrationRepository`. - -[NOTE] -The default implementation of `ClientRegistrationRepository` is `InMemoryClientRegistrationRepository`. - -The auto-configuration also registers the `ClientRegistrationRepository` as a `@Bean` in the `ApplicationContext` -so that it is available for dependency-injection, if needed by the application. - -The following listing shows an example: - -[source,java] ----- -@Controller -public class MainController { - - @Autowired - private ClientRegistrationRepository clientRegistrationRepository; - - @RequestMapping("/") - public String index() { - ClientRegistration googleRegistration = - this.clientRegistrationRepository.findByRegistrationId("google"); - - ... - - return "index"; - } -} ----- - -[[jc-oauth2login-common-oauth2-provider]] -==== CommonOAuth2Provider - -`CommonOAuth2Provider` pre-defines a set of default client properties for a number of well known providers: Google, GitHub, Facebook, and Okta. - -For example, the `authorization-uri`, `token-uri`, and `user-info-uri` do not change often for a Provider. -Therefore, it makes sense to provide default values in order to reduce the required configuration. - -As demonstrated previously, when we <>, only the `client-id` and `client-secret` properties are required. - -The following listing shows an example: - -[source,yaml] ----- -spring: - security: - oauth2: - client: - registration: - google: - client-id: google-client-id - client-secret: google-client-secret ----- - -[TIP] -The auto-defaulting of client properties works seamlessly here because the `registrationId` (`google`) matches the `GOOGLE` `enum` (case-insensitive) in `CommonOAuth2Provider`. - -For cases where you may want to specify a different `registrationId`, such as `google-login`, -you can still leverage auto-defaulting of client properties by configuring the `provider` property. - -The following listing shows an example: - -[source,yaml] ----- -spring: - security: - oauth2: - client: - registration: - google-login: <1> - provider: google <2> - client-id: google-client-id - client-secret: google-client-secret ----- -<1> The `registrationId` is set to `google-login`. -<2> The `provider` property is set to `google`, which will leverage the auto-defaulting of client properties set in `CommonOAuth2Provider.GOOGLE.getBuilder()`. - -[[jc-oauth2login-custom-provider-properties]] -==== Configuring Custom Provider Properties - -There are some OAuth 2.0 Providers that support multi-tenancy, which results in different protocol endpoints for each tenant (or sub-domain). - -For example, an OAuth Client registered with Okta is assigned to a specific sub-domain and have their own protocol endpoints. - -For these cases, Spring Boot 2.0 provides the following base property for configuring custom provider properties: `spring.security.oauth2.client.provider._[providerId]_`. - -The following listing shows an example: - -[source,yaml] ----- -spring: - security: - oauth2: - client: - registration: - okta: - client-id: okta-client-id - client-secret: okta-client-secret - provider: - okta: <1> - authorization-uri: https://your-subdomain.oktapreview.com/oauth2/v1/authorize - token-uri: https://your-subdomain.oktapreview.com/oauth2/v1/token - user-info-uri: https://your-subdomain.oktapreview.com/oauth2/v1/userinfo - user-name-attribute: sub - jwk-set-uri: https://your-subdomain.oktapreview.com/oauth2/v1/keys ----- - -<1> The base property (`spring.security.oauth2.client.provider.okta`) allows for custom configuration of protocol endpoint locations. - -[[jc-oauth2login-override-boot-autoconfig]] -==== Overriding Spring Boot 2.0 Auto-configuration - -The Spring Boot 2.0 Auto-configuration class for OAuth Client support is `OAuth2ClientAutoConfiguration`. - -It performs the following tasks: - -* Registers a `ClientRegistrationRepository` `@Bean` composed of `ClientRegistration`(s) from the configured OAuth Client properties. -* Provides a `WebSecurityConfigurerAdapter` `@Configuration` and enables OAuth 2.0 Login through `httpSecurity.oauth2Login()`. - -If you need to override the auto-configuration based on your specific requirements, you may do so in the following ways: - -* <> -* <> -* <> - - -[[jc-oauth2login-register-clientregistrationrepository-bean]] -===== Register a `ClientRegistrationRepository` `@Bean` - -The following example shows how to register a `ClientRegistrationRepository` `@Bean`: - -[source,java] ----- -@Configuration -public class OAuth2LoginConfig { - - @Bean - public ClientRegistrationRepository clientRegistrationRepository() { - return new InMemoryClientRegistrationRepository(this.googleClientRegistration()); - } - - private ClientRegistration googleClientRegistration() { - return ClientRegistration.withRegistrationId("google") - .clientId("google-client-id") - .clientSecret("google-client-secret") - .clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) - .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) - .redirectUriTemplate("{baseUrl}/login/oauth2/code/{registrationId}") - .scope("openid", "profile", "email", "address", "phone") - .authorizationUri("https://accounts.google.com/o/oauth2/v2/auth") - .tokenUri("https://www.googleapis.com/oauth2/v4/token") - .userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo") - .userNameAttributeName(IdTokenClaimNames.SUB) - .jwkSetUri("https://www.googleapis.com/oauth2/v3/certs") - .clientName("Google") - .build(); - } -} ----- - - -[[jc-oauth2login-provide-websecurityconfigureradapter]] -===== Provide a `WebSecurityConfigurerAdapter` - -The following example shows how to provide a `WebSecurityConfigurerAdapter` with `@EnableWebSecurity` and enable OAuth 2.0 login through `httpSecurity.oauth2Login()`: - -[source,java] ----- -@EnableWebSecurity -public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(HttpSecurity http) throws Exception { - http - .authorizeRequests() - .anyRequest().authenticated() - .and() - .oauth2Login(); - } -} ----- - - -[[jc-oauth2login-completely-override-autoconfiguration]] -===== Completely Override the Auto-configuration - -The following example shows how to completely override the auto-configuration by both registering a `ClientRegistrationRepository` `@Bean` and providing a `WebSecurityConfigurerAdapter`, both of which were described in the two preceding sections. - -[source,java] ----- -@Configuration -public class OAuth2LoginConfig { - - @EnableWebSecurity - public static class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(HttpSecurity http) throws Exception { - http - .authorizeRequests() - .anyRequest().authenticated() - .and() - .oauth2Login(); - } - } - - @Bean - public ClientRegistrationRepository clientRegistrationRepository() { - return new InMemoryClientRegistrationRepository(this.googleClientRegistration()); - } - - private ClientRegistration googleClientRegistration() { - return ClientRegistration.withRegistrationId("google") - .clientId("google-client-id") - .clientSecret("google-client-secret") - .clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) - .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) - .redirectUriTemplate("{baseUrl}/login/oauth2/code/{registrationId}") - .scope("openid", "profile", "email", "address", "phone") - .authorizationUri("https://accounts.google.com/o/oauth2/v2/auth") - .tokenUri("https://www.googleapis.com/oauth2/v4/token") - .userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo") - .userNameAttributeName(IdTokenClaimNames.SUB) - .jwkSetUri("https://www.googleapis.com/oauth2/v3/certs") - .clientName("Google") - .build(); - } -} ----- - -[[jc-oauth2login-javaconfig-wo-boot]] -==== Java Configuration without Spring Boot 2.0 - -If you are not able to use Spring Boot 2.0 and would like to configure one of the pre-defined providers in `CommonOAuth2Provider` (for example, Google), apply the following configuration: - -[source,java] ----- -@Configuration -public class OAuth2LoginConfig { - - @EnableWebSecurity - public static class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(HttpSecurity http) throws Exception { - http - .authorizeRequests() - .anyRequest().authenticated() - .and() - .oauth2Login(); - } - } - - @Bean - public ClientRegistrationRepository clientRegistrationRepository() { - return new InMemoryClientRegistrationRepository(this.googleClientRegistration()); - } - - @Bean - public OAuth2AuthorizedClientService authorizedClientService() { - return new InMemoryOAuth2AuthorizedClientService(this.clientRegistrationRepository()); - } - - private ClientRegistration googleClientRegistration() { - return CommonOAuth2Provider.GOOGLE.getBuilder("google") - .clientId("google-client-id") - .clientSecret("google-client-secret") - .build(); - } -} ----- - -[[jc-oauth2login-authorized-client]] -==== OAuth2AuthorizedClient / OAuth2AuthorizedClientService - -`OAuth2AuthorizedClient` is a representation of an Authorized Client. -A client is considered to be authorized when the end-user (Resource Owner) has granted authorization to the client to access its protected resources. - -`OAuth2AuthorizedClient` serves the purpose of associating an `OAuth2AccessToken` to a `ClientRegistration` (client) and resource owner, who is the `Principal` end-user that granted the authorization. - -The primary role of the `OAuth2AuthorizedClientService` is to manage `OAuth2AuthorizedClient` instances. -From a developer perspective, it provides the capability to lookup an `OAuth2AccessToken` associated with a client so that it may be used to initiate a request to a resource server. - -[NOTE] -Spring Boot 2.0 Auto-configuration registers an `OAuth2AuthorizedClientService` `@Bean` in the `ApplicationContext`. - -The developer may also register an `OAuth2AuthorizedClientService` `@Bean` in the `ApplicationContext` (overriding Spring Boot 2.0 Auto-configuration) in order to have the ability to lookup an `OAuth2AccessToken` associated with a specific `ClientRegistration` (client). - -The following listing shows an example: - -[source,java] ----- -@Controller -public class MainController { - - @Autowired - private OAuth2AuthorizedClientService authorizedClientService; - - @RequestMapping("/userinfo") - public String userinfo(OAuth2AuthenticationToken authentication) { - // authentication.getAuthorizedClientRegistrationId() returns the - // registrationId of the Client that was authorized during the Login flow - OAuth2AuthorizedClient authorizedClient = - this.authorizedClientService.loadAuthorizedClient( - authentication.getAuthorizedClientRegistrationId(), - authentication.getName()); - - OAuth2AccessToken accessToken = authorizedClient.getAccessToken(); - - ... - - return "userinfo"; - } -} ----- - - -[[jc-oauth2login-resources]] -==== Additional Resources - -The following additional resources describe advanced configuration options: - -* <> -* Authorization Endpoint: -** <> -* <> -* Token Endpoint: -** <> -* UserInfo Endpoint: -** <> -** <> -** <> -** <> - -[[jc-authentication]] -=== Authentication - -Thus far we have only taken a look at the most basic authentication configuration. -Let's take a look at a few slightly more advanced options for configuring authentication. - -[[jc-authentication-inmemory]] -==== In-Memory Authentication - -We have already seen an example of configuring in-memory authentication for a single user. -Below is an example to configure multiple users: - -[source,java] ----- -@Bean -public UserDetailsService userDetailsService() throws Exception { - // ensure the passwords are encoded properly - UserBuilder users = User.withDefaultPasswordEncoder(); - InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); - manager.createUser(users.username("user").password("password").roles("USER").build()); - manager.createUser(users.username("admin").password("password").roles("USER","ADMIN").build()); - return manager; -} ----- - -[[jc-authentication-jdbc]] -==== JDBC Authentication - -You can find the updates to support JDBC based authentication. -The example below assumes that you have already defined a `DataSource` within your application. -The https://github.com/spring-projects/spring-security/tree/master/samples/javaconfig/jdbc[jdbc-javaconfig] sample provides a complete example of using JDBC based authentication. - -[source,java] ----- -@Autowired -private DataSource dataSource; - -@Autowired -public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { - // ensure the passwords are encoded properly - UserBuilder users = User.withDefaultPasswordEncoder(); - auth - .jdbcAuthentication() - .dataSource(dataSource) - .withDefaultSchema() - .withUser(users.username("user").password("password").roles("USER")) - .withUser(users.username("admin").password("password").roles("USER","ADMIN")); -} ----- - -==== LDAP Authentication - -You can find the updates to support LDAP based authentication. -The https://github.com/spring-projects/spring-security/tree/master/samples/javaconfig/ldap[ldap-javaconfig] sample provides a complete example of using LDAP based authentication. - -[source,java] ----- -@Autowired -private DataSource dataSource; - -@Autowired -public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { - auth - .ldapAuthentication() - .userDnPatterns("uid={0},ou=people") - .groupSearchBase("ou=groups"); -} ----- - -The example above uses the following LDIF and an embedded Apache DS LDAP instance. - -.users.ldif ----- -dn: ou=groups,dc=springframework,dc=org -objectclass: top -objectclass: organizationalUnit -ou: groups - -dn: ou=people,dc=springframework,dc=org -objectclass: top -objectclass: organizationalUnit -ou: people - -dn: uid=admin,ou=people,dc=springframework,dc=org -objectclass: top -objectclass: person -objectclass: organizationalPerson -objectclass: inetOrgPerson -cn: Rod Johnson -sn: Johnson -uid: admin -userPassword: password - -dn: uid=user,ou=people,dc=springframework,dc=org -objectclass: top -objectclass: person -objectclass: organizationalPerson -objectclass: inetOrgPerson -cn: Dianne Emu -sn: Emu -uid: user -userPassword: password - -dn: cn=user,ou=groups,dc=springframework,dc=org -objectclass: top -objectclass: groupOfNames -cn: user -uniqueMember: uid=admin,ou=people,dc=springframework,dc=org -uniqueMember: uid=user,ou=people,dc=springframework,dc=org - -dn: cn=admin,ou=groups,dc=springframework,dc=org -objectclass: top -objectclass: groupOfNames -cn: admin -uniqueMember: uid=admin,ou=people,dc=springframework,dc=org ----- - -[[jc-authentication-authenticationprovider]] -==== AuthenticationProvider - -You can define custom authentication by exposing a custom `AuthenticationProvider` as a bean. -For example, the following will customize authentication assuming that `SpringAuthenticationProvider` implements `AuthenticationProvider`: - -NOTE: This is only used if the `AuthenticationManagerBuilder` has not been populated - -[source,java] ----- -@Bean -public SpringAuthenticationProvider springAuthenticationProvider() { - return new SpringAuthenticationProvider(); -} ----- - -[[jc-authentication-userdetailsservice]] -==== UserDetailsService - -You can define custom authentication by exposing a custom `UserDetailsService` as a bean. -For example, the following will customize authentication assuming that `SpringDataUserDetailsService` implements `UserDetailsService`: - -NOTE: This is only used if the `AuthenticationManagerBuilder` has not been populated and no `AuthenticationProviderBean` is defined. - -[source,java] ----- -@Bean -public SpringDataUserDetailsService springDataUserDetailsService() { - return new SpringDataUserDetailsService(); -} ----- - -You can also customize how passwords are encoded by exposing a `PasswordEncoder` as a bean. -For example, if you use bcrypt you can add a bean definition as shown below: - -[source,java] ----- -@Bean -public BCryptPasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); -} ----- - -=== Multiple HttpSecurity - -We can configure multiple HttpSecurity instances just as we can have multiple `` blocks. -The key is to extend the `WebSecurityConfigurationAdapter` multiple times. -For example, the following is an example of having a different configuration for URL's that start with `/api/`. - -[source,java] ----- -@EnableWebSecurity -public class MultiHttpSecurityConfig { - @Bean <1> - public UserDetailsService userDetailsService() throws Exception { - // ensure the passwords are encoded properly - UserBuilder users = User.withDefaultPasswordEncoder(); - InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); - manager.createUser(users.username("user").password("password").roles("USER").build()); - manager.createUser(users.username("admin").password("password").roles("USER","ADMIN").build()); - return manager; - } - - @Configuration - @Order(1) <2> - public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { - protected void configure(HttpSecurity http) throws Exception { - http - .antMatcher("/api/**") <3> - .authorizeRequests() - .anyRequest().hasRole("ADMIN") - .and() - .httpBasic(); - } - } - - @Configuration <4> - public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(HttpSecurity http) throws Exception { - http - .authorizeRequests() - .anyRequest().authenticated() - .and() - .formLogin(); - } - } -} ----- - -<1> Configure Authentication as normal -<2> Create an instance of `WebSecurityConfigurerAdapter` that contains `@Order` to specify which `WebSecurityConfigurerAdapter` should be considered first. -<3> The `http.antMatcher` states that this `HttpSecurity` will only be applicable to URLs that start with `/api/` -<4> Create another instance of `WebSecurityConfigurerAdapter`. -If the URL does not start with `/api/` this configuration will be used. -This configuration is considered after `ApiWebSecurityConfigurationAdapter` since it has an `@Order` value after `1` (no `@Order` defaults to last). - - -[[jc-method]] -=== Method Security - -From version 2.0 onwards Spring Security has improved support substantially for adding security to your service layer methods. -It provides support for JSR-250 annotation security as well as the framework's original `@Secured` annotation. -From 3.0 you can also make use of new <>. -You can apply security to a single bean, using the `intercept-methods` element to decorate the bean declaration, or you can secure multiple beans across the entire service layer using the AspectJ style pointcuts. - -==== EnableGlobalMethodSecurity - -We can enable annotation-based security using the `@EnableGlobalMethodSecurity` annotation on any `@Configuration` instance. -For example, the following would enable Spring Security's `@Secured` annotation. - -[source,java] ----- -@EnableGlobalMethodSecurity(securedEnabled = true) -public class MethodSecurityConfig { -// ... -} ----- - -Adding an annotation to a method (on a class or interface) would then limit the access to that method accordingly. -Spring Security's native annotation support defines a set of attributes for the method. -These will be passed to the AccessDecisionManager for it to make the actual decision: - -[source,java] ----- -public interface BankService { - -@Secured("IS_AUTHENTICATED_ANONYMOUSLY") -public Account readAccount(Long id); - -@Secured("IS_AUTHENTICATED_ANONYMOUSLY") -public Account[] findAccounts(); - -@Secured("ROLE_TELLER") -public Account post(Account account, double amount); -} ----- - -Support for JSR-250 annotations can be enabled using - -[source,java] ----- -@EnableGlobalMethodSecurity(jsr250Enabled = true) -public class MethodSecurityConfig { -// ... -} ----- - -These are standards-based and allow simple role-based constraints to be applied but do not have the power Spring Security's native annotations. -To use the new expression-based syntax, you would use - -[source,java] ----- -@EnableGlobalMethodSecurity(prePostEnabled = true) -public class MethodSecurityConfig { -// ... -} ----- - -and the equivalent Java code would be - -[source,java] ----- -public interface BankService { - -@PreAuthorize("isAnonymous()") -public Account readAccount(Long id); - -@PreAuthorize("isAnonymous()") -public Account[] findAccounts(); - -@PreAuthorize("hasAuthority('ROLE_TELLER')") -public Account post(Account account, double amount); -} ----- - -==== GlobalMethodSecurityConfiguration - -Sometimes you may need to perform operations that are more complicated than are possible with the `@EnableGlobalMethodSecurity` annotation allow. -For these instances, you can extend the `GlobalMethodSecurityConfiguration` ensuring that the `@EnableGlobalMethodSecurity` annotation is present on your subclass. -For example, if you wanted to provide a custom `MethodSecurityExpressionHandler`, you could use the following configuration: - -[source,java] ----- -@EnableGlobalMethodSecurity(prePostEnabled = true) -public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { - @Override - protected MethodSecurityExpressionHandler createExpressionHandler() { - // ... create and return custom MethodSecurityExpressionHandler ... - return expressionHandler; - } -} ----- - -For additional information about methods that can be overridden, refer to the `GlobalMethodSecurityConfiguration` Javadoc. - -[[jc-erms]] -==== EnableReactiveMethodSecurity - -Spring Security supports method security using https://projectreactor.io/docs/core/release/reference/#context[Reactor's Context] which is setup using `ReactiveSecurityContextHolder`. -For example, this demonstrates how to retrieve the currently logged in user's message. - -[NOTE] -==== -For this to work the return type of the method must be a `org.reactivestreams.Publisher` (i.e. `Mono`/`Flux`). -This is necessary to integrate with Reactor's `Context`. -==== - -[source,java] ----- -Authentication authentication = new TestingAuthenticationToken("user", "password", "ROLE_USER"); - -Mono messageByUsername = ReactiveSecurityContextHolder.getContext() - .map(SecurityContext::getAuthentication) - .map(Authentication::getName) - .flatMap(this::findMessageByUsername) - // In a WebFlux application the `subscriberContext` is automatically setup using `ReactorContextWebFilter` - .subscriberContext(ReactiveSecurityContextHolder.withAuthentication(authentication)); - -StepVerifier.create(messageByUsername) - .expectNext("Hi user") - .verifyComplete(); ----- - -with `this::findMessageByUsername` defined as: - -[source,java] ----- -Mono findMessageByUsername(String username) { - return Mono.just("Hi " + username); -} ----- - -Below is a minimal method security configuration when using method security in reactive applications. - -[source,java] ----- -@EnableReactiveMethodSecurity -public class SecurityConfig { - @Bean - public MapReactiveUserDetailsService userDetailsService() { - User.UserBuilder userBuilder = User.withDefaultPasswordEncoder(); - UserDetails rob = userBuilder.username("rob").password("rob").roles("USER").build(); - UserDetails admin = userBuilder.username("admin").password("admin").roles("USER","ADMIN").build(); - return new MapReactiveUserDetailsService(rob, admin); - } -} ----- - -Consider the following class: - -[source,java] ----- -@Component -public class HelloWorldMessageService { - @PreAuthorize("hasRole('ADMIN')") - public Mono findMessage() { - return Mono.just("Hello World!"); - } -} ----- - -Combined with our configuration above, `@PreAuthorize("hasRole('ADMIN')")` will ensure that `findByMessage` is only invoked by a user with the role `ADMIN`. -It is important to note that any of the expressions in standard method security work for `@EnableReactiveMethodSecurity`. -However, at this time we only support return type of `Boolean` or `boolean` of the expression. -This means that the expression must not block. - -When integrating with <>, the Reactor Context is automatically established by Spring Security according to the authenticated user. - -[source,java] ----- -@EnableWebFluxSecurity -@EnableReactiveMethodSecurity -public class SecurityConfig { - - @Bean - SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) throws Exception { - return http - // Demonstrate that method security works - // Best practice to use both for defense in depth - .authorizeExchange() - .anyExchange().permitAll() - .and() - .httpBasic().and() - .build(); - } - - @Bean - MapReactiveUserDetailsService userDetailsService() { - User.UserBuilder userBuilder = User.withDefaultPasswordEncoder(); - UserDetails rob = userBuilder.username("rob").password("rob").roles("USER").build(); - UserDetails admin = userBuilder.username("admin").password("admin").roles("USER","ADMIN").build(); - return new MapReactiveUserDetailsService(rob, admin); - } -} - ----- - -You can find a complete sample in {gh-samples-url}/javaconfig/hellowebflux-method[hellowebflux-method] - -=== Post Processing Configured Objects - -Spring Security's Java Configuration does not expose every property of every object that it configures. -This simplifies the configuration for a majority of users. -Afterall, if every property was exposed, users could use standard bean configuration. - -While there are good reasons to not directly expose every property, users may still need more advanced configuration options. -To address this Spring Security introduces the concept of an `ObjectPostProcessor` which can be used to modify or replace many of the Object instances created by the Java Configuration. -For example, if you wanted to configure the `filterSecurityPublishAuthorizationSuccess` property on `FilterSecurityInterceptor` you could use the following: - -[source,java] ----- -@Override -protected void configure(HttpSecurity http) throws Exception { - http - .authorizeRequests() - .anyRequest().authenticated() - .withObjectPostProcessor(new ObjectPostProcessor() { - public O postProcess( - O fsi) { - fsi.setPublishAuthorizationSuccess(true); - return fsi; - } - }); -} ----- - -[[jc-custom-dsls]] -=== Custom DSLs - -You can provide your own custom DSLs in Spring Security. -For example, you might have something that looks like this: - -[source,java] ----- -public class MyCustomDsl extends AbstractHttpConfigurer { - private boolean flag; - - @Override - public void init(H http) throws Exception { - // any method that adds another configurer - // must be done in the init method - http.csrf().disable(); - } - - @Override - public void configure(H http) throws Exception { - ApplicationContext context = http.getSharedObject(ApplicationContext.class); - - // here we lookup from the ApplicationContext. You can also just create a new instance. - MyFilter myFilter = context.getBean(MyFilter.class); - myFilter.setFlag(flag); - http.addFilterBefore(myFilter, UsernamePasswordAuthenticationFilter.class); - } - - public MyCustomDsl flag(boolean value) { - this.flag = value; - return this; - } - - public static MyCustomDsl customDsl() { - return new MyCustomDsl(); - } -} ----- - -NOTE: This is actually how methods like `HttpSecurity.authorizeRequests()` are implemented. - -The custom DSL can then be used like this: - -[source,java] ----- -@EnableWebSecurity -public class Config extends WebSecurityConfigurerAdapter { - @Override - protected void configure(HttpSecurity http) throws Exception { - http - .apply(customDsl()) - .flag(true) - .and() - ...; - } -} ----- - -The code is invoked in the following order: - -* Code in `Config`s configure method is invoked -* Code in `MyCustomDsl`s init method is invoked -* Code in `MyCustomDsl`s configure method is invoked - -If you want, you can have `WebSecurityConfiguerAdapter` add `MyCustomDsl` by default by using `SpringFactories`. -For example, you would create a resource on the classpath named `META-INF/spring.factories` with the following contents: - -.META-INF/spring.factories ----- -org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer = sample.MyCustomDsl ----- - -Users wishing to disable the default can do so explicitly. - -[source,java] ----- -@EnableWebSecurity -public class Config extends WebSecurityConfigurerAdapter { - @Override - protected void configure(HttpSecurity http) throws Exception { - http - .apply(customDsl()).disable() - ...; - } -} ----- - -[[ns-config]] -== Security Namespace Configuration - - -=== Introduction -Namespace configuration has been available since version 2.0 of the Spring Framework. -It allows you to supplement the traditional Spring beans application context syntax with elements from additional XML schema. -You can find more information in the Spring http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/[Reference Documentation]. -A namespace element can be used simply to allow a more concise way of configuring an individual bean or, more powerfully, to define an alternative configuration syntax which more closely matches the problem domain and hides the underlying complexity from the user. -A simple element may conceal the fact that multiple beans and processing steps are being added to the application context. -For example, adding the following element from the security namespace to an application context will start up an embedded LDAP server for testing use within the application: - -[source,xml] ----- - ----- - -This is much simpler than wiring up the equivalent Apache Directory Server beans. -The most common alternative configuration requirements are supported by attributes on the `ldap-server` element and the user is isolated from worrying about which beans they need to create and what the bean property names are. -footnote:[You can find out more about the use of the `ldap-server` element in the chapter on pass:specialcharacters,macros[<>].]. -Use of a good XML editor while editing the application context file should provide information on the attributes and elements that are available. -We would recommend that you try out the http://spring.io/tools/sts[Spring Tool Suite] as it has special features for working with standard Spring namespaces. - - -To start using the security namespace in your application context, you need to have the `spring-security-config` jar on your classpath. -Then all you need to do is add the schema declaration to your application context file: - -[source,xml] ----- - - ... - ----- - -In many of the examples you will see (and in the sample applications), we will often use "security" as the default namespace rather than "beans", which means we can omit the prefix on all the security namespace elements, making the content easier to read. -You may also want to do this if you have your application context divided up into separate files and have most of your security configuration in one of them. -Your security application context file would then start like this - -[source,xml] ----- - - ... - ----- - -We'll assume this syntax is being used from now on in this chapter. - - -==== Design of the Namespace -The namespace is designed to capture the most common uses of the framework and provide a simplified and concise syntax for enabling them within an application. -The design is based around the large-scale dependencies within the framework, and can be divided up into the following areas: - -* __Web/HTTP Security__ - the most complex part. -Sets up the filters and related service beans used to apply the framework authentication mechanisms, to secure URLs, render login and error pages and much more. - -* __Business Object (Method) Security__ - options for securing the service layer. - -* __AuthenticationManager__ - handles authentication requests from other parts of the framework. - -* __AccessDecisionManager__ - provides access decisions for web and method security. -A default one will be registered, but you can also choose to use a custom one, declared using normal Spring bean syntax. - -* __AuthenticationProvider__s - mechanisms against which the authentication manager authenticates users. -The namespace provides supports for several standard options and also a means of adding custom beans declared using a traditional syntax. - -* __UserDetailsService__ - closely related to authentication providers, but often also required by other beans. - -We'll see how to configure these in the following sections. - -[[ns-getting-started]] -=== Getting Started with Security Namespace Configuration -In this section, we'll look at how you can build up a namespace configuration to use some of the main features of the framework. -Let's assume you initially want to get up and running as quickly as possible and add authentication support and access control to an existing web application, with a few test logins. -Then we'll look at how to change over to authenticating against a database or other security repository. -In later sections we'll introduce more advanced namespace configuration options. - -[[ns-web-xml]] -==== web.xml Configuration -The first thing you need to do is add the following filter declaration to your `web.xml` file: - -[source,xml] ----- - -springSecurityFilterChain -org.springframework.web.filter.DelegatingFilterProxy - - - -springSecurityFilterChain -/* - ----- - -This provides a hook into the Spring Security web infrastructure. -`DelegatingFilterProxy` is a Spring Framework class which delegates to a filter implementation which is defined as a Spring bean in your application context. -In this case, the bean is named "springSecurityFilterChain", which is an internal infrastructure bean created by the namespace to handle web security. -Note that you should not use this bean name yourself. -Once you've added this to your `web.xml`, you're ready to start editing your application context file. -Web security services are configured using the `` element. - -[[ns-minimal]] -==== A Minimal Configuration -All you need to enable web security to begin with is - -[source,xml] ----- - - - - - ----- - -Which says that we want all URLs within our application to be secured, requiring the role `ROLE_USER` to access them, we want to log in to the application using a form with username and password, and that we want a logout URL registered which will allow us to log out of the application. -`` element is the parent for all web-related namespace functionality. -The `` element defines a `pattern` which is matched against the URLs of incoming requests using an ant path style syntax footnote:[See the section on pass:specialcharacters,macros[<>] in the Web Application Infrastructure chapter for more details on how matches are actually performed.]. -You can also use regular-expression matching as an alternative (see the namespace appendix for more details). -The `access` attribute defines the access requirements for requests matching the given pattern. -With the default configuration, this is typically a comma-separated list of roles, one of which a user must have to be allowed to make the request. -The prefix"ROLE_" is a marker which indicates that a simple comparison with the user's authorities should be made. -In other words, a normal role-based check should be used. -Access-control in Spring Security is not limited to the use of simple roles (hence the use of the prefix to differentiate between different types of security attributes). -We'll see later how the interpretation can vary footnote:[The interpretation of the comma-separated values in the `access` attribute depends on the implementation of the pass:specialcharacters,macros[<>] which is used. -In Spring Security 3.0, the attribute can also be populated with an pass:specialcharacters,macros[<>]. - - -[NOTE] -==== - -You can use multiple `` elements to define different access requirements for different sets of URLs, but they will be evaluated in the order listed and the first match will be used. -So you must put the most specific matches at the top. -You can also add a `method` attribute to limit the match to a particular HTTP method (`GET`, `POST`, `PUT` etc.). - -==== - -To add some users, you can define a set of test data directly in the namespace: - -[source,xml] ----- - - - - - - - - - ----- - -This is an example of a secure way of storing the same passwords. -The password is prefixed with `{bcrypt}` to instruct `DelegatingPasswordEncoder`, which supports any configured `PasswordEncoder` for matching, that the passwords are hashed using BCrypt: - -[source,xml] ----- - - - - - - - - - - ----- - - - -[subs="quotes"] -**** -If you are familiar with pre-namespace versions of the framework, you can probably already guess roughly what's going on here. -The `` element is responsible for creating a `FilterChainProxy` and the filter beans which it uses. -Common problems like incorrect filter ordering are no longer an issue as the filter positions are predefined. - -The `` element creates a `DaoAuthenticationProvider` bean and the `` element creates an `InMemoryDaoImpl`. -All `authentication-provider` elements must be children of the `` element, which creates a `ProviderManager` and registers the authentication providers with it. -You can find more detailed information on the beans that are created in the <>. -It's worth cross-checking this if you want to start understanding what the important classes in the framework are and how they are used, particularly if you want to customise things later. -**** - -The configuration above defines two users, their passwords and their roles within the application (which will be used for access control). -It is also possible to load user information from a standard properties file using the `properties` attribute on `user-service`. -See the section on <> for more details on the file format. -Using the `` element means that the user information will be used by the authentication manager to process authentication requests. -You can have multiple `` elements to define different authentication sources and each will be consulted in turn. - -At this point you should be able to start up your application and you will be required to log in to proceed. -Try it out, or try experimenting with the "tutorial" sample application that comes with the project. - - -[[ns-form-and-basic]] -==== Form and Basic Login Options -You might be wondering where the login form came from when you were prompted to log in, since we made no mention of any HTML files or JSPs. -In fact, since we didn't explicitly set a URL for the login page, Spring Security generates one automatically, based on the features that are enabled and using standard values for the URL which processes the submitted login, the default target URL the user will be sent to after logging in and so on. -However, the namespace offers plenty of support to allow you to customize these options. -For example, if you want to supply your own login page, you could use: - -[source,xml] ----- - - - - - ----- - -Also note that we've added an extra `intercept-url` element to say that any requests for the login page should be available to anonymous users footnote:[See the chapter on pass:specialcharacters,macros[<>]] and also the <> class for more details on how the value `IS_AUTHENTICATED_ANONYMOUSLY` is processed.]. -Otherwise the request would be matched by the pattern /** and it wouldn't be possible to access the login page itself! -This is a common configuration error and will result in an infinite loop in the application. -Spring Security will emit a warning in the log if your login page appears to be secured. -It is also possible to have all requests matching a particular pattern bypass the security filter chain completely, by defining a separate `http` element for the pattern like this: - - -[source,xml] ----- - - - - - - - ----- - -From Spring Security 3.1 it is now possible to use multiple `http` elements to define separate security filter chain configurations for different request patterns. -If the `pattern` attribute is omitted from an `http` element, it matches all requests. -Creating an unsecured pattern is a simple example of this syntax, where the pattern is mapped to an empty filter chain footnote:[The use of multiple `` elements is an important feature, allowing the namespace to simultaneously support both stateful and stateless paths within the same application, for example. -The previous syntax, using the attribute `filters="none"` on an `intercept-url` element is incompatible with this change and is no longer supported in 3.1.]. -We'll look at this new syntax in more detail in the chapter on the <>. - -It's important to realise that these unsecured requests will be completely oblivious to any Spring Security web-related configuration or additional attributes such as `requires-channel`, so you will not be able to access information on the current user or call secured methods during the request. -Use `access='IS_AUTHENTICATED_ANONYMOUSLY'` as an alternative if you still want the security filter chain to be applied. - -If you want to use basic authentication instead of form login, then change the configuration to - -[source,xml] ----- - - - - ----- - -Basic authentication will then take precedence and will be used to prompt for a login when a user attempts to access a protected resource. -Form login is still available in this configuration if you wish to use it, for example through a login form embedded in another web page. - -[[ns-form-target]] -===== Setting a Default Post-Login Destination -If a form login isn't prompted by an attempt to access a protected resource, the `default-target-url` option comes into play. -This is the URL the user will be taken to after successfully logging in, and defaults to "/". -You can also configure things so that the user __always__ ends up at this page (regardless of whether the login was "on-demand" or they explicitly chose to log in) by setting the `always-use-default-target` attribute to "true". -This is useful if your application always requires that the user starts at a "home" page, for example: - -[source,xml] ----- - - - - - ----- - -For even more control over the destination, you can use the `authentication-success-handler-ref` attribute as an alternative to `default-target-url`. -The referenced bean should be an instance of `AuthenticationSuccessHandler`. -You'll find more on this in the <> chapter and also in the namespace appendix, as well as information on how to customize the flow when authentication fails. - -[[ns-logout]] -==== Logout Handling -The `logout` element adds support for logging out by navigating to a particular URL. -The default logout URL is `/logout`, but you can set it to something else using the `logout-url` attribute. -More information on other available attributes may be found in the namespace appendix. - -[[ns-auth-providers]] -==== Using other Authentication Providers -In practice you will need a more scalable source of user information than a few names added to the application context file. -Most likely you will want to store your user information in something like a database or an LDAP server. -LDAP namespace configuration is dealt with in the <>, so we won't cover it here. -If you have a custom implementation of Spring Security's `UserDetailsService`, called "myUserDetailsService" in your application context, then you can authenticate against this using - -[source,xml] ----- - - - - - ----- - -If you want to use a database, then you can use - -[source,xml] ----- - - - - - ----- - -Where "securityDataSource" is the name of a `DataSource` bean in the application context, pointing at a database containing the standard Spring Security <>. -Alternatively, you could configure a Spring Security `JdbcDaoImpl` bean and point at that using the `user-service-ref` attribute: - -[source,xml] ----- - - - - - - - ----- - -You can also use standard `AuthenticationProvider` beans as follows - -[source,xml] ----- - - - - - ----- - -where `myAuthenticationProvider` is the name of a bean in your application context which implements `AuthenticationProvider`. -You can use multiple `authentication-provider` elements, in which case the providers will be queried in the order they are declared. -See <> for more information on how the Spring Security `AuthenticationManager` is configured using the namespace. - -[[ns-password-encoder]] -===== Adding a Password Encoder -Passwords should always be encoded using a secure hashing algorithm designed for the purpose (not a standard algorithm like SHA or MD5). -This is supported by the `` element. -With bcrypt encoded passwords, the original authentication provider configuration would look like this: - -[source,xml] ----- - - - - - - - - - - - - ----- - - - -bcrypt is a good choice for most cases, unless you have a legacy system which forces you to use a different algorithm. -If you are using a simple hashing algorithm or, even worse, storing plain text passwords, then you should consider migrating to a more secure option like bcrypt. - -[[ns-web-advanced]] -=== Advanced Web Features - -[[ns-remember-me]] -==== Remember-Me Authentication -See the separate <> for information on remember-me namespace configuration. - -[[ns-requires-channel]] -==== Adding HTTP/HTTPS Channel Security -If your application supports both HTTP and HTTPS, and you require that particular URLs can only be accessed over HTTPS, then this is directly supported using the `requires-channel` attribute on ``: - -[source,xml] ----- - - - -... - ----- - -With this configuration in place, if a user attempts to access anything matching the "/secure/**" pattern using HTTP, they will first be redirected to an HTTPS URL footnote:[For more details on how channel-processing is implemented, see the Javadoc for `ChannelProcessingFilter` and related classes.]. -The available options are "http", "https" or "any". -Using the value "any" means that either HTTP or HTTPS can be used. - -If your application uses non-standard ports for HTTP and/or HTTPS, you can specify a list of port mappings as follows: - -[source,xml] ----- - -... - - - - ----- - -Note that in order to be truly secure, an application should not use HTTP at all or switch between HTTP and HTTPS. -It should start in HTTPS (with the user entering an HTTPS URL) and use a secure connection throughout to avoid any possibility of man-in-the-middle attacks. - -[[ns-session-mgmt]] -==== Session Management - -===== Detecting Timeouts -You can configure Spring Security to detect the submission of an invalid session ID and redirect the user to an appropriate URL. -This is achieved through the `session-management` element: - -[source,xml] ----- - -... - - ----- - -Note that if you use this mechanism to detect session timeouts, it may falsely report an error if the user logs out and then logs back in without closing the browser. -This is because the session cookie is not cleared when you invalidate the session and will be resubmitted even if the user has logged out. -You may be able to explicitly delete the JSESSIONID cookie on logging out, for example by using the following syntax in the logout handler: - -[source,xml] ----- - - - ----- - -Unfortunately this can't be guaranteed to work with every servlet container, so you will need to test it in your environment - -[NOTE] -==== -If you are running your application behind a proxy, you may also be able to remove the session cookie by configuring the proxy server. -For example, using Apache HTTPD's mod_headers, the following directive would delete the `JSESSIONID` cookie by expiring it in the response to a logout request (assuming the application is deployed under the path `/tutorial`): - -[source,xml] ----- - -Header always set Set-Cookie "JSESSIONID=;Path=/tutorial;Expires=Thu, 01 Jan 1970 00:00:00 GMT" - ----- -==== - - -[[ns-concurrent-sessions]] -===== Concurrent Session Control -If you wish to place constraints on a single user's ability to log in to your application, Spring Security supports this out of the box with the following simple additions. -First you need to add the following listener to your `web.xml` file to keep Spring Security updated about session lifecycle events: - -[source,xml] ----- - - - org.springframework.security.web.session.HttpSessionEventPublisher - - ----- - -Then add the following lines to your application context: - -[source,xml] ----- - -... - - - - ----- - -This will prevent a user from logging in multiple times - a second login will cause the first to be invalidated. -Often you would prefer to prevent a second login, in which case you can use - -[source,xml] ----- - -... - - - - ----- - -The second login will then be rejected. -By "rejected", we mean that the user will be sent to the `authentication-failure-url` if form-based login is being used. -If the second authentication takes place through another non-interactive mechanism, such as "remember-me", an "unauthorized" (401) error will be sent to the client. -If instead you want to use an error page, you can add the attribute `session-authentication-error-url` to the `session-management` element. - -If you are using a customized authentication filter for form-based login, then you have to configure concurrent session control support explicitly. -More details can be found in the <>. - -[[ns-session-fixation]] -===== Session Fixation Attack Protection -http://en.wikipedia.org/wiki/Session_fixation[Session fixation] attacks are a potential risk where it is possible for a malicious attacker to create a session by accessing a site, then persuade another user to log in with the same session (by sending them a link containing the session identifier as a parameter, for example). -Spring Security protects against this automatically by creating a new session or otherwise changing the session ID when a user logs in. -If you don't require this protection, or it conflicts with some other requirement, you can control the behavior using the `session-fixation-protection` attribute on ``, which has four options - -* `none` - Don't do anything. -The original session will be retained. - -* `newSession` - Create a new "clean" session, without copying the existing session data (Spring Security-related attributes will still be copied). - -* `migrateSession` - Create a new session and copy all existing session attributes to the new session. -This is the default in Servlet 3.0 or older containers. - -* `changeSessionId` - Do not create a new session. -Instead, use the session fixation protection provided by the Servlet container (`HttpServletRequest#changeSessionId()`). -This option is only available in Servlet 3.1 (Java EE 7) and newer containers. -Specifying it in older containers will result in an exception. -This is the default in Servlet 3.1 and newer containers. - - -When session fixation protection occurs, it results in a `SessionFixationProtectionEvent` being published in the application context. -If you use `changeSessionId`, this protection will __also__ result in any `javax.servlet.http.HttpSessionIdListener` s being notified, so use caution if your code listens for both events. -See the <> chapter for additional information. - - -[[ns-openid]] -==== OpenID Support -The namespace supports http://openid.net/[OpenID] login either instead of, or in addition to normal form-based login, with a simple change: - -[source,xml] ----- - - - - ----- - -You should then register yourself with an OpenID provider (such as myopenid.com), and add the user information to your in-memory ``: - -[source,xml] ----- - ----- - -You should be able to login using the `myopenid.com` site to authenticate. -It is also possible to select a specific `UserDetailsService` bean for use OpenID by setting the `user-service-ref` attribute on the `openid-login` element. -See the previous section on <> for more information. -Note that we have omitted the password attribute from the above user configuration, since this set of user data is only being used to load the authorities for the user. -A random password will be generated internally, preventing you from accidentally using this user data as an authentication source elsewhere in your configuration. - - -===== Attribute Exchange -Support for OpenID http://openid.net/specs/openid-attribute-exchange-1_0.html[attribute exchange]. -As an example, the following configuration would attempt to retrieve the email and full name from the OpenID provider, for use by the application: - -[source,xml] ----- - - - - - - ----- - -The "type" of each OpenID attribute is a URI, determined by a particular schema, in this case http://axschema.org/[http://axschema.org/]. -If an attribute must be retrieved for successful authentication, the `required` attribute can be set. -The exact schema and attributes supported will depend on your OpenID provider. -The attribute values are returned as part of the authentication process and can be accessed afterwards using the following code: - -[source,java] ----- -OpenIDAuthenticationToken token = - (OpenIDAuthenticationToken)SecurityContextHolder.getContext().getAuthentication(); -List attributes = token.getAttributes(); ----- - -The `OpenIDAttribute` contains the attribute type and the retrieved value (or values in the case of multi-valued attributes). -We'll see more about how the `SecurityContextHolder` class is used when we look at core Spring Security components in the <> chapter. -Multiple attribute exchange configurations are also be supported, if you wish to use multiple identity providers. -You can supply multiple `attribute-exchange` elements, using an `identifier-matcher` attribute on each. -This contains a regular expression which will be matched against the OpenID identifier supplied by the user. -See the OpenID sample application in the codebase for an example configuration, providing different attribute lists for the Google, Yahoo and MyOpenID providers. - - -[[ns-headers]] -==== Response Headers -For additional information on how to customize the headers element refer to the <> section of the reference. - - -[[ns-custom-filters]] -==== Adding in Your Own Filters -If you've used Spring Security before, you'll know that the framework maintains a chain of filters in order to apply its services. -You may want to add your own filters to the stack at particular locations or use a Spring Security filter for which there isn't currently a namespace configuration option (CAS, for example). -Or you might want to use a customized version of a standard namespace filter, such as the `UsernamePasswordAuthenticationFilter` which is created by the `` element, taking advantage of some of the extra configuration options which are available by using the bean explicitly. -How can you do this with namespace configuration, since the filter chain is not directly exposed? - -The order of the filters is always strictly enforced when using the namespace. -When the application context is being created, the filter beans are sorted by the namespace handling code and the standard Spring Security filters each have an alias in the namespace and a well-known position. - -[NOTE] -==== -In previous versions, the sorting took place after the filter instances had been created, during post-processing of the application context. -In version 3.0+ the sorting is now done at the bean metadata level, before the classes have been instantiated. -This has implications for how you add your own filters to the stack as the entire filter list must be known during the parsing of the `` element, so the syntax has changed slightly in 3.0. -==== - -The filters, aliases and namespace elements/attributes which create the filters are shown in <>. -The filters are listed in the order in which they occur in the filter chain. - -[[filter-stack]] -.Standard Filter Aliases and Ordering -|=== -| Alias | Filter Class | Namespace Element or Attribute - -| CHANNEL_FILTER -| `ChannelProcessingFilter` -| `http/intercept-url@requires-channel` - -| SECURITY_CONTEXT_FILTER -| `SecurityContextPersistenceFilter` -| `http` - -| CONCURRENT_SESSION_FILTER -| `ConcurrentSessionFilter` -| `session-management/concurrency-control` - -| HEADERS_FILTER -| `HeaderWriterFilter` -| `http/headers` - -| CSRF_FILTER -| `CsrfFilter` -| `http/csrf` - -| LOGOUT_FILTER -| `LogoutFilter` -| `http/logout` - -| X509_FILTER -| `X509AuthenticationFilter` -| `http/x509` - -| PRE_AUTH_FILTER -| `AbstractPreAuthenticatedProcessingFilter` Subclasses -| N/A - -| CAS_FILTER -| `CasAuthenticationFilter` -| N/A - -| FORM_LOGIN_FILTER -| `UsernamePasswordAuthenticationFilter` -| `http/form-login` - -| BASIC_AUTH_FILTER -| `BasicAuthenticationFilter` -| `http/http-basic` - -| SERVLET_API_SUPPORT_FILTER -| `SecurityContextHolderAwareRequestFilter` -| `http/@servlet-api-provision` - -| JAAS_API_SUPPORT_FILTER -| `JaasApiIntegrationFilter` -| `http/@jaas-api-provision` - -| REMEMBER_ME_FILTER -| `RememberMeAuthenticationFilter` -| `http/remember-me` - -| ANONYMOUS_FILTER -| `AnonymousAuthenticationFilter` -| `http/anonymous` - -| SESSION_MANAGEMENT_FILTER -| `SessionManagementFilter` -| `session-management` - -| EXCEPTION_TRANSLATION_FILTER -| `ExceptionTranslationFilter` -| `http` - -| FILTER_SECURITY_INTERCEPTOR -| `FilterSecurityInterceptor` -| `http` - -| SWITCH_USER_FILTER -| `SwitchUserFilter` -| N/A -|=== - -You can add your own filter to the stack, using the `custom-filter` element and one of these names to specify the position your filter should appear at: - -[source,xml] ----- - - - - - ----- - -You can also use the `after` or `before` attributes if you want your filter to be inserted before or after another filter in the stack. -The names "FIRST" and "LAST" can be used with the `position` attribute to indicate that you want your filter to appear before or after the entire stack, respectively. - -.Avoiding filter position conflicts -[TIP] -==== - -If you are inserting a custom filter which may occupy the same position as one of the standard filters created by the namespace then it's important that you don't include the namespace versions by mistake. -Remove any elements which create filters whose functionality you want to replace. - -Note that you can't replace filters which are created by the use of the `` element itself - `SecurityContextPersistenceFilter`, `ExceptionTranslationFilter` or `FilterSecurityInterceptor`. -Some other filters are added by default, but you can disable them. -An `AnonymousAuthenticationFilter` is added by default and unless you have <> disabled, a `SessionManagementFilter` will also be added to the filter chain. - -==== - -If you're replacing a namespace filter which requires an authentication entry point (i.e. where the authentication process is triggered by an attempt by an unauthenticated user to access to a secured resource), you will need to add a custom entry point bean too. - - -[[ns-entry-point-ref]] -===== Setting a Custom AuthenticationEntryPoint -If you aren't using form login, OpenID or basic authentication through the namespace, you may want to define an authentication filter and entry point using a traditional bean syntax and link them into the namespace, as we've just seen. -The corresponding `AuthenticationEntryPoint` can be set using the `entry-point-ref` attribute on the `` element. - -The CAS sample application is a good example of the use of custom beans with the namespace, including this syntax. -If you aren't familiar with authentication entry points, they are discussed in the <> chapter. - - -[[ns-method-security]] -=== Method Security -From version 2.0 onwards Spring Security has improved support substantially for adding security to your service layer methods. -It provides support for JSR-250 annotation security as well as the framework's original `@Secured` annotation. -From 3.0 you can also make use of new <>. -You can apply security to a single bean, using the `intercept-methods` element to decorate the bean declaration, or you can secure multiple beans across the entire service layer using the AspectJ style pointcuts. - - -[[ns-global-method]] -==== The Element -This element is used to enable annotation-based security in your application (by setting the appropriate attributes on the element), and also to group together security pointcut declarations which will be applied across your entire application context. -You should only declare one `` element. -The following declaration would enable support for Spring Security's `@Secured`: - -[source,xml] ----- - ----- - -Adding an annotation to a method (on an class or interface) would then limit the access to that method accordingly. -Spring Security's native annotation support defines a set of attributes for the method. -These will be passed to the `AccessDecisionManager` for it to make the actual decision: - -[source,java] ----- -public interface BankService { - -@Secured("IS_AUTHENTICATED_ANONYMOUSLY") -public Account readAccount(Long id); - -@Secured("IS_AUTHENTICATED_ANONYMOUSLY") -public Account[] findAccounts(); - -@Secured("ROLE_TELLER") -public Account post(Account account, double amount); -} ----- - -Support for JSR-250 annotations can be enabled using - -[source,xml] ----- - ----- - -These are standards-based and allow simple role-based constraints to be applied but do not have the power Spring Security's native annotations. -To use the new expression-based syntax, you would use - -[source,xml] ----- - ----- - -and the equivalent Java code would be - -[source,java] ----- -public interface BankService { - -@PreAuthorize("isAnonymous()") -public Account readAccount(Long id); - -@PreAuthorize("isAnonymous()") -public Account[] findAccounts(); - -@PreAuthorize("hasAuthority('ROLE_TELLER')") -public Account post(Account account, double amount); -} ----- - -Expression-based annotations are a good choice if you need to define simple rules that go beyond checking the role names against the user's list of authorities. - -[NOTE] -==== -The annotated methods will only be secured for instances which are defined as Spring beans (in the same application context in which method-security is enabled). -If you want to secure instances which are not created by Spring (using the `new` operator, for example) then you need to use AspectJ. -==== - -[NOTE] -==== -You can enable more than one type of annotation in the same application, but only one type should be used for any interface or class as the behaviour will not be well-defined otherwise. -If two annotations are found which apply to a particular method, then only one of them will be applied. -==== - -[[ns-protect-pointcut]] -===== Adding Security Pointcuts using protect-pointcut - -The use of `protect-pointcut` is particularly powerful, as it allows you to apply security to many beans with only a simple declaration. -Consider the following example: - -[source,xml] ----- - - - ----- - -This will protect all methods on beans declared in the application context whose classes are in the `com.mycompany` package and whose class names end in "Service". -Only users with the `ROLE_USER` role will be able to invoke these methods. -As with URL matching, the most specific matches must come first in the list of pointcuts, as the first matching expression will be used. -Security annotations take precedence over pointcuts. - -[[ns-access-manager]] -=== The Default AccessDecisionManager -This section assumes you have some knowledge of the underlying architecture for access-control within Spring Security. -If you don't you can skip it and come back to it later, as this section is only really relevant for people who need to do some customization in order to use more than simple role-based security. - -When you use a namespace configuration, a default instance of `AccessDecisionManager` is automatically registered for you and will be used for making access decisions for method invocations and web URL access, based on the access attributes you specify in your `intercept-url` and `protect-pointcut` declarations (and in annotations if you are using annotation secured methods). - -The default strategy is to use an `AffirmativeBased` `AccessDecisionManager` with a `RoleVoter` and an `AuthenticatedVoter`. -You can find out more about these in the chapter on <>. - - -[[ns-custom-access-mgr]] -==== Customizing the AccessDecisionManager -If you need to use a more complicated access control strategy then it is easy to set an alternative for both method and web security. - -For method security, you do this by setting the `access-decision-manager-ref` attribute on `global-method-security` to the `id` of the appropriate `AccessDecisionManager` bean in the application context: - -[source,xml] ----- - -... - ----- - -The syntax for web security is the same, but on the `http` element: - -[source,xml] ----- - -... - ----- - -[[ns-auth-manager]] -=== The Authentication Manager and the Namespace -The main interface which provides authentication services in Spring Security is the `AuthenticationManager`. -This is usually an instance of Spring Security's `ProviderManager` class, which you may already be familiar with if you've used the framework before. -If not, it will be covered later, in the <>. -The bean instance is registered using the `authentication-manager` namespace element. -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 `AuthenticationProvider` s that are used. - -You may want to register additional `AuthenticationProvider` beans with the `ProviderManager` and you can do this using the `` element with the `ref` attribute, where the value of the attribute is the name of the provider bean you want to add. -For example: - -[source,xml] ----- - - - - - -... - ----- - -Another common requirement is that another bean in the context may require a reference to the `AuthenticationManager`. -You can easily register an alias for the `AuthenticationManager` and use this name elsewhere in your application context. - -[source,xml] ----- - -... - - - - -... - ----- - -[[sample-apps]] -== Sample Applications -There are several sample web applications that are available with the project. -To avoid an overly large download, only the "tutorial" and "contacts" samples are included in the distribution zip file. -The others can be built directly from the source which you can obtain as described in <>. -It's easy to build the project yourself and there's more information on the project web site at http://spring.io/spring-security/[http://spring.io/spring-security/]. -All paths referred to in this chapter are relative to the project source directory. - - -[[tutorial-sample]] -=== Tutorial Sample -The tutorial sample is a nice basic example to get you started. -It uses simple namespace configuration throughout. -The compiled application is included in the distribution zip file, ready to be deployed into your web container (`spring-security-samples-tutorial-3.1.x.war`). -The <> authentication mechanism is used in combination with the commonly-used <> authentication provider to automatically remember the login using cookies. - -We recommend you start with the tutorial sample, as the XML is minimal and easy to follow. -Most importantly, you can easily add this one XML file (and its corresponding `web.xml` entries) to your existing application. -Only when this basic integration is achieved do we suggest you attempt adding in method authorization or domain object security. - - -[[contacts-sample]] -=== Contacts -The Contacts Sample is an advanced example in that it illustrates the more powerful features of domain object access control lists (ACLs) in addition to basic application security. -The application provides an interface with which the users are able to administer a simple database of contacts (the domain objects). - -To deploy, simply copy the WAR file from Spring Security distribution into your container's `webapps` directory. -The war should be called `spring-security-samples-contacts-3.1.x.war` (the appended version number will vary depending on what release you are using). - -After starting your container, check the application can load. -Visit http://localhost:8080/contacts (or whichever URL is appropriate for your web container and the WAR you deployed). - -Next, click "Debug". -You will be prompted to authenticate, and a series of usernames and passwords are suggested on that page. -Simply authenticate with any of these and view the resulting page. -It should contain a success message similar to the following: ----- - -Security Debug Information - -Authentication object is of type: -org.springframework.security.authentication.UsernamePasswordAuthenticationToken - -Authentication object as a String: - -org.springframework.security.authentication.UsernamePasswordAuthenticationToken@1f127853: -Principal: org.springframework.security.core.userdetails.User@b07ed00: Username: rod; \ -Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; -credentialsNonExpired: true; AccountNonLocked: true; \ -Granted Authorities: ROLE_SUPERVISOR, ROLE_USER; \ -Password: [PROTECTED]; Authenticated: true; \ -Details: org.springframework.security.web.authentication.WebAuthenticationDetails@0: \ -RemoteIpAddress: 127.0.0.1; SessionId: 8fkp8t83ohar; \ -Granted Authorities: ROLE_SUPERVISOR, ROLE_USER - -Authentication object holds the following granted authorities: - -ROLE_SUPERVISOR (getAuthority(): ROLE_SUPERVISOR) -ROLE_USER (getAuthority(): ROLE_USER) - -Success! Your web filters appear to be properly configured! - ----- - - -Once you successfully receive the above message, return to the sample application's home page and click "Manage". -You can then try out the application. -Notice that only the contacts available to the currently logged on user are displayed, and only users with `ROLE_SUPERVISOR` are granted access to delete their contacts. -Behind the scenes, the `MethodSecurityInterceptor` is securing the business objects. - -The application allows you to modify the access control lists associated with different contacts. -Be sure to give this a try and understand how it works by reviewing the application context XML files. - - -[[ldap-sample]] -=== LDAP Sample -The LDAP sample application provides a basic configuration and sets up both a namespace configuration and an equivalent configuration using traditional beans, both in the same application context file. -This means there are actually two identical authentication providers configured in this application. - - -[[openid-sample]] -=== OpenID Sample -The OpenID sample demonstrates how to use the namespace to configure OpenID and how to set up http://openid.net/specs/openid-attribute-exchange-1_0.html[attribute exchange] configurations for Google, Yahoo and MyOpenID identity providers (you can experiment with adding others if you wish). -It uses the JQuery-based http://code.google.com/p/openid-selector/[openid-selector] project to provide a user-friendly login page which allows the user to easily select a provider, rather than typing in the full OpenID identifier. - -The application differs from normal authentication scenarios in that it allows any user to access the site (provided their OpenID authentication is successful). -The first time you login, you will get a "Welcome [your name]"" message. -If you logout and log back in (with the same OpenID identity) then this should change to "Welcome Back". -This is achieved by using a custom `UserDetailsService` which assigns a standard role to any user and stores the identities internally in a map. -Obviously a real application would use a database instead. -Have a look at the source form more information. -This class also takes into account the fact that different attributes may be returned from different providers and builds the name with which it addresses the user accordingly. - - -[[cas-sample]] -=== CAS Sample -The CAS sample requires that you run both a CAS server and CAS client. -It isn't included in the distribution so you should check out the project code as described in <>. -You'll find the relevant files under the `sample/cas` directory. -There's also a `Readme.txt` file in there which explains how to run both the server and the client directly from the source tree, complete with SSL support. - - -[[jaas-sample]] -=== JAAS Sample -The JAAS sample is very simple example of how to use a JAAS LoginModule with Spring Security. -The provided LoginModule will successfully authenticate a user if the username equals the password otherwise a LoginException is thrown. -The AuthorityGranter used in this example always grants the role ROLE_USER. -The sample application also demonstrates how to run as the JAAS Subject returned by the LoginModule by setting <> equal to "true". - - -[[preauth-sample]] -=== Pre-Authentication Sample -This sample application demonstrates how to wire up beans from the <> framework to make use of login information from a Java EE container. -The user name and roles are those setup by the container. - -The code is in `samples/preauth`. - - -[[community]] -== Spring Security Community - - -[[jira]] -=== Issue Tracking -Spring Security uses JIRA to manage bug reports and enhancement requests. -If you find a bug, please log a report using JIRA. -Do not log it on the support forum, mailing list or by emailing the project's developers. -Such approaches are ad-hoc and we prefer to manage bugs using a more formal process. - -If possible, in your issue report please provide a JUnit test that demonstrates any incorrect behaviour. -Or, better yet, provide a patch that corrects the issue. -Similarly, enhancements are welcome to be logged in the issue tracker, although we only accept enhancement requests if you include corresponding unit tests. -This is necessary to ensure project test coverage is adequately maintained. - -You can access the issue tracker at https://github.com/spring-projects/spring-security/issues. - - -[[becoming-involved]] -=== Becoming Involved -We welcome your involvement in the Spring Security project. -There are many ways of contributing, including reading the forum and responding to questions from other people, writing new code, improving existing code, assisting with documentation, developing samples or tutorials, or simply making suggestions. - - -[[further-info]] -=== Further Information -Questions and comments on Spring Security are welcome. -You can use the Spring at Stack Overflow web site at http://spring.io/questions[http://spring.io/questions] to discuss Spring Security with other users of the framework. -Remember to use JIRA for bug reports, as explained above. diff --git a/docs/manual/src/docs/asciidoc/_includes/preface/community.adoc b/docs/manual/src/docs/asciidoc/_includes/preface/community.adoc new file mode 100644 index 0000000000..aeff291508 --- /dev/null +++ b/docs/manual/src/docs/asciidoc/_includes/preface/community.adoc @@ -0,0 +1,31 @@ + +[[community]] +== Spring Security Community + + +[[jira]] +=== Issue Tracking +Spring Security uses JIRA to manage bug reports and enhancement requests. +If you find a bug, please log a report using JIRA. +Do not log it on the support forum, mailing list or by emailing the project's developers. +Such approaches are ad-hoc and we prefer to manage bugs using a more formal process. + +If possible, in your issue report please provide a JUnit test that demonstrates any incorrect behaviour. +Or, better yet, provide a patch that corrects the issue. +Similarly, enhancements are welcome to be logged in the issue tracker, although we only accept enhancement requests if you include corresponding unit tests. +This is necessary to ensure project test coverage is adequately maintained. + +You can access the issue tracker at https://github.com/spring-projects/spring-security/issues. + + +[[becoming-involved]] +=== Becoming Involved +We welcome your involvement in the Spring Security project. +There are many ways of contributing, including reading the forum and responding to questions from other people, writing new code, improving existing code, assisting with documentation, developing samples or tutorials, or simply making suggestions. + + +[[further-info]] +=== Further Information +Questions and comments on Spring Security are welcome. +You can use the Spring at Stack Overflow web site at http://spring.io/questions[http://spring.io/questions] to discuss Spring Security with other users of the framework. +Remember to use JIRA for bug reports, as explained above. diff --git a/docs/manual/src/docs/asciidoc/_includes/preface/getting-started.adoc b/docs/manual/src/docs/asciidoc/_includes/preface/getting-started.adoc new file mode 100644 index 0000000000..fc846a3abd --- /dev/null +++ b/docs/manual/src/docs/asciidoc/_includes/preface/getting-started.adoc @@ -0,0 +1,13 @@ + +[[getting-started]] +== Getting Started +The later parts of this guide provide an in-depth discussion of the framework architecture and implementation classes, which you need to understand if you want to do any serious customization. +In this part, we'll introduce Spring Security 4. +0, give a brief overview of the project's history and take a slightly gentler look at how to get started using the framework. +In particular, we'll look at namespace configuration which provides a much simpler way of securing your application compared to the traditional Spring bean approach where you have to wire up all the implementation classes individually. + +We'll also take a look at the sample applications that are available. +It's worth trying to run these and experimenting with them a bit even before you read the later sections - you can dip back into them as your understanding of the framework increases. +Please also check out the http://spring. +io/spring-security[project website] as it has useful information on building the project, plus links to articles, videos and tutorials. + diff --git a/docs/manual/src/docs/asciidoc/_includes/preface/guides.adoc b/docs/manual/src/docs/asciidoc/_includes/preface/guides.adoc new file mode 100644 index 0000000000..8749067886 --- /dev/null +++ b/docs/manual/src/docs/asciidoc/_includes/preface/guides.adoc @@ -0,0 +1,34 @@ +[[samples]] +== Samples and Guides (Start Here) + +If you are looking to get started with Spring Security, the best place to start is our Sample Applications. + +.Sample Applications +|=== +| Source | Description | Guide + +| {gh-samples-url}/javaconfig/helloworld[Hello Spring Security] +| Demonstrates how to integrate Spring Security with an existing application using Java-based configuration. +| link:../../guides/html5/helloworld-javaconfig.html[Hello Spring Security Guide] + +| {gh-samples-url}/boot/helloworld[Hello Spring Security Boot] +| Demonstrates how to integrate Spring Security with an existing Spring Boot application. +| link:../../guides/html5/helloworld-boot.html[Hello Spring Security Boot Guide] + +| {gh-samples-url}/xml/helloworld[Hello Spring Security XML] +| Demonstrates how to integrate Spring Security with an existing application using XML-based configuration. +| link:../../guides/html5/helloworld-xml.html[Hello Spring Security XML Guide] + +| {gh-samples-url}/javaconfig/hellomvc[Hello Spring MVC Security] +| Demonstrates how to integrate Spring Security with an existing Spring MVC application. +| link:../../guides/html5/hellomvc-javaconfig.html[Hello Spring MVC Security Guide] + +| {gh-samples-url}/javaconfig/form[Custom Login Form] +| Demonstrates how to create a custom login form. +| link:../../guides/html5/form-javaconfig.html[Custom Login Form Guide] + +| {gh-samples-url}/boot/oauth2login[OAuth 2.0 Login] +| Demonstrates how to integrate OAuth 2.0 Login with an OAuth 2.0 or OpenID Connect 1.0 Provider. +| link:{gh-samples-url}/boot/oauth2login/README.adoc[OAuth 2.0 Login Guide] + +|=== diff --git a/docs/manual/src/docs/asciidoc/_includes/preface/index.adoc b/docs/manual/src/docs/asciidoc/_includes/preface/index.adoc new file mode 100644 index 0000000000..3bfd696d32 --- /dev/null +++ b/docs/manual/src/docs/asciidoc/_includes/preface/index.adoc @@ -0,0 +1,58 @@ +[[preface]] += Preface +Spring Security provides a comprehensive security solution for Java EE-based enterprise software applications. +As you will discover as you venture through this reference guide, we have tried to provide you a useful and highly configurable security system. + +Security is an ever-moving target, and it's important to pursue a comprehensive, system-wide approach. +In security circles we encourage you to adopt "layers of security", so that each layer tries to be as secure as possible in its own right, with successive layers providing additional security. +The "tighter" the security of each layer, the more robust and safe your application will be. +At the bottom level you'll need to deal with issues such as transport security and system identification, in order to mitigate man-in-the-middle attacks. +Next you'll generally utilise firewalls, perhaps with VPNs or IP security to ensure only authorised systems can attempt to connect. +In corporate environments you may deploy a DMZ to separate public-facing servers from backend database and application servers. +Your operating system will also play a critical part, addressing issues such as running processes as non-privileged users and maximising file system security. +An operating system will usually also be configured with its own firewall. +Hopefully somewhere along the way you'll be trying to prevent denial of service and brute force attacks against the system. +An intrusion detection system will also be especially useful for monitoring and responding to attacks, with such systems able to take protective action such as blocking offending TCP/IP addresses in real-time. +Moving to the higher layers, your Java Virtual Machine will hopefully be configured to minimize the permissions granted to different Java types, and then your application will add its own problem domain-specific security configuration. +Spring Security makes this latter area - application security - much easier. + +Of course, you will need to properly address all security layers mentioned above, together with managerial factors that encompass every layer. +A non-exhaustive list of such managerial factors would include security bulletin monitoring, patching, personnel vetting, audits, change control, engineering management systems, data backup, disaster recovery, performance benchmarking, load monitoring, centralised logging, incident response procedures etc. + +With Spring Security being focused on helping you with the enterprise application security layer, you will find that there are as many different requirements as there are business problem domains. +A banking application has different needs from an ecommerce application. +An ecommerce application has different needs from a corporate sales force automation tool. +These custom requirements make application security interesting, challenging and rewarding. + +Please read <>, in its entirety to begin with. +This will introduce you to the framework and the namespace-based configuration system with which you can get up and running quite quickly. +To get more of an understanding of how Spring Security works, and some of the classes you might need to use, you should then read <>. +The remaining parts of this guide are structured in a more traditional reference style, designed to be read on an as-required basis. +We'd also recommend that you read up as much as possible on application security issues in general. +Spring Security is not a panacea which will solve all security issues. +It is important that the application is designed with security in mind from the start. +Attempting to retrofit it is not a good idea. +In particular, if you are building a web application, you should be aware of the many potential vulnerabilities such as cross-site scripting, request-forgery and session-hijacking which you should be taking into account from the start. +The OWASP web site (http://www. +owasp. +org/) maintains a top ten list of web application vulnerabilities as well as a lot of useful reference information. + +We hope that you find this reference guide useful, and we welcome your feedback and <>. + +Finally, welcome to the Spring Security <>. + +include::getting-started.adoc[] + +include::introduction.adoc[] + +include::whats-new.adoc[] + +include::guides.adoc[] + +include::java-configuration.adoc[] + +include::namespace.adoc[] + +include::samples.adoc[] + +include::community.adoc[] diff --git a/docs/manual/src/docs/asciidoc/_includes/preface/introduction.adoc b/docs/manual/src/docs/asciidoc/_includes/preface/introduction.adoc new file mode 100644 index 0000000000..56f293c639 --- /dev/null +++ b/docs/manual/src/docs/asciidoc/_includes/preface/introduction.adoc @@ -0,0 +1,448 @@ + + +[[introduction]] +== Introduction + + +[[what-is-acegi-security]] +=== What is Spring Security? +Spring Security provides comprehensive security services for Java EE-based enterprise software applications. +There is a particular emphasis on supporting projects built using The Spring Framework, which is the leading Java EE solution for enterprise software development. +If you're not using Spring for developing enterprise applications, we warmly encourage you to take a closer look at it. +Some familiarity with Spring - and in particular dependency injection principles - will help you get up to speed with Spring Security more easily. + +People use Spring Security for many reasons, but most are drawn to the project after finding the security features of Java EE's Servlet Specification or EJB Specification lack the depth required for typical enterprise application scenarios. +Whilst mentioning these standards, it's important to recognise that they are not portable at a WAR or EAR level. +Therefore, if you switch server environments, it is typically a lot of work to reconfigure your application's security in the new target environment. +Using Spring Security overcomes these problems, and also brings you dozens of other useful, customisable security features. + +As you probably know two major areas of application security are "authentication" and "authorization" (or "access-control"). +These are the two main areas that Spring Security targets. +"Authentication" is the process of establishing a principal is who they claim to be (a "principal" generally means a user, device or some other system which can perform an action in your application). +"Authorization" refers to the process of deciding whether a principal is allowed to perform an action within your application. +To arrive at the point where an authorization decision is needed, the identity of the principal has already been established by the authentication process. +These concepts are common, and not at all specific to Spring Security. + +At an authentication level, Spring Security supports a wide range of authentication models. +Most of these authentication models are either provided by third parties, or are developed by relevant standards bodies such as the Internet Engineering Task Force. +In addition, Spring Security provides its own set of authentication features. +Specifically, Spring Security currently supports authentication integration with all of these technologies: + + +* HTTP BASIC authentication headers (an IETF RFC-based standard) + +* HTTP Digest authentication headers (an IETF RFC-based standard) + +* HTTP X.509 client certificate exchange (an IETF RFC-based standard) + +* LDAP (a very common approach to cross-platform authentication needs, especially in large environments) + +* Form-based authentication (for simple user interface needs) + +* OpenID authentication + +* Authentication based on pre-established request headers (such as Computer Associates Siteminder) + +* Jasig Central Authentication Service (otherwise known as CAS, which is a popular open source single sign-on system) + +* Transparent authentication context propagation for Remote Method Invocation (RMI) and HttpInvoker (a Spring remoting protocol) + +* Automatic "remember-me" authentication (so you can tick a box to avoid re-authentication for a predetermined period of time) + +* Anonymous authentication (allowing every unauthenticated call to automatically assume a particular security identity) + +* Run-as authentication (which is useful if one call should proceed with a different security identity) + +* Java Authentication and Authorization Service (JAAS) + +* Java EE container authentication (so you can still use Container Managed Authentication if desired) + +* Kerberos + +* Java Open Source Single Sign-On (JOSSO) * + +* OpenNMS Network Management Platform * + +* AppFuse * + +* AndroMDA * + +* Mule ESB * + +* Direct Web Request (DWR) * + +* Grails * + +* Tapestry * + +* JTrac * + +* Jasypt * + +* Roller * + +* Elastic Path * + +* Atlassian Crowd * + +* Your own authentication systems (see below) + + + +(* Denotes provided by a third party) + +Many independent software vendors (ISVs) adopt Spring Security because of this significant choice of flexible authentication models. +Doing so allows them to quickly integrate their solutions with whatever their end clients need, without undertaking a lot of engineering or requiring the client to change their environment. +If none of the above authentication mechanisms suit your needs, Spring Security is an open platform and it is quite simple to write your own authentication mechanism. +Many corporate users of Spring Security need to integrate with "legacy" systems that don't follow any particular security standards, and Spring Security is happy to "play nicely" with such systems. + +Irrespective of the authentication mechanism, Spring Security provides a deep set of authorization capabilities. +There are three main areas of interest: authorizing web requests, authorizing whether methods can be invoked and authorizing access to individual domain object instances. +To help you understand the differences, consider the authorization capabilities found in the Servlet Specification web pattern security, EJB Container Managed Security and file system security respectively. +Spring Security provides deep capabilities in all of these important areas, which we'll explore later in this reference guide. + + +[[history]] +=== History +Spring Security began in late 2003 as "The Acegi Security System for Spring". +A question was posed on the Spring Developers' mailing list asking whether there had been any consideration given to a Spring-based security implementation. +At the time the Spring community was relatively small (especially compared with the size today!), and indeed Spring itself had only existed as a SourceForge project from early 2003. +The response to the question was that it was a worthwhile area, although a lack of time currently prevented its exploration. + +With that in mind, a simple security implementation was built and not released. +A few weeks later another member of the Spring community inquired about security, and at the time this code was offered to them. +Several other requests followed, and by January 2004 around twenty people were using the code. +These pioneering users were joined by others who suggested a SourceForge project was in order, which was duly established in March 2004. + +In those early days, the project didn't have any of its own authentication modules. +Container Managed Security was relied upon for the authentication process, with Acegi Security instead focusing on authorization. +This was suitable at first, but as more and more users requested additional container support, the fundamental limitation of container-specific authentication realm interfaces became clear. +There was also a related issue of adding new JARs to the container's classpath, which was a common source of end user confusion and misconfiguration. + +Acegi Security-specific authentication services were subsequently introduced. +Around a year later, Acegi Security became an official Spring Framework subproject. +The 1. +0. +0 final release was published in May 2006 - after more than two and a half years of active use in numerous production software projects and many hundreds of improvements and community contributions. + +Acegi Security became an official Spring Portfolio project towards the end of 2007 and was rebranded as "Spring Security". + +Today Spring Security enjoys a strong and active open source community. +There are thousands of messages about Spring Security on the support forums. +There is an active core of developers who work on the code itself and an active community which also regularly share patches and support their peers. + + +[[release-numbering]] +=== Release Numbering +It is useful to understand how Spring Security release numbers work, as it will help you identify the effort (or lack thereof) involved in migrating to future releases of the project. +Each release uses a standard triplet of integers: MAJOR.MINOR.PATCH. +The intent is that MAJOR versions are incompatible, large-scale upgrades of the API. +MINOR versions should largely retain source and binary compatibility with older minor versions, thought there may be some design changes and incompatible updates. +PATCH level should be perfectly compatible, forwards and backwards, with the possible exception of changes which are to fix bugs and defects. + +The extent to which you are affected by changes will depend on how tightly integrated your code is. +If you are doing a lot of customization you are more likely to be affected than if you are using a simple namespace configuration. + +You should always test your application thoroughly before rolling out a new version. + + +[[get-spring-security]] +=== Getting Spring Security +You can get hold of Spring Security in several ways. +You can download a packaged distribution from the main http://spring. +io/spring-security[Spring Security] page, download individual jars from the Maven Central repository (or a Spring Maven repository for snapshot and milestone releases) or, alternatively, you can build the project from source yourself. + +[[maven]] +==== Usage with Maven + +A minimal Spring Security Maven set of dependencies typically looks like the following: + +.pom.xml +[source,xml] +[subs="verbatim,attributes"] +---- + + + + org.springframework.security + spring-security-web + {spring-security-version} + + + org.springframework.security + spring-security-config + {spring-security-version} + + +---- + +If you are using additional features like LDAP, OpenID, etc. you will need to also include the appropriate <>. + +[[maven-repositories]] +===== Maven Repositories +All GA releases (i.e. versions ending in .RELEASE) are deployed to Maven Central, so no additional Maven repositories need to be declared in your pom. + +If you are using a SNAPSHOT version, you will need to ensure you have the Spring Snapshot repository defined as shown below: + +.pom.xml +[source,xml] +---- + + + + spring-snapshot + Spring Snapshot Repository + http://repo.spring.io/snapshot + + +---- + +If you are using a milestone or release candidate version, you will need to ensure you have the Spring Milestone repository defined as shown below: + +.pom.xml +[source,xml] +---- + + + + spring-milestone + Spring Milestone Repository + http://repo.spring.io/milestone + + +---- + +[[maven-bom]] +===== Spring Framework Bom + +Spring Security builds against Spring Framework {spring-version}, but should work with 4.0.x. +The problem that many users will have is that Spring Security's transitive dependencies resolve Spring Framework {spring-version} which can cause strange classpath problems. + +One (tedious) way to circumvent this issue would be to include all the Spring Framework modules in a http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Management[] section of your pom. +An alternative approach is to include the `spring-framework-bom` within your `` section of your `pom.xml` as shown below: + +.pom.xml +[source,xml] +[subs="verbatim,attributes"] +---- + + + + org.springframework + spring-framework-bom + {spring-version} + pom + import + + + +---- + +This will ensure that all the transitive dependencies of Spring Security use the Spring {spring-version} modules. + +NOTE: This approach uses Maven's "bill of materials" (BOM) concept and is only available in Maven 2.0.9+. +For additional details about how dependencies are resolved refer to http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html[Maven's Introduction to the Dependency Mechanism documentation]. + +[[gradle]] +==== Gradle +A minimal Spring Security Gradle set of dependencies typically looks like the following: + +.build.gradle +[source,groovy] +[subs="verbatim,attributes"] +---- +dependencies { + compile 'org.springframework.security:spring-security-web:{spring-security-version}' + compile 'org.springframework.security:spring-security-config:{spring-security-version}' +} +---- + +If you are using additional features like LDAP, OpenID, etc. you will need to also include the appropriate <>. + +[[gradle-repositories]] +===== Gradle Repositories +All GA releases (i.e. versions ending in .RELEASE) are deployed to Maven Central, so using the mavenCentral() repository is sufficient for GA releases. + +.build.gradle +[source,groovy] +---- +repositories { + mavenCentral() +} +---- + +If you are using a SNAPSHOT version, you will need to ensure you have the Spring Snapshot repository defined as shown below: + +.build.gradle +[source,groovy] +---- +repositories { + maven { url 'https://repo.spring.io/snapshot' } +} +---- + +If you are using a milestone or release candidate version, you will need to ensure you have the Spring Milestone repository defined as shown below: + +.build.gradle +[source,groovy] +---- +repositories { + maven { url 'https://repo.spring.io/milestone' } +} +---- + +[[gradle-resolutionStrategy]] +===== Using Spring 4.0.x and Gradle + +By default Gradle will use the newest version when resolving transitive versions. +This means that often times no additional work is necessary when running Spring Security {spring-security-version} with Spring Framework {spring-version}. +However, at times there can be issues that come up so it is best to mitigate this using http://www.gradle.org/docs/current/dsl/org.gradle.api.artifacts.ResolutionStrategy.html[Gradle's ResolutionStrategy] as shown below: + +.build.gradle +[source,groovy] +[subs="verbatim,attributes"] +---- +configurations.all { + resolutionStrategy.eachDependency { DependencyResolveDetails details -> + if (details.requested.group == 'org.springframework') { + details.useVersion '{spring-version}' + } + } +} +---- + +This will ensure that all the transitive dependencies of Spring Security use the Spring {spring-version} modules. + +NOTE: This example uses Gradle 1.9, but may need modifications to work in future versions of Gradle since this is an incubating feature within Gradle. + +[[modules]] +==== Project Modules +In Spring Security 3.0, the codebase has been sub-divided into separate jars which more clearly separate different functionality areas and third-party dependencies. +If you are using Maven to build your project, then these are the modules you will add to your `pom.xml`. +Even if you're not using Maven, we'd recommend that you consult the `pom.xml` files to get an idea of third-party dependencies and versions. +Alternatively, a good idea is to examine the libraries that are included in the sample applications. + + +[[spring-security-core]] +===== Core - spring-security-core.jar +Contains core authentication and access-contol classes and interfaces, remoting support and basic provisioning APIs. +Required by any application which uses Spring Security. +Supports standalone applications, remote clients, method (service layer) security and JDBC user provisioning. +Contains the top-level packages: + +* `org.springframework.security.core` + +* `org.springframework.security.access` + +* `org.springframework.security.authentication` + +* `org.springframework.security.provisioning` + + + + + +[[spring-security-remoting]] +===== Remoting - spring-security-remoting.jar +Provides intergration with Spring Remoting. +You don't need this unless you are writing a remote client which uses Spring Remoting. +The main package is `org.springframework.security.remoting`. + + +[[spring-security-web]] +===== Web - spring-security-web.jar +Contains filters and related web-security infrastructure code. +Anything with a servlet API dependency. +You'll need it if you require Spring Security web authentication services and URL-based access-control. +The main package is `org.springframework.security.web`. + + +[[spring-security-config]] +===== Config - spring-security-config.jar +Contains the security namespace parsing code & Java configuration code. +You need it if you are using the Spring Security XML namespace for configuration or Spring Security's Java Configuration support. +The main package is `org.springframework.security.config`. +None of the classes are intended for direct use in an application. + + +[[spring-security-ldap]] +===== LDAP - spring-security-ldap.jar +LDAP authentication and provisioning code. +Required if you need to use LDAP authentication or manage LDAP user entries. +The top-level package is `org.springframework.security.ldap`. + + +[[spring-security-oauth2-core]] +===== OAuth 2.0 Core - spring-security-oauth2-core.jar +`spring-security-oauth2-core.jar` contains core classes and interfaces that provide support for the _OAuth 2.0 Authorization Framework_ and for _OpenID Connect Core 1.0_. +It is required by applications that use _OAuth 2.0_ or _OpenID Connect Core 1.0_, such as Client, Resource Server, and Authorization Server. +The top-level package is `org.springframework.security.oauth2.core`. + + +[[spring-security-oauth2-client]] +===== OAuth 2.0 Client - spring-security-oauth2-client.jar +`spring-security-oauth2-client.jar` is Spring Security's client support for _OAuth 2.0 Authorization Framework_ and _OpenID Connect Core 1.0_. +Required by applications leveraging *OAuth 2.0 Login* and/or OAuth Client support. +The top-level package is `org.springframework.security.oauth2.client`. + + +[[spring-security-oauth2-jose]] +===== OAuth 2.0 JOSE - spring-security-oauth2-jose.jar +`spring-security-oauth2-jose.jar` contains Spring Security's support for the _JOSE_ (Javascript Object Signing and Encryption) framework. +The _JOSE_ framework is intended to provide a method to securely transfer claims between parties. +It is built from a collection of specifications: + +* JSON Web Token (JWT) +* JSON Web Signature (JWS) +* JSON Web Encryption (JWE) +* JSON Web Key (JWK) + +It contains the top-level packages: + +* `org.springframework.security.oauth2.jwt` +* `org.springframework.security.oauth2.jose` + + +[[spring-security-acl]] +===== ACL - spring-security-acl.jar +Specialized domain object ACL implementation. +Used to apply security to specific domain object instances within your application. +The top-level package is `org.springframework.security.acls`. + + +[[spring-security-cas]] +===== CAS - spring-security-cas.jar +Spring Security's CAS client integration. +If you want to use Spring Security web authentication with a CAS single sign-on server. +The top-level package is `org.springframework.security.cas`. + + +[[spring-security-openid]] +===== OpenID - spring-security-openid.jar +OpenID web authentication support. +Used to authenticate users against an external OpenID server. +`org.springframework.security.openid`. +Requires OpenID4Java. + + +[[spring-security-test]] +===== Test - spring-security-test.jar +Support for testing with Spring Security. + + +[[get-source]] +==== Checking out the Source +Since Spring Security is an Open Source project, we'd strongly encourage you to check out the source code using git. +This will give you full access to all the sample applications and you can build the most up to date version of the project easily. +Having the source for a project is also a huge help in debugging. +Exception stack traces are no longer obscure black-box issues but you can get straight to the line that's causing the problem and work out what's happening. +The source is the ultimate documentation for a project and often the simplest place to find out how something actually works. + +To obtain the source for the project, use the following git command: + +[source,txt] +---- +git clone https://github.com/spring-projects/spring-security.git +---- + +This will give you access to the entire project history (including all releases and branches) on your local machine. diff --git a/docs/manual/src/docs/asciidoc/_includes/preface/java-configuration.adoc b/docs/manual/src/docs/asciidoc/_includes/preface/java-configuration.adoc new file mode 100644 index 0000000000..2d786baebd --- /dev/null +++ b/docs/manual/src/docs/asciidoc/_includes/preface/java-configuration.adoc @@ -0,0 +1,1527 @@ + +[[jc]] +== Java Configuration + +General support for http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/beans.html#beans-java[Java Configuration] was added to Spring Framework in Spring 3.1. +Since Spring Security 3.2 there has been Spring Security Java Configuration support which enables users to easily configure Spring Security without the use of any XML. + +If you are familiar with the <> then you should find quite a few similarities between it and the Security Java Configuration support. + +NOTE: Spring Security provides https://github.com/spring-projects/spring-security/tree/master/samples/javaconfig[lots of sample applications] which demonstrate the use of Spring Security Java Configuration. + +=== Hello Web Security Java Configuration + +The first step is to create our Spring Security Java Configuration. +The configuration creates a Servlet Filter known as the `springSecurityFilterChain` which is responsible for all the security (protecting the application URLs, validating submitted username and passwords, redirecting to the log in form, etc) within your application. +You can find the most basic example of a Spring Security Java Configuration below: + +[[jc-hello-wsca]] +[source,java] +---- +import org.springframework.beans.factory.annotation.Autowired; + +import org.springframework.context.annotation.*; +import org.springframework.security.config.annotation.authentication.builders.*; +import org.springframework.security.config.annotation.web.configuration.*; + +@EnableWebSecurity +public class WebSecurityConfig implements WebMvcConfigurer { + + @Bean + public UserDetailsService userDetailsService() throws Exception { + InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); + manager.createUser(User.withDefaultPasswordEncoder().username("user").password("password").roles("USER").build()); + return manager; + } +} +---- + +There really isn't much to this configuration, but it does a lot. +You can find a summary of the features below: + +* Require authentication to every URL in your application +* Generate a login form for you +* Allow the user with the *Username* _user_ and the *Password* _password_ to authenticate with form based authentication +* Allow the user to logout +* http://en.wikipedia.org/wiki/Cross-site_request_forgery[CSRF attack] prevention +* http://en.wikipedia.org/wiki/Session_fixation[Session Fixation] protection +* Security Header integration +** http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security[HTTP Strict Transport Security] for secure requests +** http://msdn.microsoft.com/en-us/library/ie/gg622941(v=vs.85).aspx[X-Content-Type-Options] integration +** Cache Control (can be overridden later by your application to allow caching of your static resources) +** http://msdn.microsoft.com/en-us/library/dd565647(v=vs.85).aspx[X-XSS-Protection] integration +** X-Frame-Options integration to help prevent http://en.wikipedia.org/wiki/Clickjacking[Clickjacking] +* Integrate with the following Servlet API methods +** http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#getRemoteUser()[HttpServletRequest#getRemoteUser()] +** http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#getUserPrincipal()[HttpServletRequest.html#getUserPrincipal()] +** http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#isUserInRole(java.lang.String)[HttpServletRequest.html#isUserInRole(java.lang.String)] +** http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#login(java.lang.String,%20java.lang.String)[HttpServletRequest.html#login(java.lang.String, java.lang.String)] +** http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#logout()[HttpServletRequest.html#logout()] + +==== AbstractSecurityWebApplicationInitializer + +The next step is to register the `springSecurityFilterChain` with the war. +This can be done in Java Configuration with http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-container-config[Spring's WebApplicationInitializer support] in a Servlet 3.0+ environment. +Not suprisingly, Spring Security provides a base class `AbstractSecurityWebApplicationInitializer` that will ensure the `springSecurityFilterChain` gets registered for you. +The way in which we use `AbstractSecurityWebApplicationInitializer` differs depending on if we are already using Spring or if Spring Security is the only Spring component in our application. + +* <> - Use these instructions if you are not using Spring already +* <> - Use these instructions if you are already using Spring + +==== AbstractSecurityWebApplicationInitializer without Existing Spring + +If you are not using Spring or Spring MVC, you will need to pass in the `WebSecurityConfig` into the superclass to ensure the configuration is picked up. +You can find an example below: + +[source,java] +---- +import org.springframework.security.web.context.*; + +public class SecurityWebApplicationInitializer + extends AbstractSecurityWebApplicationInitializer { + + public SecurityWebApplicationInitializer() { + super(WebSecurityConfig.class); + } +} +---- + +The `SecurityWebApplicationInitializer` will do the following things: + +* Automatically register the springSecurityFilterChain Filter for every URL in your application +* Add a ContextLoaderListener that loads the <>. + +==== AbstractSecurityWebApplicationInitializer with Spring MVC + +If we were using Spring elsewhere in our application we probably already had a `WebApplicationInitializer` that is loading our Spring Configuration. +If we use the previous configuration we would get an error. +Instead, we should register Spring Security with the existing `ApplicationContext`. +For example, if we were using Spring MVC our `SecurityWebApplicationInitializer` would look something like the following: + +[source,java] +---- +import org.springframework.security.web.context.*; + +public class SecurityWebApplicationInitializer + extends AbstractSecurityWebApplicationInitializer { + +} +---- + +This would simply only register the springSecurityFilterChain Filter for every URL in your application. +After that we would ensure that `WebSecurityConfig` was loaded in our existing ApplicationInitializer. +For example, if we were using Spring MVC it would be added in the `getRootConfigClasses()` + +[[message-web-application-inititializer-java]] +[source,java] +---- +public class MvcWebApplicationInitializer extends + AbstractAnnotationConfigDispatcherServletInitializer { + + @Override + protected Class[] getRootConfigClasses() { + return new Class[] { WebSecurityConfig.class }; + } + + // ... other overrides ... +} +---- + +[[jc-httpsecurity]] +=== HttpSecurity + +Thus far our <> only contains information about how to authenticate our users. +How does Spring Security know that we want to require all users to be authenticated? How does Spring Security know we want to support form based authentication? The reason for this is that the `WebSecurityConfigurerAdapter` provides a default configuration in the `configure(HttpSecurity http)` method that looks like: + +[source,java] +---- +protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .anyRequest().authenticated() + .and() + .formLogin() + .and() + .httpBasic(); +} +---- + +The default configuration above: + +* Ensures that any request to our application requires the user to be authenticated +* Allows users to authenticate with form based login +* Allows users to authenticate with HTTP Basic authentication + +You will notice that this configuration is quite similar the XML Namespace configuration: + +[source,xml] +---- + + + + + +---- + +The Java Configuration equivalent of closing an XML tag is expressed using the `and()` method which allows us to continue configuring the parent. +If you read the code it also makes sense. +I want to configure authorized requests __and__ configure form login __and__ configure HTTP Basic authentication. + +However, Java Configuration has different defaults URLs and parameters. +Keep this in mind when creating custom login pages. +The result is that our URLs are more RESTful. +Additionally, it is not quite so obvious we are using Spring Security which helps to prevent https://www.owasp.org/index.php/Information_Leak_(information_disclosure)[information leaks]. +For example: + +[[jc-form]] +=== Java Configuration and Form Login +You might be wondering where the login form came from when you were prompted to log in, since we made no mention of any HTML files or JSPs. +Since Spring Security's default configuration does not explicitly set a URL for the login page, Spring Security generates one automatically, based on the features that are enabled and using standard values for the URL which processes the submitted login, the default target URL the user will be sent to after logging in and so on. + +While the automatically generated log in page is convenient to get up and running quickly, most applications will want to provide their own log in page. +To do so we can update our configuration as seen below: + + +[source,java] +---- +protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .anyRequest().authenticated() + .and() + .formLogin() + .loginPage("/login") // <1> + .permitAll(); // <2> +} +---- + +<1> The updated configuration specifies the location of the log in page. +<2> We must grant all users (i.e. unauthenticated users) access to our log in page. +The `formLogin().permitAll()` method allows granting access to all users for all URLs associated with form based log in. + +An example log in page implemented with JSPs for our current configuration can be seen below: + +NOTE: The login page below represents our current configuration. +We could easily update our configuration if some of the defaults do not meet our needs. + +[source,html] +---- + +
<1> + <2> +

+ Invalid username and password. +

+
+ <3> +

+ You have been logged out. +

+
+

+ + <4> +

+

+ + <5> +

+ + name="${_csrf.parameterName}" + value="${_csrf.token}"/> + +
+---- + +<1> A POST to the `/login` URL will attempt to authenticate the user +<2> If the query parameter `error` exists, authentication was attempted and failed +<3> If the query parameter `logout` exists, the user was successfully logged out +<4> The username must be present as the HTTP parameter named __username__ +<5> The password must be present as the HTTP parameter named __password__ +<6> We must <> To learn more read the <> section of the reference + +[[jc-authorize-requests]] +=== Authorize Requests +Our examples have only required users to be authenticated and have done so for every URL in our application. +We can specify custom requirements for our URLs by adding multiple children to our `http.authorizeRequests()` method. +For example: + + +[source,java] +---- +protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() <1> + .antMatchers("/resources/**", "/signup", "/about").permitAll() <2> + .antMatchers("/admin/**").hasRole("ADMIN") <3> + .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')") <4> + .anyRequest().authenticated() <5> + .and() + // ... + .formLogin(); +} +---- + +<1> There are multiple children to the `http.authorizeRequests()` method each matcher is considered in the order they were declared. +<2> We specified multiple URL patterns that any user can access. +Specifically, any user can access a request if the URL starts with "/resources/", equals "/signup", or equals "/about". +<3> Any URL that starts with "/admin/" will be restricted to users who have the role "ROLE_ADMIN". +You will notice that since we are invoking the `hasRole` method we do not need to specify the "ROLE_" prefix. +<4> Any URL that starts with "/db/" requires the user to have both "ROLE_ADMIN" and "ROLE_DBA". +You will notice that since we are using the `hasRole` expression we do not need to specify the "ROLE_" prefix. +<5> Any URL that has not already been matched on only requires that the user be authenticated + +[[jc-logout]] +=== Handling Logouts + +When using the `{security-api-url}org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurerAdapter.html[WebSecurityConfigurerAdapter]`, logout capabilities are automatically applied. +The default is that accessing the URL `/logout` will log the user out by: + +- Invalidating the HTTP Session +- Cleaning up any RememberMe authentication that was configured +- Clearing the `SecurityContextHolder` +- Redirect to `/login?logout` + +Similar to configuring login capabilities, however, you also have various options to further customize your logout requirements: + +[source,java] +---- +protected void configure(HttpSecurity http) throws Exception { + http + .logout() <1> + .logoutUrl("/my/logout") <2> + .logoutSuccessUrl("/my/index") <3> + .logoutSuccessHandler(logoutSuccessHandler) <4> + .invalidateHttpSession(true) <5> + .addLogoutHandler(logoutHandler) <6> + .deleteCookies(cookieNamesToClear) <7> + .and() + ... +} +---- + +<1> Provides logout support. +This is automatically applied when using `WebSecurityConfigurerAdapter`. +<2> The URL that triggers log out to occur (default is `/logout`). +If CSRF protection is enabled (default), then the request must also be a POST. +For more information, please consult the {security-api-url}org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.html#logoutUrl-java.lang.String-[JavaDoc]. +<3> The URL to redirect to after logout has occurred. +The default is `/login?logout`. +For more information, please consult the {security-api-url}org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.html#logoutSuccessUrl-java.lang.String-[JavaDoc]. +<4> Let's you specify a custom `LogoutSuccessHandler`. +If this is specified, `logoutSuccessUrl()` is ignored. +For more information, please consult the {security-api-url}org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.html#logoutSuccessHandler-org.springframework.security.web.authentication.logout.LogoutSuccessHandler-[JavaDoc]. +<5> Specify whether to invalidate the `HttpSession` at the time of logout. +This is *true* by default. +Configures the `SecurityContextLogoutHandler` under the covers. +For more information, please consult the {security-api-url}org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.html#invalidateHttpSession-boolean-[JavaDoc]. +<6> Adds a `LogoutHandler`. +`SecurityContextLogoutHandler` is added as the last `LogoutHandler` by default. +<7> Allows specifying the names of cookies to be removed on logout success. +This is a shortcut for adding a `CookieClearingLogoutHandler` explicitly. + +[NOTE] +==== +Logouts can of course also be configured using the XML Namespace notation. +Please see the documentation for the <> in the Spring Security XML Namespace section for further details. +==== + +Generally, in order to customize logout functionality, you can add +`{security-api-url}org/springframework/security/web/authentication/logout/LogoutHandler.html[LogoutHandler]` +and/or +`{security-api-url}org/springframework/security/web/authentication/logout/LogoutSuccessHandler.html[LogoutSuccessHandler]` +implementations. +For many common scenarios, these handlers are applied under the +covers when using the fluent API. + +[[jc-logout-handler]] +==== LogoutHandler + +Generally, `{security-api-url}org/springframework/security/web/authentication/logout/LogoutHandler.html[LogoutHandler]` +implementations indicate classes that are able to participate in logout handling. +They are expected to be invoked to perform necessary clean-up. +As such they should +not throw exceptions. +Various implementations are provided: + +- {security-api-url}org/springframework/security/web/authentication/rememberme/PersistentTokenBasedRememberMeServices.html[PersistentTokenBasedRememberMeServices] +- {security-api-url}org/springframework/security/web/authentication/rememberme/TokenBasedRememberMeServices.html[TokenBasedRememberMeServices] +- {security-api-url}org/springframework/security/web/authentication/logout/CookieClearingLogoutHandler.html[CookieClearingLogoutHandler] +- {security-api-url}org/springframework/security/web/csrf/CsrfLogoutHandler.html[CsrfLogoutHandler] +- {security-api-url}org/springframework/security/web/authentication/logout/SecurityContextLogoutHandler.html[SecurityContextLogoutHandler] + +Please see <> for details. + +Instead of providing `LogoutHandler` implementations directly, the fluent API also provides shortcuts that provide the respective `LogoutHandler` implementations under the covers. +E.g. `deleteCookies()` allows specifying the names of one or more cookies to be removed on logout success. +This is a shortcut compared to adding a `CookieClearingLogoutHandler`. + +[[jc-logout-success-handler]] +==== LogoutSuccessHandler + +The `LogoutSuccessHandler` is called after a successful logout by the `LogoutFilter`, to handle e.g. +redirection or forwarding to the appropriate destination. +Note that the interface is almost the same as the `LogoutHandler` but may raise an exception. + +The following implementations are provided: + +- {security-api-url}org/springframework/security/web/authentication/logout/SimpleUrlLogoutSuccessHandler.html[SimpleUrlLogoutSuccessHandler] +- HttpStatusReturningLogoutSuccessHandler + +As mentioned above, you don't need to specify the `SimpleUrlLogoutSuccessHandler` directly. +Instead, the fluent API provides a shortcut by setting the `logoutSuccessUrl()`. +This will setup the `SimpleUrlLogoutSuccessHandler` under the covers. +The provided URL will be redirected to after a logout has occurred. +The default is `/login?logout`. + +The `HttpStatusReturningLogoutSuccessHandler` can be interesting in REST API type scenarios. +Instead of redirecting to a URL upon the successful logout, this `LogoutSuccessHandler` allows you to provide a plain HTTP status code to be returned. +If not configured a status code 200 will be returned by default. + +[[jc-logout-references]] +==== Further Logout-Related References + +- <> +- <> +- <> +- <> +- <> in section CSRF Caveats +- Section <> (CAS protocol) +- Documentation for the <> in the Spring Security XML Namespace section + +[[jc-webflux]] +=== WebFlux Security + +Spring Security's WebFlux support relies on a `WebFilter` and works the same for Spring WebFlux and Spring WebFlux.Fn. +You can find a few sample applications that demonstrate the code below: + +* Hello WebFlux {gh-samples-url}/javaconfig/hellowebflux[hellowebflux] +* Hello WebFlux.Fn {gh-samples-url}/javaconfig/hellowebfluxfn[hellowebfluxfn] +* Hello WebFlux Method {gh-samples-url}/javaconfig/hellowebflux-method[hellowebflux-method] + + +==== Minimal WebFlux Security Configuration + +You can find a minimal WebFlux Security configuration below: + +[source,java] +----- +@EnableWebFluxSecurity +public class HelloWebfluxSecurityConfig { + + @Bean + public MapReactiveUserDetailsService userDetailsService() { + UserDetails user = User.withDefaultPasswordEncoder() + .username("user") + .password("user") + .roles("USER") + .build(); + return new MapReactiveUserDetailsService(user); + } +} +----- + +This configuration provides form and http basic authentication, sets up authorization to require an authenticated user for accessing any page, sets up a default log in page and a default log out page, sets up security related HTTP headers, CSRF protection, and more. + +==== Explicit WebFlux Security Configuration + +You can find an explicit version of the minimal WebFlux Security configuration below: + +[source,java] +----- +@EnableWebFluxSecurity +public class HelloWebfluxSecurityConfig { + + @Bean + public MapReactiveUserDetailsService userDetailsService() { + UserDetails user = User.withDefaultPasswordEncoder() + .username("user") + .password("user") + .roles("USER") + .build(); + return new MapReactiveUserDetailsService(user); + } + + @Bean + public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { + http + .authorizeExchange() + .anyExchange().authenticated() + .and() + .httpBasic().and() + .formLogin(); + return http.build(); + } +} +----- + +This configuration explicitly sets up all the same things as our minimal configuration. +From here you can easily make the changes to the defaults. + +[[jc-oauth2login]] +=== OAuth 2.0 Login + +The OAuth 2.0 Login feature provides an application with the capability to have users log in to the application by using their existing account at an OAuth 2.0 Provider (e.g. +GitHub) or OpenID Connect 1.0 Provider (such as Google). +OAuth 2.0 Login implements the use cases: "Login with Google" or "Login with GitHub". + +NOTE: OAuth 2.0 Login is implemented by using the *Authorization Code Grant*, as specified in the https://tools.ietf.org/html/rfc6749#section-4.1[OAuth 2.0 Authorization Framework] and http://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth[OpenID Connect Core 1.0]. + +[[jc-oauth2login-sample-boot]] +==== Spring Boot 2.0 Sample + +Spring Boot 2.0 brings full auto-configuration capabilities for OAuth 2.0 Login. + +This section shows how to configure the {gh-samples-url}/boot/oauth2login[*OAuth 2.0 Login sample*] using _Google_ as the _Authentication Provider_ and covers the following topics: + +* <> +* <> +* <> +* <> + + +[[jc-oauth2login-sample-initial-setup]] +===== Initial setup + +To use Google's OAuth 2.0 authentication system for login, you must set up a project in the Google API Console to obtain OAuth 2.0 credentials. + +NOTE: https://developers.google.com/identity/protocols/OpenIDConnect[Google's OAuth 2.0 implementation] for authentication conforms to the http://openid.net/connect/[OpenID Connect 1.0] specification and is http://openid.net/certification/[OpenID Certified]. + +Follow the instructions on the https://developers.google.com/identity/protocols/OpenIDConnect[OpenID Connect] page, starting in the section, "Setting up OAuth 2.0". + +After completing the "Obtain OAuth 2.0 credentials" instructions, you should have a new OAuth Client with credentials consisting of a Client ID and a Client Secret. + +[[jc-oauth2login-sample-redirect-uri]] +===== Setting the redirect URI + +The redirect URI is the path in the application that the end-user's user-agent is redirected back to after they have authenticated with Google and have granted access to the OAuth Client _(<>)_ on the Consent page. + +In the "Set a redirect URI" sub-section, ensure that the *Authorized redirect URIs* field is set to `http://localhost:8080/login/oauth2/code/google`. + +TIP: The default redirect URI template is `{baseUrl}/login/oauth2/code/{registrationId}`. +The *_registrationId_* is a unique identifier for the <>. + +[[jc-oauth2login-sample-application-config]] +===== Configure `application.yml` + +Now that you have a new OAuth Client with Google, you need to configure the application to use the OAuth Client for the _authentication flow_. +To do so: + +. Go to `application.yml` and set the following configuration: ++ +[source,yaml] +---- +spring: + security: + oauth2: + client: + registration: <1> + google: <2> + client-id: google-client-id + client-secret: google-client-secret +---- ++ +.OAuth Client properties +==== +<1> `spring.security.oauth2.client.registration` is the base property prefix for OAuth Client properties. +<2> Following the base property prefix is the ID for the <>, such as google. +==== + +. Replace the values in the `client-id` and `client-secret` property with the OAuth 2.0 credentials you created earlier. + + +[[jc-oauth2login-sample-boot-application]] +===== Boot up the application + +Launch the Spring Boot 2.0 sample and go to `http://localhost:8080`. +You are then redirected to the default _auto-generated_ login page, which displays a link for Google. + +Click on the Google link, and you are then redirected to Google for authentication. + +After authenticating with your Google account credentials, the next page presented to you is the Consent screen. +The Consent screen asks you to either allow or deny access to the OAuth Client you created earlier. +Click *Allow* to authorize the OAuth Client to access your email address and basic profile information. + +At this point, the OAuth Client retrieves your email address and basic profile information from the http://openid.net/specs/openid-connect-core-1_0.html#UserInfo[UserInfo Endpoint] and establishes an authenticated session. + +[[jc-oauth2login-client-registration]] +==== ClientRegistration + +`ClientRegistration` is a representation of a client registered with an OAuth 2.0 or OpenID Connect 1.0 Provider. + +A client registration holds information, such as client id, client secret, +authorization grant type, redirect URI, scope(s), authorization URI, token URI, and other details. + +`ClientRegistration` and its properties are defined as follows: + +[source,java] +---- +public final class ClientRegistration { + private String registrationId; <1> + private String clientId; <2> + private String clientSecret; <3> + private ClientAuthenticationMethod clientAuthenticationMethod; <4> + private AuthorizationGrantType authorizationGrantType; <5> + private String redirectUriTemplate; <6> + private Set scopes; <7> + private ProviderDetails providerDetails; + private String clientName; <8> + + public class ProviderDetails { + private String authorizationUri; <9> + private String tokenUri; <10> + private UserInfoEndpoint userInfoEndpoint; + private String jwkSetUri; <11> + + public class UserInfoEndpoint { + private String uri; <12> + private String userNameAttributeName; <13> + + } + } +} +---- +<1> `registrationId`: The ID that uniquely identifies the `ClientRegistration`. +<2> `clientId`: The client identifier. +<3> `clientSecret`: The client secret. +<4> `clientAuthenticationMethod`: The method used to authenticate the Client with the Provider. +The supported values are *basic* and *post*. +<5> `authorizationGrantType`: The OAuth 2.0 Authorization Framework defines four https://tools.ietf.org/html/rfc6749#section-1.3[Authorization Grant] types. + The supported values are authorization_code and implicit. +<6> `redirectUriTemplate`: The client's registered redirect URI that the _Authorization Server_ redirects the end-user's user-agent + to after the end-user has authenticated and authorized access to the client. + The default redirect URI template is `{baseUrl}/login/oauth2/code/{registrationId}`, which supports URI template variables. +<7> `scopes`: The scope(s) requested by the client during the Authorization Request flow, such as openid, email, or profile. +<8> `clientName`: A descriptive name used for the client. +The name may be used in certain scenarios, such as when displaying the name of the client in the auto-generated login page. +<9> `authorizationUri`: The Authorization Endpoint URI for the Authorization Server. +<10> `tokenUri`: The Token Endpoint URI for the Authorization Server. +<11> `jwkSetUri`: The URI used to retrieve the https://tools.ietf.org/html/rfc7517[JSON Web Key (JWK)] Set from the Authorization Server, + which contains the cryptographic key(s) used to verify the https://tools.ietf.org/html/rfc7515[JSON Web Signature (JWS)] of the ID Token and optionally the UserInfo Response. +<12> `(userInfoEndpoint)uri`: The UserInfo Endpoint URI used to access the claims/attributes of the authenticated end-user. +<13> `userNameAttributeName`: The name of the attribute returned in the UserInfo Response that references the Name or Identifier of the end-user. + +[[jc-oauth2login-boot-property-mappings]] +==== Spring Boot 2.0 Property Mappings + +The following table outlines the mapping of the Spring Boot 2.0 OAuth Client properties to the `ClientRegistration` properties. + +|=== +|Spring Boot 2.0 |ClientRegistration + +|`spring.security.oauth2.client.registration._[registrationId]_` +|`registrationId` + +|`spring.security.oauth2.client.registration._[registrationId]_.client-id` +|`clientId` + +|`spring.security.oauth2.client.registration._[registrationId]_.client-secret` +|`clientSecret` + +|`spring.security.oauth2.client.registration._[registrationId]_.client-authentication-method` +|`clientAuthenticationMethod` + +|`spring.security.oauth2.client.registration._[registrationId]_.authorization-grant-type` +|`authorizationGrantType` + +|`spring.security.oauth2.client.registration._[registrationId]_.redirect-uri-template` +|`redirectUriTemplate` + +|`spring.security.oauth2.client.registration._[registrationId]_.scope` +|`scopes` + +|`spring.security.oauth2.client.registration._[registrationId]_.client-name` +|`clientName` + +|`spring.security.oauth2.client.provider._[providerId]_.authorization-uri` +|`providerDetails.authorizationUri` + +|`spring.security.oauth2.client.provider._[providerId]_.token-uri` +|`providerDetails.tokenUri` + +|`spring.security.oauth2.client.provider._[providerId]_.jwk-set-uri` +|`providerDetails.jwkSetUri` + +|`spring.security.oauth2.client.provider._[providerId]_.user-info-uri` +|`providerDetails.userInfoEndpoint.uri` + +|`spring.security.oauth2.client.provider._[providerId]_.userNameAttribute` +|`providerDetails.userInfoEndpoint.userNameAttributeName` +|=== + +[[jc-oauth2login-client-registration-repo]] +==== ClientRegistrationRepository + +The `ClientRegistrationRepository` serves as a repository for OAuth 2.0 / OpenID Connect 1.0 `ClientRegistration`(s). + +[NOTE] +Client registration information is ultimately stored and owned by the associated Authorization Server. +This repository provides the ability to retrieve a sub-set of the primary client registration information, +which is stored with the Authorization Server. + +Spring Boot 2.0 auto-configuration binds each of the properties under `spring.security.oauth2.client.registration._[registrationId]_` +to an instance of `ClientRegistration` and then composes each of the `ClientRegistration` instance(s) within a `ClientRegistrationRepository`. + +[NOTE] +The default implementation of `ClientRegistrationRepository` is `InMemoryClientRegistrationRepository`. + +The auto-configuration also registers the `ClientRegistrationRepository` as a `@Bean` in the `ApplicationContext` +so that it is available for dependency-injection, if needed by the application. + +The following listing shows an example: + +[source,java] +---- +@Controller +public class MainController { + + @Autowired + private ClientRegistrationRepository clientRegistrationRepository; + + @RequestMapping("/") + public String index() { + ClientRegistration googleRegistration = + this.clientRegistrationRepository.findByRegistrationId("google"); + + ... + + return "index"; + } +} +---- + +[[jc-oauth2login-common-oauth2-provider]] +==== CommonOAuth2Provider + +`CommonOAuth2Provider` pre-defines a set of default client properties for a number of well known providers: Google, GitHub, Facebook, and Okta. + +For example, the `authorization-uri`, `token-uri`, and `user-info-uri` do not change often for a Provider. +Therefore, it makes sense to provide default values in order to reduce the required configuration. + +As demonstrated previously, when we <>, only the `client-id` and `client-secret` properties are required. + +The following listing shows an example: + +[source,yaml] +---- +spring: + security: + oauth2: + client: + registration: + google: + client-id: google-client-id + client-secret: google-client-secret +---- + +[TIP] +The auto-defaulting of client properties works seamlessly here because the `registrationId` (`google`) matches the `GOOGLE` `enum` (case-insensitive) in `CommonOAuth2Provider`. + +For cases where you may want to specify a different `registrationId`, such as `google-login`, +you can still leverage auto-defaulting of client properties by configuring the `provider` property. + +The following listing shows an example: + +[source,yaml] +---- +spring: + security: + oauth2: + client: + registration: + google-login: <1> + provider: google <2> + client-id: google-client-id + client-secret: google-client-secret +---- +<1> The `registrationId` is set to `google-login`. +<2> The `provider` property is set to `google`, which will leverage the auto-defaulting of client properties set in `CommonOAuth2Provider.GOOGLE.getBuilder()`. + +[[jc-oauth2login-custom-provider-properties]] +==== Configuring Custom Provider Properties + +There are some OAuth 2.0 Providers that support multi-tenancy, which results in different protocol endpoints for each tenant (or sub-domain). + +For example, an OAuth Client registered with Okta is assigned to a specific sub-domain and have their own protocol endpoints. + +For these cases, Spring Boot 2.0 provides the following base property for configuring custom provider properties: `spring.security.oauth2.client.provider._[providerId]_`. + +The following listing shows an example: + +[source,yaml] +---- +spring: + security: + oauth2: + client: + registration: + okta: + client-id: okta-client-id + client-secret: okta-client-secret + provider: + okta: <1> + authorization-uri: https://your-subdomain.oktapreview.com/oauth2/v1/authorize + token-uri: https://your-subdomain.oktapreview.com/oauth2/v1/token + user-info-uri: https://your-subdomain.oktapreview.com/oauth2/v1/userinfo + user-name-attribute: sub + jwk-set-uri: https://your-subdomain.oktapreview.com/oauth2/v1/keys +---- + +<1> The base property (`spring.security.oauth2.client.provider.okta`) allows for custom configuration of protocol endpoint locations. + +[[jc-oauth2login-override-boot-autoconfig]] +==== Overriding Spring Boot 2.0 Auto-configuration + +The Spring Boot 2.0 Auto-configuration class for OAuth Client support is `OAuth2ClientAutoConfiguration`. + +It performs the following tasks: + +* Registers a `ClientRegistrationRepository` `@Bean` composed of `ClientRegistration`(s) from the configured OAuth Client properties. +* Provides a `WebSecurityConfigurerAdapter` `@Configuration` and enables OAuth 2.0 Login through `httpSecurity.oauth2Login()`. + +If you need to override the auto-configuration based on your specific requirements, you may do so in the following ways: + +* <> +* <> +* <> + + +[[jc-oauth2login-register-clientregistrationrepository-bean]] +===== Register a `ClientRegistrationRepository` `@Bean` + +The following example shows how to register a `ClientRegistrationRepository` `@Bean`: + +[source,java] +---- +@Configuration +public class OAuth2LoginConfig { + + @Bean + public ClientRegistrationRepository clientRegistrationRepository() { + return new InMemoryClientRegistrationRepository(this.googleClientRegistration()); + } + + private ClientRegistration googleClientRegistration() { + return ClientRegistration.withRegistrationId("google") + .clientId("google-client-id") + .clientSecret("google-client-secret") + .clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) + .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) + .redirectUriTemplate("{baseUrl}/login/oauth2/code/{registrationId}") + .scope("openid", "profile", "email", "address", "phone") + .authorizationUri("https://accounts.google.com/o/oauth2/v2/auth") + .tokenUri("https://www.googleapis.com/oauth2/v4/token") + .userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo") + .userNameAttributeName(IdTokenClaimNames.SUB) + .jwkSetUri("https://www.googleapis.com/oauth2/v3/certs") + .clientName("Google") + .build(); + } +} +---- + + +[[jc-oauth2login-provide-websecurityconfigureradapter]] +===== Provide a `WebSecurityConfigurerAdapter` + +The following example shows how to provide a `WebSecurityConfigurerAdapter` with `@EnableWebSecurity` and enable OAuth 2.0 login through `httpSecurity.oauth2Login()`: + +[source,java] +---- +@EnableWebSecurity +public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .anyRequest().authenticated() + .and() + .oauth2Login(); + } +} +---- + + +[[jc-oauth2login-completely-override-autoconfiguration]] +===== Completely Override the Auto-configuration + +The following example shows how to completely override the auto-configuration by both registering a `ClientRegistrationRepository` `@Bean` and providing a `WebSecurityConfigurerAdapter`, both of which were described in the two preceding sections. + +[source,java] +---- +@Configuration +public class OAuth2LoginConfig { + + @EnableWebSecurity + public static class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .anyRequest().authenticated() + .and() + .oauth2Login(); + } + } + + @Bean + public ClientRegistrationRepository clientRegistrationRepository() { + return new InMemoryClientRegistrationRepository(this.googleClientRegistration()); + } + + private ClientRegistration googleClientRegistration() { + return ClientRegistration.withRegistrationId("google") + .clientId("google-client-id") + .clientSecret("google-client-secret") + .clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) + .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) + .redirectUriTemplate("{baseUrl}/login/oauth2/code/{registrationId}") + .scope("openid", "profile", "email", "address", "phone") + .authorizationUri("https://accounts.google.com/o/oauth2/v2/auth") + .tokenUri("https://www.googleapis.com/oauth2/v4/token") + .userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo") + .userNameAttributeName(IdTokenClaimNames.SUB) + .jwkSetUri("https://www.googleapis.com/oauth2/v3/certs") + .clientName("Google") + .build(); + } +} +---- + +[[jc-oauth2login-javaconfig-wo-boot]] +==== Java Configuration without Spring Boot 2.0 + +If you are not able to use Spring Boot 2.0 and would like to configure one of the pre-defined providers in `CommonOAuth2Provider` (for example, Google), apply the following configuration: + +[source,java] +---- +@Configuration +public class OAuth2LoginConfig { + + @EnableWebSecurity + public static class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .anyRequest().authenticated() + .and() + .oauth2Login(); + } + } + + @Bean + public ClientRegistrationRepository clientRegistrationRepository() { + return new InMemoryClientRegistrationRepository(this.googleClientRegistration()); + } + + @Bean + public OAuth2AuthorizedClientService authorizedClientService() { + return new InMemoryOAuth2AuthorizedClientService(this.clientRegistrationRepository()); + } + + private ClientRegistration googleClientRegistration() { + return CommonOAuth2Provider.GOOGLE.getBuilder("google") + .clientId("google-client-id") + .clientSecret("google-client-secret") + .build(); + } +} +---- + +[[jc-oauth2login-authorized-client]] +==== OAuth2AuthorizedClient / OAuth2AuthorizedClientService + +`OAuth2AuthorizedClient` is a representation of an Authorized Client. +A client is considered to be authorized when the end-user (Resource Owner) has granted authorization to the client to access its protected resources. + +`OAuth2AuthorizedClient` serves the purpose of associating an `OAuth2AccessToken` to a `ClientRegistration` (client) and resource owner, who is the `Principal` end-user that granted the authorization. + +The primary role of the `OAuth2AuthorizedClientService` is to manage `OAuth2AuthorizedClient` instances. +From a developer perspective, it provides the capability to lookup an `OAuth2AccessToken` associated with a client so that it may be used to initiate a request to a resource server. + +[NOTE] +Spring Boot 2.0 Auto-configuration registers an `OAuth2AuthorizedClientService` `@Bean` in the `ApplicationContext`. + +The developer may also register an `OAuth2AuthorizedClientService` `@Bean` in the `ApplicationContext` (overriding Spring Boot 2.0 Auto-configuration) in order to have the ability to lookup an `OAuth2AccessToken` associated with a specific `ClientRegistration` (client). + +The following listing shows an example: + +[source,java] +---- +@Controller +public class MainController { + + @Autowired + private OAuth2AuthorizedClientService authorizedClientService; + + @RequestMapping("/userinfo") + public String userinfo(OAuth2AuthenticationToken authentication) { + // authentication.getAuthorizedClientRegistrationId() returns the + // registrationId of the Client that was authorized during the Login flow + OAuth2AuthorizedClient authorizedClient = + this.authorizedClientService.loadAuthorizedClient( + authentication.getAuthorizedClientRegistrationId(), + authentication.getName()); + + OAuth2AccessToken accessToken = authorizedClient.getAccessToken(); + + ... + + return "userinfo"; + } +} +---- + + +[[jc-oauth2login-resources]] +==== Additional Resources + +The following additional resources describe advanced configuration options: + +* <> +* Authorization Endpoint: +** <> +* <> +* Token Endpoint: +** <> +* UserInfo Endpoint: +** <> +** <> +** <> +** <> + +[[jc-authentication]] +=== Authentication + +Thus far we have only taken a look at the most basic authentication configuration. +Let's take a look at a few slightly more advanced options for configuring authentication. + +[[jc-authentication-inmemory]] +==== In-Memory Authentication + +We have already seen an example of configuring in-memory authentication for a single user. +Below is an example to configure multiple users: + +[source,java] +---- +@Bean +public UserDetailsService userDetailsService() throws Exception { + // ensure the passwords are encoded properly + UserBuilder users = User.withDefaultPasswordEncoder(); + InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); + manager.createUser(users.username("user").password("password").roles("USER").build()); + manager.createUser(users.username("admin").password("password").roles("USER","ADMIN").build()); + return manager; +} +---- + +[[jc-authentication-jdbc]] +==== JDBC Authentication + +You can find the updates to support JDBC based authentication. +The example below assumes that you have already defined a `DataSource` within your application. +The https://github.com/spring-projects/spring-security/tree/master/samples/javaconfig/jdbc[jdbc-javaconfig] sample provides a complete example of using JDBC based authentication. + +[source,java] +---- +@Autowired +private DataSource dataSource; + +@Autowired +public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + // ensure the passwords are encoded properly + UserBuilder users = User.withDefaultPasswordEncoder(); + auth + .jdbcAuthentication() + .dataSource(dataSource) + .withDefaultSchema() + .withUser(users.username("user").password("password").roles("USER")) + .withUser(users.username("admin").password("password").roles("USER","ADMIN")); +} +---- + +==== LDAP Authentication + +You can find the updates to support LDAP based authentication. +The https://github.com/spring-projects/spring-security/tree/master/samples/javaconfig/ldap[ldap-javaconfig] sample provides a complete example of using LDAP based authentication. + +[source,java] +---- +@Autowired +private DataSource dataSource; + +@Autowired +public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth + .ldapAuthentication() + .userDnPatterns("uid={0},ou=people") + .groupSearchBase("ou=groups"); +} +---- + +The example above uses the following LDIF and an embedded Apache DS LDAP instance. + +.users.ldif +---- +dn: ou=groups,dc=springframework,dc=org +objectclass: top +objectclass: organizationalUnit +ou: groups + +dn: ou=people,dc=springframework,dc=org +objectclass: top +objectclass: organizationalUnit +ou: people + +dn: uid=admin,ou=people,dc=springframework,dc=org +objectclass: top +objectclass: person +objectclass: organizationalPerson +objectclass: inetOrgPerson +cn: Rod Johnson +sn: Johnson +uid: admin +userPassword: password + +dn: uid=user,ou=people,dc=springframework,dc=org +objectclass: top +objectclass: person +objectclass: organizationalPerson +objectclass: inetOrgPerson +cn: Dianne Emu +sn: Emu +uid: user +userPassword: password + +dn: cn=user,ou=groups,dc=springframework,dc=org +objectclass: top +objectclass: groupOfNames +cn: user +uniqueMember: uid=admin,ou=people,dc=springframework,dc=org +uniqueMember: uid=user,ou=people,dc=springframework,dc=org + +dn: cn=admin,ou=groups,dc=springframework,dc=org +objectclass: top +objectclass: groupOfNames +cn: admin +uniqueMember: uid=admin,ou=people,dc=springframework,dc=org +---- + +[[jc-authentication-authenticationprovider]] +==== AuthenticationProvider + +You can define custom authentication by exposing a custom `AuthenticationProvider` as a bean. +For example, the following will customize authentication assuming that `SpringAuthenticationProvider` implements `AuthenticationProvider`: + +NOTE: This is only used if the `AuthenticationManagerBuilder` has not been populated + +[source,java] +---- +@Bean +public SpringAuthenticationProvider springAuthenticationProvider() { + return new SpringAuthenticationProvider(); +} +---- + +[[jc-authentication-userdetailsservice]] +==== UserDetailsService + +You can define custom authentication by exposing a custom `UserDetailsService` as a bean. +For example, the following will customize authentication assuming that `SpringDataUserDetailsService` implements `UserDetailsService`: + +NOTE: This is only used if the `AuthenticationManagerBuilder` has not been populated and no `AuthenticationProviderBean` is defined. + +[source,java] +---- +@Bean +public SpringDataUserDetailsService springDataUserDetailsService() { + return new SpringDataUserDetailsService(); +} +---- + +You can also customize how passwords are encoded by exposing a `PasswordEncoder` as a bean. +For example, if you use bcrypt you can add a bean definition as shown below: + +[source,java] +---- +@Bean +public BCryptPasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); +} +---- + +=== Multiple HttpSecurity + +We can configure multiple HttpSecurity instances just as we can have multiple `` blocks. +The key is to extend the `WebSecurityConfigurationAdapter` multiple times. +For example, the following is an example of having a different configuration for URL's that start with `/api/`. + +[source,java] +---- +@EnableWebSecurity +public class MultiHttpSecurityConfig { + @Bean <1> + public UserDetailsService userDetailsService() throws Exception { + // ensure the passwords are encoded properly + UserBuilder users = User.withDefaultPasswordEncoder(); + InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); + manager.createUser(users.username("user").password("password").roles("USER").build()); + manager.createUser(users.username("admin").password("password").roles("USER","ADMIN").build()); + return manager; + } + + @Configuration + @Order(1) <2> + public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { + protected void configure(HttpSecurity http) throws Exception { + http + .antMatcher("/api/**") <3> + .authorizeRequests() + .anyRequest().hasRole("ADMIN") + .and() + .httpBasic(); + } + } + + @Configuration <4> + public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .anyRequest().authenticated() + .and() + .formLogin(); + } + } +} +---- + +<1> Configure Authentication as normal +<2> Create an instance of `WebSecurityConfigurerAdapter` that contains `@Order` to specify which `WebSecurityConfigurerAdapter` should be considered first. +<3> The `http.antMatcher` states that this `HttpSecurity` will only be applicable to URLs that start with `/api/` +<4> Create another instance of `WebSecurityConfigurerAdapter`. +If the URL does not start with `/api/` this configuration will be used. +This configuration is considered after `ApiWebSecurityConfigurationAdapter` since it has an `@Order` value after `1` (no `@Order` defaults to last). + + +[[jc-method]] +=== Method Security + +From version 2.0 onwards Spring Security has improved support substantially for adding security to your service layer methods. +It provides support for JSR-250 annotation security as well as the framework's original `@Secured` annotation. +From 3.0 you can also make use of new <>. +You can apply security to a single bean, using the `intercept-methods` element to decorate the bean declaration, or you can secure multiple beans across the entire service layer using the AspectJ style pointcuts. + +==== EnableGlobalMethodSecurity + +We can enable annotation-based security using the `@EnableGlobalMethodSecurity` annotation on any `@Configuration` instance. +For example, the following would enable Spring Security's `@Secured` annotation. + +[source,java] +---- +@EnableGlobalMethodSecurity(securedEnabled = true) +public class MethodSecurityConfig { +// ... +} +---- + +Adding an annotation to a method (on a class or interface) would then limit the access to that method accordingly. +Spring Security's native annotation support defines a set of attributes for the method. +These will be passed to the AccessDecisionManager for it to make the actual decision: + +[source,java] +---- +public interface BankService { + +@Secured("IS_AUTHENTICATED_ANONYMOUSLY") +public Account readAccount(Long id); + +@Secured("IS_AUTHENTICATED_ANONYMOUSLY") +public Account[] findAccounts(); + +@Secured("ROLE_TELLER") +public Account post(Account account, double amount); +} +---- + +Support for JSR-250 annotations can be enabled using + +[source,java] +---- +@EnableGlobalMethodSecurity(jsr250Enabled = true) +public class MethodSecurityConfig { +// ... +} +---- + +These are standards-based and allow simple role-based constraints to be applied but do not have the power Spring Security's native annotations. +To use the new expression-based syntax, you would use + +[source,java] +---- +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class MethodSecurityConfig { +// ... +} +---- + +and the equivalent Java code would be + +[source,java] +---- +public interface BankService { + +@PreAuthorize("isAnonymous()") +public Account readAccount(Long id); + +@PreAuthorize("isAnonymous()") +public Account[] findAccounts(); + +@PreAuthorize("hasAuthority('ROLE_TELLER')") +public Account post(Account account, double amount); +} +---- + +==== GlobalMethodSecurityConfiguration + +Sometimes you may need to perform operations that are more complicated than are possible with the `@EnableGlobalMethodSecurity` annotation allow. +For these instances, you can extend the `GlobalMethodSecurityConfiguration` ensuring that the `@EnableGlobalMethodSecurity` annotation is present on your subclass. +For example, if you wanted to provide a custom `MethodSecurityExpressionHandler`, you could use the following configuration: + +[source,java] +---- +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { + @Override + protected MethodSecurityExpressionHandler createExpressionHandler() { + // ... create and return custom MethodSecurityExpressionHandler ... + return expressionHandler; + } +} +---- + +For additional information about methods that can be overridden, refer to the `GlobalMethodSecurityConfiguration` Javadoc. + +[[jc-erms]] +==== EnableReactiveMethodSecurity + +Spring Security supports method security using https://projectreactor.io/docs/core/release/reference/#context[Reactor's Context] which is setup using `ReactiveSecurityContextHolder`. +For example, this demonstrates how to retrieve the currently logged in user's message. + +[NOTE] +==== +For this to work the return type of the method must be a `org.reactivestreams.Publisher` (i.e. `Mono`/`Flux`). +This is necessary to integrate with Reactor's `Context`. +==== + +[source,java] +---- +Authentication authentication = new TestingAuthenticationToken("user", "password", "ROLE_USER"); + +Mono messageByUsername = ReactiveSecurityContextHolder.getContext() + .map(SecurityContext::getAuthentication) + .map(Authentication::getName) + .flatMap(this::findMessageByUsername) + // In a WebFlux application the `subscriberContext` is automatically setup using `ReactorContextWebFilter` + .subscriberContext(ReactiveSecurityContextHolder.withAuthentication(authentication)); + +StepVerifier.create(messageByUsername) + .expectNext("Hi user") + .verifyComplete(); +---- + +with `this::findMessageByUsername` defined as: + +[source,java] +---- +Mono findMessageByUsername(String username) { + return Mono.just("Hi " + username); +} +---- + +Below is a minimal method security configuration when using method security in reactive applications. + +[source,java] +---- +@EnableReactiveMethodSecurity +public class SecurityConfig { + @Bean + public MapReactiveUserDetailsService userDetailsService() { + User.UserBuilder userBuilder = User.withDefaultPasswordEncoder(); + UserDetails rob = userBuilder.username("rob").password("rob").roles("USER").build(); + UserDetails admin = userBuilder.username("admin").password("admin").roles("USER","ADMIN").build(); + return new MapReactiveUserDetailsService(rob, admin); + } +} +---- + +Consider the following class: + +[source,java] +---- +@Component +public class HelloWorldMessageService { + @PreAuthorize("hasRole('ADMIN')") + public Mono findMessage() { + return Mono.just("Hello World!"); + } +} +---- + +Combined with our configuration above, `@PreAuthorize("hasRole('ADMIN')")` will ensure that `findByMessage` is only invoked by a user with the role `ADMIN`. +It is important to note that any of the expressions in standard method security work for `@EnableReactiveMethodSecurity`. +However, at this time we only support return type of `Boolean` or `boolean` of the expression. +This means that the expression must not block. + +When integrating with <>, the Reactor Context is automatically established by Spring Security according to the authenticated user. + +[source,java] +---- +@EnableWebFluxSecurity +@EnableReactiveMethodSecurity +public class SecurityConfig { + + @Bean + SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) throws Exception { + return http + // Demonstrate that method security works + // Best practice to use both for defense in depth + .authorizeExchange() + .anyExchange().permitAll() + .and() + .httpBasic().and() + .build(); + } + + @Bean + MapReactiveUserDetailsService userDetailsService() { + User.UserBuilder userBuilder = User.withDefaultPasswordEncoder(); + UserDetails rob = userBuilder.username("rob").password("rob").roles("USER").build(); + UserDetails admin = userBuilder.username("admin").password("admin").roles("USER","ADMIN").build(); + return new MapReactiveUserDetailsService(rob, admin); + } +} + +---- + +You can find a complete sample in {gh-samples-url}/javaconfig/hellowebflux-method[hellowebflux-method] + +=== Post Processing Configured Objects + +Spring Security's Java Configuration does not expose every property of every object that it configures. +This simplifies the configuration for a majority of users. +Afterall, if every property was exposed, users could use standard bean configuration. + +While there are good reasons to not directly expose every property, users may still need more advanced configuration options. +To address this Spring Security introduces the concept of an `ObjectPostProcessor` which can be used to modify or replace many of the Object instances created by the Java Configuration. +For example, if you wanted to configure the `filterSecurityPublishAuthorizationSuccess` property on `FilterSecurityInterceptor` you could use the following: + +[source,java] +---- +@Override +protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .anyRequest().authenticated() + .withObjectPostProcessor(new ObjectPostProcessor() { + public O postProcess( + O fsi) { + fsi.setPublishAuthorizationSuccess(true); + return fsi; + } + }); +} +---- + +[[jc-custom-dsls]] +=== Custom DSLs + +You can provide your own custom DSLs in Spring Security. +For example, you might have something that looks like this: + +[source,java] +---- +public class MyCustomDsl extends AbstractHttpConfigurer { + private boolean flag; + + @Override + public void init(H http) throws Exception { + // any method that adds another configurer + // must be done in the init method + http.csrf().disable(); + } + + @Override + public void configure(H http) throws Exception { + ApplicationContext context = http.getSharedObject(ApplicationContext.class); + + // here we lookup from the ApplicationContext. You can also just create a new instance. + MyFilter myFilter = context.getBean(MyFilter.class); + myFilter.setFlag(flag); + http.addFilterBefore(myFilter, UsernamePasswordAuthenticationFilter.class); + } + + public MyCustomDsl flag(boolean value) { + this.flag = value; + return this; + } + + public static MyCustomDsl customDsl() { + return new MyCustomDsl(); + } +} +---- + +NOTE: This is actually how methods like `HttpSecurity.authorizeRequests()` are implemented. + +The custom DSL can then be used like this: + +[source,java] +---- +@EnableWebSecurity +public class Config extends WebSecurityConfigurerAdapter { + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .apply(customDsl()) + .flag(true) + .and() + ...; + } +} +---- + +The code is invoked in the following order: + +* Code in `Config`s configure method is invoked +* Code in `MyCustomDsl`s init method is invoked +* Code in `MyCustomDsl`s configure method is invoked + +If you want, you can have `WebSecurityConfiguerAdapter` add `MyCustomDsl` by default by using `SpringFactories`. +For example, you would create a resource on the classpath named `META-INF/spring.factories` with the following contents: + +.META-INF/spring.factories +---- +org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer = sample.MyCustomDsl +---- + +Users wishing to disable the default can do so explicitly. + +[source,java] +---- +@EnableWebSecurity +public class Config extends WebSecurityConfigurerAdapter { + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .apply(customDsl()).disable() + ...; + } +} +---- diff --git a/docs/manual/src/docs/asciidoc/_includes/preface/namespace.adoc b/docs/manual/src/docs/asciidoc/_includes/preface/namespace.adoc new file mode 100644 index 0000000000..07c0a996c0 --- /dev/null +++ b/docs/manual/src/docs/asciidoc/_includes/preface/namespace.adoc @@ -0,0 +1,912 @@ + +[[ns-config]] +== Security Namespace Configuration + + +=== Introduction +Namespace configuration has been available since version 2.0 of the Spring Framework. +It allows you to supplement the traditional Spring beans application context syntax with elements from additional XML schema. +You can find more information in the Spring http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/[Reference Documentation]. +A namespace element can be used simply to allow a more concise way of configuring an individual bean or, more powerfully, to define an alternative configuration syntax which more closely matches the problem domain and hides the underlying complexity from the user. +A simple element may conceal the fact that multiple beans and processing steps are being added to the application context. +For example, adding the following element from the security namespace to an application context will start up an embedded LDAP server for testing use within the application: + +[source,xml] +---- + +---- + +This is much simpler than wiring up the equivalent Apache Directory Server beans. +The most common alternative configuration requirements are supported by attributes on the `ldap-server` element and the user is isolated from worrying about which beans they need to create and what the bean property names are. +footnote:[You can find out more about the use of the `ldap-server` element in the chapter on pass:specialcharacters,macros[<>].]. +Use of a good XML editor while editing the application context file should provide information on the attributes and elements that are available. +We would recommend that you try out the http://spring.io/tools/sts[Spring Tool Suite] as it has special features for working with standard Spring namespaces. + + +To start using the security namespace in your application context, you need to have the `spring-security-config` jar on your classpath. +Then all you need to do is add the schema declaration to your application context file: + +[source,xml] +---- + + ... + +---- + +In many of the examples you will see (and in the sample applications), we will often use "security" as the default namespace rather than "beans", which means we can omit the prefix on all the security namespace elements, making the content easier to read. +You may also want to do this if you have your application context divided up into separate files and have most of your security configuration in one of them. +Your security application context file would then start like this + +[source,xml] +---- + + ... + +---- + +We'll assume this syntax is being used from now on in this chapter. + + +==== Design of the Namespace +The namespace is designed to capture the most common uses of the framework and provide a simplified and concise syntax for enabling them within an application. +The design is based around the large-scale dependencies within the framework, and can be divided up into the following areas: + +* __Web/HTTP Security__ - the most complex part. +Sets up the filters and related service beans used to apply the framework authentication mechanisms, to secure URLs, render login and error pages and much more. + +* __Business Object (Method) Security__ - options for securing the service layer. + +* __AuthenticationManager__ - handles authentication requests from other parts of the framework. + +* __AccessDecisionManager__ - provides access decisions for web and method security. +A default one will be registered, but you can also choose to use a custom one, declared using normal Spring bean syntax. + +* __AuthenticationProvider__s - mechanisms against which the authentication manager authenticates users. +The namespace provides supports for several standard options and also a means of adding custom beans declared using a traditional syntax. + +* __UserDetailsService__ - closely related to authentication providers, but often also required by other beans. + +We'll see how to configure these in the following sections. + +[[ns-getting-started]] +=== Getting Started with Security Namespace Configuration +In this section, we'll look at how you can build up a namespace configuration to use some of the main features of the framework. +Let's assume you initially want to get up and running as quickly as possible and add authentication support and access control to an existing web application, with a few test logins. +Then we'll look at how to change over to authenticating against a database or other security repository. +In later sections we'll introduce more advanced namespace configuration options. + +[[ns-web-xml]] +==== web.xml Configuration +The first thing you need to do is add the following filter declaration to your `web.xml` file: + +[source,xml] +---- + +springSecurityFilterChain +org.springframework.web.filter.DelegatingFilterProxy + + + +springSecurityFilterChain +/* + +---- + +This provides a hook into the Spring Security web infrastructure. +`DelegatingFilterProxy` is a Spring Framework class which delegates to a filter implementation which is defined as a Spring bean in your application context. +In this case, the bean is named "springSecurityFilterChain", which is an internal infrastructure bean created by the namespace to handle web security. +Note that you should not use this bean name yourself. +Once you've added this to your `web.xml`, you're ready to start editing your application context file. +Web security services are configured using the `` element. + +[[ns-minimal]] +==== A Minimal Configuration +All you need to enable web security to begin with is + +[source,xml] +---- + + + + + +---- + +Which says that we want all URLs within our application to be secured, requiring the role `ROLE_USER` to access them, we want to log in to the application using a form with username and password, and that we want a logout URL registered which will allow us to log out of the application. +`` element is the parent for all web-related namespace functionality. +The `` element defines a `pattern` which is matched against the URLs of incoming requests using an ant path style syntax footnote:[See the section on pass:specialcharacters,macros[<>] in the Web Application Infrastructure chapter for more details on how matches are actually performed.]. +You can also use regular-expression matching as an alternative (see the namespace appendix for more details). +The `access` attribute defines the access requirements for requests matching the given pattern. +With the default configuration, this is typically a comma-separated list of roles, one of which a user must have to be allowed to make the request. +The prefix"ROLE_" is a marker which indicates that a simple comparison with the user's authorities should be made. +In other words, a normal role-based check should be used. +Access-control in Spring Security is not limited to the use of simple roles (hence the use of the prefix to differentiate between different types of security attributes). +We'll see later how the interpretation can vary footnote:[The interpretation of the comma-separated values in the `access` attribute depends on the implementation of the pass:specialcharacters,macros[<>] which is used. +In Spring Security 3.0, the attribute can also be populated with an pass:specialcharacters,macros[<>]. + + +[NOTE] +==== + +You can use multiple `` elements to define different access requirements for different sets of URLs, but they will be evaluated in the order listed and the first match will be used. +So you must put the most specific matches at the top. +You can also add a `method` attribute to limit the match to a particular HTTP method (`GET`, `POST`, `PUT` etc.). + +==== + +To add some users, you can define a set of test data directly in the namespace: + +[source,xml] +---- + + + + + + + + + +---- + +This is an example of a secure way of storing the same passwords. +The password is prefixed with `{bcrypt}` to instruct `DelegatingPasswordEncoder`, which supports any configured `PasswordEncoder` for matching, that the passwords are hashed using BCrypt: + +[source,xml] +---- + + + + + + + + + + +---- + + + +[subs="quotes"] +**** +If you are familiar with pre-namespace versions of the framework, you can probably already guess roughly what's going on here. +The `` element is responsible for creating a `FilterChainProxy` and the filter beans which it uses. +Common problems like incorrect filter ordering are no longer an issue as the filter positions are predefined. + +The `` element creates a `DaoAuthenticationProvider` bean and the `` element creates an `InMemoryDaoImpl`. +All `authentication-provider` elements must be children of the `` element, which creates a `ProviderManager` and registers the authentication providers with it. +You can find more detailed information on the beans that are created in the <>. +It's worth cross-checking this if you want to start understanding what the important classes in the framework are and how they are used, particularly if you want to customise things later. +**** + +The configuration above defines two users, their passwords and their roles within the application (which will be used for access control). +It is also possible to load user information from a standard properties file using the `properties` attribute on `user-service`. +See the section on <> for more details on the file format. +Using the `` element means that the user information will be used by the authentication manager to process authentication requests. +You can have multiple `` elements to define different authentication sources and each will be consulted in turn. + +At this point you should be able to start up your application and you will be required to log in to proceed. +Try it out, or try experimenting with the "tutorial" sample application that comes with the project. + + +[[ns-form-and-basic]] +==== Form and Basic Login Options +You might be wondering where the login form came from when you were prompted to log in, since we made no mention of any HTML files or JSPs. +In fact, since we didn't explicitly set a URL for the login page, Spring Security generates one automatically, based on the features that are enabled and using standard values for the URL which processes the submitted login, the default target URL the user will be sent to after logging in and so on. +However, the namespace offers plenty of support to allow you to customize these options. +For example, if you want to supply your own login page, you could use: + +[source,xml] +---- + + + + + +---- + +Also note that we've added an extra `intercept-url` element to say that any requests for the login page should be available to anonymous users footnote:[See the chapter on pass:specialcharacters,macros[<>]] and also the <> class for more details on how the value `IS_AUTHENTICATED_ANONYMOUSLY` is processed.]. +Otherwise the request would be matched by the pattern /** and it wouldn't be possible to access the login page itself! +This is a common configuration error and will result in an infinite loop in the application. +Spring Security will emit a warning in the log if your login page appears to be secured. +It is also possible to have all requests matching a particular pattern bypass the security filter chain completely, by defining a separate `http` element for the pattern like this: + + +[source,xml] +---- + + + + + + + +---- + +From Spring Security 3.1 it is now possible to use multiple `http` elements to define separate security filter chain configurations for different request patterns. +If the `pattern` attribute is omitted from an `http` element, it matches all requests. +Creating an unsecured pattern is a simple example of this syntax, where the pattern is mapped to an empty filter chain footnote:[The use of multiple `` elements is an important feature, allowing the namespace to simultaneously support both stateful and stateless paths within the same application, for example. +The previous syntax, using the attribute `filters="none"` on an `intercept-url` element is incompatible with this change and is no longer supported in 3.1.]. +We'll look at this new syntax in more detail in the chapter on the <>. + +It's important to realise that these unsecured requests will be completely oblivious to any Spring Security web-related configuration or additional attributes such as `requires-channel`, so you will not be able to access information on the current user or call secured methods during the request. +Use `access='IS_AUTHENTICATED_ANONYMOUSLY'` as an alternative if you still want the security filter chain to be applied. + +If you want to use basic authentication instead of form login, then change the configuration to + +[source,xml] +---- + + + + +---- + +Basic authentication will then take precedence and will be used to prompt for a login when a user attempts to access a protected resource. +Form login is still available in this configuration if you wish to use it, for example through a login form embedded in another web page. + +[[ns-form-target]] +===== Setting a Default Post-Login Destination +If a form login isn't prompted by an attempt to access a protected resource, the `default-target-url` option comes into play. +This is the URL the user will be taken to after successfully logging in, and defaults to "/". +You can also configure things so that the user __always__ ends up at this page (regardless of whether the login was "on-demand" or they explicitly chose to log in) by setting the `always-use-default-target` attribute to "true". +This is useful if your application always requires that the user starts at a "home" page, for example: + +[source,xml] +---- + + + + + +---- + +For even more control over the destination, you can use the `authentication-success-handler-ref` attribute as an alternative to `default-target-url`. +The referenced bean should be an instance of `AuthenticationSuccessHandler`. +You'll find more on this in the <> chapter and also in the namespace appendix, as well as information on how to customize the flow when authentication fails. + +[[ns-logout]] +==== Logout Handling +The `logout` element adds support for logging out by navigating to a particular URL. +The default logout URL is `/logout`, but you can set it to something else using the `logout-url` attribute. +More information on other available attributes may be found in the namespace appendix. + +[[ns-auth-providers]] +==== Using other Authentication Providers +In practice you will need a more scalable source of user information than a few names added to the application context file. +Most likely you will want to store your user information in something like a database or an LDAP server. +LDAP namespace configuration is dealt with in the <>, so we won't cover it here. +If you have a custom implementation of Spring Security's `UserDetailsService`, called "myUserDetailsService" in your application context, then you can authenticate against this using + +[source,xml] +---- + + + + + +---- + +If you want to use a database, then you can use + +[source,xml] +---- + + + + + +---- + +Where "securityDataSource" is the name of a `DataSource` bean in the application context, pointing at a database containing the standard Spring Security <>. +Alternatively, you could configure a Spring Security `JdbcDaoImpl` bean and point at that using the `user-service-ref` attribute: + +[source,xml] +---- + + + + + + + +---- + +You can also use standard `AuthenticationProvider` beans as follows + +[source,xml] +---- + + + + + +---- + +where `myAuthenticationProvider` is the name of a bean in your application context which implements `AuthenticationProvider`. +You can use multiple `authentication-provider` elements, in which case the providers will be queried in the order they are declared. +See <> for more information on how the Spring Security `AuthenticationManager` is configured using the namespace. + +[[ns-password-encoder]] +===== Adding a Password Encoder +Passwords should always be encoded using a secure hashing algorithm designed for the purpose (not a standard algorithm like SHA or MD5). +This is supported by the `` element. +With bcrypt encoded passwords, the original authentication provider configuration would look like this: + +[source,xml] +---- + + + + + + + + + + + + +---- + + + +bcrypt is a good choice for most cases, unless you have a legacy system which forces you to use a different algorithm. +If you are using a simple hashing algorithm or, even worse, storing plain text passwords, then you should consider migrating to a more secure option like bcrypt. + +[[ns-web-advanced]] +=== Advanced Web Features + +[[ns-remember-me]] +==== Remember-Me Authentication +See the separate <> for information on remember-me namespace configuration. + +[[ns-requires-channel]] +==== Adding HTTP/HTTPS Channel Security +If your application supports both HTTP and HTTPS, and you require that particular URLs can only be accessed over HTTPS, then this is directly supported using the `requires-channel` attribute on ``: + +[source,xml] +---- + + + +... + +---- + +With this configuration in place, if a user attempts to access anything matching the "/secure/**" pattern using HTTP, they will first be redirected to an HTTPS URL footnote:[For more details on how channel-processing is implemented, see the Javadoc for `ChannelProcessingFilter` and related classes.]. +The available options are "http", "https" or "any". +Using the value "any" means that either HTTP or HTTPS can be used. + +If your application uses non-standard ports for HTTP and/or HTTPS, you can specify a list of port mappings as follows: + +[source,xml] +---- + +... + + + + +---- + +Note that in order to be truly secure, an application should not use HTTP at all or switch between HTTP and HTTPS. +It should start in HTTPS (with the user entering an HTTPS URL) and use a secure connection throughout to avoid any possibility of man-in-the-middle attacks. + +[[ns-session-mgmt]] +==== Session Management + +===== Detecting Timeouts +You can configure Spring Security to detect the submission of an invalid session ID and redirect the user to an appropriate URL. +This is achieved through the `session-management` element: + +[source,xml] +---- + +... + + +---- + +Note that if you use this mechanism to detect session timeouts, it may falsely report an error if the user logs out and then logs back in without closing the browser. +This is because the session cookie is not cleared when you invalidate the session and will be resubmitted even if the user has logged out. +You may be able to explicitly delete the JSESSIONID cookie on logging out, for example by using the following syntax in the logout handler: + +[source,xml] +---- + + + +---- + +Unfortunately this can't be guaranteed to work with every servlet container, so you will need to test it in your environment + +[NOTE] +==== +If you are running your application behind a proxy, you may also be able to remove the session cookie by configuring the proxy server. +For example, using Apache HTTPD's mod_headers, the following directive would delete the `JSESSIONID` cookie by expiring it in the response to a logout request (assuming the application is deployed under the path `/tutorial`): + +[source,xml] +---- + +Header always set Set-Cookie "JSESSIONID=;Path=/tutorial;Expires=Thu, 01 Jan 1970 00:00:00 GMT" + +---- +==== + + +[[ns-concurrent-sessions]] +===== Concurrent Session Control +If you wish to place constraints on a single user's ability to log in to your application, Spring Security supports this out of the box with the following simple additions. +First you need to add the following listener to your `web.xml` file to keep Spring Security updated about session lifecycle events: + +[source,xml] +---- + + + org.springframework.security.web.session.HttpSessionEventPublisher + + +---- + +Then add the following lines to your application context: + +[source,xml] +---- + +... + + + + +---- + +This will prevent a user from logging in multiple times - a second login will cause the first to be invalidated. +Often you would prefer to prevent a second login, in which case you can use + +[source,xml] +---- + +... + + + + +---- + +The second login will then be rejected. +By "rejected", we mean that the user will be sent to the `authentication-failure-url` if form-based login is being used. +If the second authentication takes place through another non-interactive mechanism, such as "remember-me", an "unauthorized" (401) error will be sent to the client. +If instead you want to use an error page, you can add the attribute `session-authentication-error-url` to the `session-management` element. + +If you are using a customized authentication filter for form-based login, then you have to configure concurrent session control support explicitly. +More details can be found in the <>. + +[[ns-session-fixation]] +===== Session Fixation Attack Protection +http://en.wikipedia.org/wiki/Session_fixation[Session fixation] attacks are a potential risk where it is possible for a malicious attacker to create a session by accessing a site, then persuade another user to log in with the same session (by sending them a link containing the session identifier as a parameter, for example). +Spring Security protects against this automatically by creating a new session or otherwise changing the session ID when a user logs in. +If you don't require this protection, or it conflicts with some other requirement, you can control the behavior using the `session-fixation-protection` attribute on ``, which has four options + +* `none` - Don't do anything. +The original session will be retained. + +* `newSession` - Create a new "clean" session, without copying the existing session data (Spring Security-related attributes will still be copied). + +* `migrateSession` - Create a new session and copy all existing session attributes to the new session. +This is the default in Servlet 3.0 or older containers. + +* `changeSessionId` - Do not create a new session. +Instead, use the session fixation protection provided by the Servlet container (`HttpServletRequest#changeSessionId()`). +This option is only available in Servlet 3.1 (Java EE 7) and newer containers. +Specifying it in older containers will result in an exception. +This is the default in Servlet 3.1 and newer containers. + + +When session fixation protection occurs, it results in a `SessionFixationProtectionEvent` being published in the application context. +If you use `changeSessionId`, this protection will __also__ result in any `javax.servlet.http.HttpSessionIdListener` s being notified, so use caution if your code listens for both events. +See the <> chapter for additional information. + + +[[ns-openid]] +==== OpenID Support +The namespace supports http://openid.net/[OpenID] login either instead of, or in addition to normal form-based login, with a simple change: + +[source,xml] +---- + + + + +---- + +You should then register yourself with an OpenID provider (such as myopenid.com), and add the user information to your in-memory ``: + +[source,xml] +---- + +---- + +You should be able to login using the `myopenid.com` site to authenticate. +It is also possible to select a specific `UserDetailsService` bean for use OpenID by setting the `user-service-ref` attribute on the `openid-login` element. +See the previous section on <> for more information. +Note that we have omitted the password attribute from the above user configuration, since this set of user data is only being used to load the authorities for the user. +A random password will be generated internally, preventing you from accidentally using this user data as an authentication source elsewhere in your configuration. + + +===== Attribute Exchange +Support for OpenID http://openid.net/specs/openid-attribute-exchange-1_0.html[attribute exchange]. +As an example, the following configuration would attempt to retrieve the email and full name from the OpenID provider, for use by the application: + +[source,xml] +---- + + + + + + +---- + +The "type" of each OpenID attribute is a URI, determined by a particular schema, in this case http://axschema.org/[http://axschema.org/]. +If an attribute must be retrieved for successful authentication, the `required` attribute can be set. +The exact schema and attributes supported will depend on your OpenID provider. +The attribute values are returned as part of the authentication process and can be accessed afterwards using the following code: + +[source,java] +---- +OpenIDAuthenticationToken token = + (OpenIDAuthenticationToken)SecurityContextHolder.getContext().getAuthentication(); +List attributes = token.getAttributes(); +---- + +The `OpenIDAttribute` contains the attribute type and the retrieved value (or values in the case of multi-valued attributes). +We'll see more about how the `SecurityContextHolder` class is used when we look at core Spring Security components in the <> chapter. +Multiple attribute exchange configurations are also be supported, if you wish to use multiple identity providers. +You can supply multiple `attribute-exchange` elements, using an `identifier-matcher` attribute on each. +This contains a regular expression which will be matched against the OpenID identifier supplied by the user. +See the OpenID sample application in the codebase for an example configuration, providing different attribute lists for the Google, Yahoo and MyOpenID providers. + + +[[ns-headers]] +==== Response Headers +For additional information on how to customize the headers element refer to the <> section of the reference. + + +[[ns-custom-filters]] +==== Adding in Your Own Filters +If you've used Spring Security before, you'll know that the framework maintains a chain of filters in order to apply its services. +You may want to add your own filters to the stack at particular locations or use a Spring Security filter for which there isn't currently a namespace configuration option (CAS, for example). +Or you might want to use a customized version of a standard namespace filter, such as the `UsernamePasswordAuthenticationFilter` which is created by the `` element, taking advantage of some of the extra configuration options which are available by using the bean explicitly. +How can you do this with namespace configuration, since the filter chain is not directly exposed? + +The order of the filters is always strictly enforced when using the namespace. +When the application context is being created, the filter beans are sorted by the namespace handling code and the standard Spring Security filters each have an alias in the namespace and a well-known position. + +[NOTE] +==== +In previous versions, the sorting took place after the filter instances had been created, during post-processing of the application context. +In version 3.0+ the sorting is now done at the bean metadata level, before the classes have been instantiated. +This has implications for how you add your own filters to the stack as the entire filter list must be known during the parsing of the `` element, so the syntax has changed slightly in 3.0. +==== + +The filters, aliases and namespace elements/attributes which create the filters are shown in <>. +The filters are listed in the order in which they occur in the filter chain. + +[[filter-stack]] +.Standard Filter Aliases and Ordering +|=== +| Alias | Filter Class | Namespace Element or Attribute + +| CHANNEL_FILTER +| `ChannelProcessingFilter` +| `http/intercept-url@requires-channel` + +| SECURITY_CONTEXT_FILTER +| `SecurityContextPersistenceFilter` +| `http` + +| CONCURRENT_SESSION_FILTER +| `ConcurrentSessionFilter` +| `session-management/concurrency-control` + +| HEADERS_FILTER +| `HeaderWriterFilter` +| `http/headers` + +| CSRF_FILTER +| `CsrfFilter` +| `http/csrf` + +| LOGOUT_FILTER +| `LogoutFilter` +| `http/logout` + +| X509_FILTER +| `X509AuthenticationFilter` +| `http/x509` + +| PRE_AUTH_FILTER +| `AbstractPreAuthenticatedProcessingFilter` Subclasses +| N/A + +| CAS_FILTER +| `CasAuthenticationFilter` +| N/A + +| FORM_LOGIN_FILTER +| `UsernamePasswordAuthenticationFilter` +| `http/form-login` + +| BASIC_AUTH_FILTER +| `BasicAuthenticationFilter` +| `http/http-basic` + +| SERVLET_API_SUPPORT_FILTER +| `SecurityContextHolderAwareRequestFilter` +| `http/@servlet-api-provision` + +| JAAS_API_SUPPORT_FILTER +| `JaasApiIntegrationFilter` +| `http/@jaas-api-provision` + +| REMEMBER_ME_FILTER +| `RememberMeAuthenticationFilter` +| `http/remember-me` + +| ANONYMOUS_FILTER +| `AnonymousAuthenticationFilter` +| `http/anonymous` + +| SESSION_MANAGEMENT_FILTER +| `SessionManagementFilter` +| `session-management` + +| EXCEPTION_TRANSLATION_FILTER +| `ExceptionTranslationFilter` +| `http` + +| FILTER_SECURITY_INTERCEPTOR +| `FilterSecurityInterceptor` +| `http` + +| SWITCH_USER_FILTER +| `SwitchUserFilter` +| N/A +|=== + +You can add your own filter to the stack, using the `custom-filter` element and one of these names to specify the position your filter should appear at: + +[source,xml] +---- + + + + + +---- + +You can also use the `after` or `before` attributes if you want your filter to be inserted before or after another filter in the stack. +The names "FIRST" and "LAST" can be used with the `position` attribute to indicate that you want your filter to appear before or after the entire stack, respectively. + +.Avoiding filter position conflicts +[TIP] +==== + +If you are inserting a custom filter which may occupy the same position as one of the standard filters created by the namespace then it's important that you don't include the namespace versions by mistake. +Remove any elements which create filters whose functionality you want to replace. + +Note that you can't replace filters which are created by the use of the `` element itself - `SecurityContextPersistenceFilter`, `ExceptionTranslationFilter` or `FilterSecurityInterceptor`. +Some other filters are added by default, but you can disable them. +An `AnonymousAuthenticationFilter` is added by default and unless you have <> disabled, a `SessionManagementFilter` will also be added to the filter chain. + +==== + +If you're replacing a namespace filter which requires an authentication entry point (i.e. where the authentication process is triggered by an attempt by an unauthenticated user to access to a secured resource), you will need to add a custom entry point bean too. + + +[[ns-entry-point-ref]] +===== Setting a Custom AuthenticationEntryPoint +If you aren't using form login, OpenID or basic authentication through the namespace, you may want to define an authentication filter and entry point using a traditional bean syntax and link them into the namespace, as we've just seen. +The corresponding `AuthenticationEntryPoint` can be set using the `entry-point-ref` attribute on the `` element. + +The CAS sample application is a good example of the use of custom beans with the namespace, including this syntax. +If you aren't familiar with authentication entry points, they are discussed in the <> chapter. + + +[[ns-method-security]] +=== Method Security +From version 2.0 onwards Spring Security has improved support substantially for adding security to your service layer methods. +It provides support for JSR-250 annotation security as well as the framework's original `@Secured` annotation. +From 3.0 you can also make use of new <>. +You can apply security to a single bean, using the `intercept-methods` element to decorate the bean declaration, or you can secure multiple beans across the entire service layer using the AspectJ style pointcuts. + + +[[ns-global-method]] +==== The Element +This element is used to enable annotation-based security in your application (by setting the appropriate attributes on the element), and also to group together security pointcut declarations which will be applied across your entire application context. +You should only declare one `` element. +The following declaration would enable support for Spring Security's `@Secured`: + +[source,xml] +---- + +---- + +Adding an annotation to a method (on an class or interface) would then limit the access to that method accordingly. +Spring Security's native annotation support defines a set of attributes for the method. +These will be passed to the `AccessDecisionManager` for it to make the actual decision: + +[source,java] +---- +public interface BankService { + +@Secured("IS_AUTHENTICATED_ANONYMOUSLY") +public Account readAccount(Long id); + +@Secured("IS_AUTHENTICATED_ANONYMOUSLY") +public Account[] findAccounts(); + +@Secured("ROLE_TELLER") +public Account post(Account account, double amount); +} +---- + +Support for JSR-250 annotations can be enabled using + +[source,xml] +---- + +---- + +These are standards-based and allow simple role-based constraints to be applied but do not have the power Spring Security's native annotations. +To use the new expression-based syntax, you would use + +[source,xml] +---- + +---- + +and the equivalent Java code would be + +[source,java] +---- +public interface BankService { + +@PreAuthorize("isAnonymous()") +public Account readAccount(Long id); + +@PreAuthorize("isAnonymous()") +public Account[] findAccounts(); + +@PreAuthorize("hasAuthority('ROLE_TELLER')") +public Account post(Account account, double amount); +} +---- + +Expression-based annotations are a good choice if you need to define simple rules that go beyond checking the role names against the user's list of authorities. + +[NOTE] +==== +The annotated methods will only be secured for instances which are defined as Spring beans (in the same application context in which method-security is enabled). +If you want to secure instances which are not created by Spring (using the `new` operator, for example) then you need to use AspectJ. +==== + +[NOTE] +==== +You can enable more than one type of annotation in the same application, but only one type should be used for any interface or class as the behaviour will not be well-defined otherwise. +If two annotations are found which apply to a particular method, then only one of them will be applied. +==== + +[[ns-protect-pointcut]] +===== Adding Security Pointcuts using protect-pointcut + +The use of `protect-pointcut` is particularly powerful, as it allows you to apply security to many beans with only a simple declaration. +Consider the following example: + +[source,xml] +---- + + + +---- + +This will protect all methods on beans declared in the application context whose classes are in the `com.mycompany` package and whose class names end in "Service". +Only users with the `ROLE_USER` role will be able to invoke these methods. +As with URL matching, the most specific matches must come first in the list of pointcuts, as the first matching expression will be used. +Security annotations take precedence over pointcuts. + +[[ns-access-manager]] +=== The Default AccessDecisionManager +This section assumes you have some knowledge of the underlying architecture for access-control within Spring Security. +If you don't you can skip it and come back to it later, as this section is only really relevant for people who need to do some customization in order to use more than simple role-based security. + +When you use a namespace configuration, a default instance of `AccessDecisionManager` is automatically registered for you and will be used for making access decisions for method invocations and web URL access, based on the access attributes you specify in your `intercept-url` and `protect-pointcut` declarations (and in annotations if you are using annotation secured methods). + +The default strategy is to use an `AffirmativeBased` `AccessDecisionManager` with a `RoleVoter` and an `AuthenticatedVoter`. +You can find out more about these in the chapter on <>. + + +[[ns-custom-access-mgr]] +==== Customizing the AccessDecisionManager +If you need to use a more complicated access control strategy then it is easy to set an alternative for both method and web security. + +For method security, you do this by setting the `access-decision-manager-ref` attribute on `global-method-security` to the `id` of the appropriate `AccessDecisionManager` bean in the application context: + +[source,xml] +---- + +... + +---- + +The syntax for web security is the same, but on the `http` element: + +[source,xml] +---- + +... + +---- + +[[ns-auth-manager]] +=== The Authentication Manager and the Namespace +The main interface which provides authentication services in Spring Security is the `AuthenticationManager`. +This is usually an instance of Spring Security's `ProviderManager` class, which you may already be familiar with if you've used the framework before. +If not, it will be covered later, in the <>. +The bean instance is registered using the `authentication-manager` namespace element. +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 `AuthenticationProvider` s that are used. + +You may want to register additional `AuthenticationProvider` beans with the `ProviderManager` and you can do this using the `` element with the `ref` attribute, where the value of the attribute is the name of the provider bean you want to add. +For example: + +[source,xml] +---- + + + + + +... + +---- + +Another common requirement is that another bean in the context may require a reference to the `AuthenticationManager`. +You can easily register an alias for the `AuthenticationManager` and use this name elsewhere in your application context. + +[source,xml] +---- + +... + + + + +... + +---- diff --git a/docs/manual/src/docs/asciidoc/_includes/preface/samples.adoc b/docs/manual/src/docs/asciidoc/_includes/preface/samples.adoc new file mode 100644 index 0000000000..708a64a2bc --- /dev/null +++ b/docs/manual/src/docs/asciidoc/_includes/preface/samples.adoc @@ -0,0 +1,119 @@ + + +[[sample-apps]] +== Sample Applications +There are several sample web applications that are available with the project. +To avoid an overly large download, only the "tutorial" and "contacts" samples are included in the distribution zip file. +The others can be built directly from the source which you can obtain as described in <>. +It's easy to build the project yourself and there's more information on the project web site at http://spring.io/spring-security/[http://spring.io/spring-security/]. +All paths referred to in this chapter are relative to the project source directory. + + +[[tutorial-sample]] +=== Tutorial Sample +The tutorial sample is a nice basic example to get you started. +It uses simple namespace configuration throughout. +The compiled application is included in the distribution zip file, ready to be deployed into your web container (`spring-security-samples-tutorial-3.1.x.war`). +The <> authentication mechanism is used in combination with the commonly-used <> authentication provider to automatically remember the login using cookies. + +We recommend you start with the tutorial sample, as the XML is minimal and easy to follow. +Most importantly, you can easily add this one XML file (and its corresponding `web.xml` entries) to your existing application. +Only when this basic integration is achieved do we suggest you attempt adding in method authorization or domain object security. + + +[[contacts-sample]] +=== Contacts +The Contacts Sample is an advanced example in that it illustrates the more powerful features of domain object access control lists (ACLs) in addition to basic application security. +The application provides an interface with which the users are able to administer a simple database of contacts (the domain objects). + +To deploy, simply copy the WAR file from Spring Security distribution into your container's `webapps` directory. +The war should be called `spring-security-samples-contacts-3.1.x.war` (the appended version number will vary depending on what release you are using). + +After starting your container, check the application can load. +Visit http://localhost:8080/contacts (or whichever URL is appropriate for your web container and the WAR you deployed). + +Next, click "Debug". +You will be prompted to authenticate, and a series of usernames and passwords are suggested on that page. +Simply authenticate with any of these and view the resulting page. +It should contain a success message similar to the following: +---- + +Security Debug Information + +Authentication object is of type: +org.springframework.security.authentication.UsernamePasswordAuthenticationToken + +Authentication object as a String: + +org.springframework.security.authentication.UsernamePasswordAuthenticationToken@1f127853: +Principal: org.springframework.security.core.userdetails.User@b07ed00: Username: rod; \ +Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; +credentialsNonExpired: true; AccountNonLocked: true; \ +Granted Authorities: ROLE_SUPERVISOR, ROLE_USER; \ +Password: [PROTECTED]; Authenticated: true; \ +Details: org.springframework.security.web.authentication.WebAuthenticationDetails@0: \ +RemoteIpAddress: 127.0.0.1; SessionId: 8fkp8t83ohar; \ +Granted Authorities: ROLE_SUPERVISOR, ROLE_USER + +Authentication object holds the following granted authorities: + +ROLE_SUPERVISOR (getAuthority(): ROLE_SUPERVISOR) +ROLE_USER (getAuthority(): ROLE_USER) + +Success! Your web filters appear to be properly configured! + +---- + + +Once you successfully receive the above message, return to the sample application's home page and click "Manage". +You can then try out the application. +Notice that only the contacts available to the currently logged on user are displayed, and only users with `ROLE_SUPERVISOR` are granted access to delete their contacts. +Behind the scenes, the `MethodSecurityInterceptor` is securing the business objects. + +The application allows you to modify the access control lists associated with different contacts. +Be sure to give this a try and understand how it works by reviewing the application context XML files. + + +[[ldap-sample]] +=== LDAP Sample +The LDAP sample application provides a basic configuration and sets up both a namespace configuration and an equivalent configuration using traditional beans, both in the same application context file. +This means there are actually two identical authentication providers configured in this application. + + +[[openid-sample]] +=== OpenID Sample +The OpenID sample demonstrates how to use the namespace to configure OpenID and how to set up http://openid.net/specs/openid-attribute-exchange-1_0.html[attribute exchange] configurations for Google, Yahoo and MyOpenID identity providers (you can experiment with adding others if you wish). +It uses the JQuery-based http://code.google.com/p/openid-selector/[openid-selector] project to provide a user-friendly login page which allows the user to easily select a provider, rather than typing in the full OpenID identifier. + +The application differs from normal authentication scenarios in that it allows any user to access the site (provided their OpenID authentication is successful). +The first time you login, you will get a "Welcome [your name]"" message. +If you logout and log back in (with the same OpenID identity) then this should change to "Welcome Back". +This is achieved by using a custom `UserDetailsService` which assigns a standard role to any user and stores the identities internally in a map. +Obviously a real application would use a database instead. +Have a look at the source form more information. +This class also takes into account the fact that different attributes may be returned from different providers and builds the name with which it addresses the user accordingly. + + +[[cas-sample]] +=== CAS Sample +The CAS sample requires that you run both a CAS server and CAS client. +It isn't included in the distribution so you should check out the project code as described in <>. +You'll find the relevant files under the `sample/cas` directory. +There's also a `Readme.txt` file in there which explains how to run both the server and the client directly from the source tree, complete with SSL support. + + +[[jaas-sample]] +=== JAAS Sample +The JAAS sample is very simple example of how to use a JAAS LoginModule with Spring Security. +The provided LoginModule will successfully authenticate a user if the username equals the password otherwise a LoginException is thrown. +The AuthorityGranter used in this example always grants the role ROLE_USER. +The sample application also demonstrates how to run as the JAAS Subject returned by the LoginModule by setting <> equal to "true". + + +[[preauth-sample]] +=== Pre-Authentication Sample +This sample application demonstrates how to wire up beans from the <> framework to make use of login information from a Java EE container. +The user name and roles are those setup by the container. + +The code is in `samples/preauth`. + diff --git a/docs/manual/src/docs/asciidoc/_includes/preface/whats-new.adoc b/docs/manual/src/docs/asciidoc/_includes/preface/whats-new.adoc new file mode 100644 index 0000000000..8e5a1eef66 --- /dev/null +++ b/docs/manual/src/docs/asciidoc/_includes/preface/whats-new.adoc @@ -0,0 +1,16 @@ +[[new]] +== What's New in Spring Security 5.1 + +Spring Security 5.1 provides a number of new features. +Below are the highlights of the release. + +=== New Features + +* <> +** Support for customizing when the `SecurityContext` is setup in the test +For example, `@WithMockUser(setupBefore = TestExecutionEvent.TEST_EXECUTION)` will setup a user after JUnit's `@Before` and before the test executes. +** `@WithUserDetails` now works with `ReactiveUserDetailsService` +* <> - added support for `BadCredentialsException` +* <> +** Supports resolving beans in WebFlux (was already supported in Spring MVC) +** Supports resolving `errorOnInvalidType` in WebFlux (was already supported in Spring MVC) diff --git a/docs/manual/src/docs/asciidoc/index.adoc b/docs/manual/src/docs/asciidoc/index.adoc index d560ce60c2..9648eeadaa 100644 --- a/docs/manual/src/docs/asciidoc/index.adoc +++ b/docs/manual/src/docs/asciidoc/index.adoc @@ -6,7 +6,7 @@ Ben Alex; Luke Taylor; Rob Winch; Gunnar Hillert; Joe Grandja; Jay Bryant Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications. -include::{include-dir}/preface.adoc[] +include::{include-dir}/preface/index.adoc[] include::{include-dir}/architecture.adoc[]