首页 > 代码库 > Spring Security Java Config Preview--官方

Spring Security Java Config Preview--官方

【2】https://spring.io/blog/2013/07/03/spring-security-java-config-preview-web-security/

【3】https://spring.io/blog/2013/07/04/spring-security-java-config-preview-method-security/

【4】https://spring.io/blog/2013/07/05/spring-security-java-config-preview-oauth/

【5】https://spring.io/blog/2013/07/11/spring-security-java-config-preview-readability/

Spring Security Java Config Preview: Introduction

Yesterday I announced the release of Spring Security Java Configuration support and the release of Spring Security 3.2.0.M2 which contains Java Configuration support.

Spring Security‘s Java Configuration support is intended to provide a complete replacement of the XML namespace configuration. It is also designed to be extensible, so that Spring Security‘s extension projects can work nicely with the Java Configuration support.

In this first post of a five part Spring Security Java Configuration blog series, I discuss the logistics of the Spring Security Java Configuration project.

 

“Required Versions”
Regardless of how you decide to integrate with Spring Security, it is important to ensure you are using Spring 3.2.3.RELEASE+ to ensure that you avoid SPR-10546.

 

Availability

Before we get started, I’d like to talk about the two modules that Spring Security’s Java Configuration can be found.

Availability in Spring Security 3.2.0.M2+

Spring Security Java Configuration has been copied into the Spring Security 3.2.0.M2+ code base. This means if you are using Spring Security 3.2.0.M2+ you should ensure to have the spring-security-config jar on your classpath. For example, you might have the following entries in your Maven pom.xml:


<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>3.2.0.M2</version></dependency><repository> <id>repository.springsource.milestone</id> <name>SpringSource Milestone Repository</name> <url>http://repo.springsource.org/milestone</url></repository>

 

“Future Availability”
Currently there are no plans to provide any updates to spring-security-javaconfig. Instead, users will be encouraged to update to Spring Security 3.2 when it is released.

 

Availability for Spring Security 3.1.4.RELEASE+

In order to encourage users to try Spring Security Java Configuration, it is also available as a standalone module called spring-security-javaconfig. For example, you might have the following entries in your Maven pom.xml:


<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-javaconfig</artifactId> <version>1.0.0.M1</version></dependency><repository> <id>repository.springsource.milestone</id> <name>SpringSource Milestone Repository</name> <url>http://repo.springsource.org/milestone</url></repository>

 

SpringOne2GX 2013
Want to learn more about Spring Security 3.2 release? Register for SpringOne2GX 2013, September 9-12 in Santa Clara, California where I will be discussing Spring Security 3.2 in more detail! There conference will have tons of great sessions to quickly catch you up with everything that is happening in the Spring, Groovy, and Grails communities! Don’t forget to register by Aug 9th to save Want to learn more about Spring Security 3.2 release? Register for SpringOne2GX 2013, September 9-12 in Santa Clara, California where I will be discussing Spring Security 3.2 in more detail! There conference will have tons of great sessions to quickly catch you up with everything that is happening in the Spring, Groovy, and Grails communities! Don’t forget to register by Aug 9th to save $200 with the Early discount!
00 with the Early discount!

 

Feedback Please

If you encounter a bug, have an idea for improvement, etc please do not hesitate to bring it up! We want to hear your thoughts so we can ensure we get it right before the code is generally available. Trying out new features early is a good and simple way to give back to the community. This also ensures that the features you want are present and working as you think they should.

Please log any issues or feature requests to the Spring Security JIRA under the category "Java Config". After logging a JIRA, we encourage (but do not require) you to submit your changes in a pull request. You can read more about how to do this in the Contributor Guidelines

If you have questions on how to do something, please use the Spring Security forums or Stack Overflow with the tag spring-security (I will be monitoring them closely). If you have specific comments questions about this blog, feel free to leave a comment. Using the appropriate tools will help make it easier for everyone.

Conclusion

You should now have a clear idea of why Spring Security Java Configuration exists it multiple places, where you will find updates, and where to log issues to. In the next post, we will walk through using Spring Security Java configuration in a web application.

Spring Security Java Config Preview: Web Security

Update

Users should refer to the Spring Security Reference which contains more up to date information.

Original Blog Post

In my previous post, I introduced Spring Security Java configuration and discussed some of the logistics of the project. In this post, we will start off by walking through a very simple web security configuration. We will then spice things up a bit with configuration that has been customized some.

Hello Web Security

In this section we go through the most basic configuration for web based security. It can be broken into four steps:

  • Updating your dependencies - we demonstrated this using Maven in our previous blog post
  • Provide the Spring Security configuration - in our example this is done with a WebSecurityConfigurerAdapter
  • Ensure the Spring Security configuration is loaded - in our example this is done with AbstractAnnotationConfigDispatcherServletInitializer
  • Configure the springSecurityFilterChain - in our example this is done with AbstractSecurityWebApplicationInitializer

WebSecurityConfigurerAdapter

The @EnableWebSecurity annotation and WebSecurityConfigurerAdapter work together to provide web based security. By extending WebSecurityConfigurerAdapter and only a few lines of code we are able to do the following:

  • Require the user to be authenticated prior to accessing any URL within our application
  • Create a user with the username “user”, password “password”, and role of “ROLE_USER”
  • Enables HTTP Basic and Form based authentication
  • Spring Security will automatically render a login page and logout success page for you

@Configuration@EnableWebSecuritypublic class HelloWebSecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) { auth .inMemoryAuthentication() .withUser("user").password("password").roles("USER"); }}

For your reference, this is similar to the following XML configuration with a few exceptions:

  • Spring Security will render the login, authentication failure url, and logout success URLs
  • The login-processing-url will only be processed for HTTP POST
  • The login-page will only be processed for HTTP GET

<http use-expressions="true"> <intercept-url pattern="/**" access="authenticated"/> <logout logout-success-url="/login?logout" logout-url="/logout" /> <form-login authentication-failure-url="/login?error" login-page="/login" login-processing-url="/login" password-parameter="password" username-parameter="username" /></http><authentication-manager> <authentication-provider> <user-service> <user name="user" password="password" authorities="ROLE_USER"/> </user-service> </authentication-provider></authentication-manager>

AbstractAnnotationConfigDispatcherServletInitializer

The next step is to ensure that the root ApplicationContext includes the HelloWebSecurityConfiguration we just specified. There are many different ways we could do this, but if you are using Spring’s AbstractAnnotationConfigDispatcherServletInitializer it might look something like this:


public class SpringWebMvcInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class[] { HelloWebSecurityConfiguration.class }; } ...}

To put this in perspective, Spring Security was traditionally initialized using something similar to the following lines within the web.xml:


<!-- Creates the Spring Container shared by all Servlets and Filters --><listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class></listener><!-- Load all Spring XML configuration including our security.xml file --><context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/*.xml</param-value></context-param>

 

“Ordering of WebApplicationInitializer”
If any servlet Filter mappings are added after AbstractSecurityWebApplicationInitializer is invoked, they might be accidentally added before springSecurityFilterChain. Unless an application contains Filter instances that do not need to be secured, springSecurityFilterChain should be before any other Filter mappings. The @Order annotation can be used to help ensure that any WebApplicationInitializer is loaded in a deterministic order.

 

AbstractSecurity WebApplicationInitializer

The last step is we need to map the springSecurityFilterChain. We can easily do this by extending AbstractSecurityWebApplicationInitializer and optionally overriding methods to customize the mapping.

The most basic example below accepts the default mapping and adds springSecurityFilterChain with the following characteristics:

  • springSecurityFilterChain is mapped to “/*”
  • springSecurityFilterChain uses the dispatch types of ERROR and REQUEST
  • The springSecurityFilterChain mapping is inserted before any servlet Filter mappings that have already been configured

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {}

The above code is the equivalent of the following lines within the web.xml:


<filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class> org.springframework.web.filter.DelegatingFilterProxy </filter-class></filter><filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> <dispatcher>ERROR</dispatcher> <dispatcher>REQUEST</dispatcher></filter-mapping>

CustomWebSecurityConfigurerAdapter

Our HelloWebSecurityConfiguration sample, demonstrates that Spring Security Java configuration can provide some very nice defaults for us. Let’s take a look at some basic customization.


@EnableWebSecurity@Configurationpublic class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) { auth .inMemoryAuthentication() .withUser("user") // #1 .password("password") .roles("USER") .and() .withUser("admin") // #2 .password("password") .roles("ADMIN","USER"); } @Override public void configure(WebSecurity web) throws Exception { web .ignoring() .antMatchers("/resources/**"); // #3 } @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeUrls() .antMatchers("/signup","/about").permitAll() // #4 .antMatchers("/admin/**").hasRole("ADMIN") // #6 .anyRequest().authenticated() // 7 .and() .formLogin() // #8 .loginUrl("/login") // #9 .permitAll(); // #5 }}

Assuming that we adjust AbstractAnnotationConfigDispatcherServletInitializer to load our new configuration, our CustomWebSecurityConfigurerAdapter will do the following:

  • Allow in memory authentication with a user named “user”
  • Allow in memory authentication with an administrative user named “admin”
  • Ignore any request that starts with “/resources/”. This is similar to configuring http@security=none when using the XML namespace configuration.
  • Allow anyone (including unauthenticated users) to access to the URLs “/signup” and “/about”
  • Allow anyone (including unauthenticated users) to access to the URLs “/login” and “/login?error”. The permitAll() in this case means, allow access to any URL that formLogin() uses.
  • Any URL that starts with “/admin/” must be an administrative user. For our example, that would be the user “admin”.
  • All remaining URLs require that the user be successfully authenticated
  • Setup form based authentication using the Java configuration defaults. Authentication is performed when a POST is submitted to the URL “/login” with the parameters “username” and “password”.
  • Explicitly state the login page, which means the developer is required to render the login page when GET /login is requested.

For those that are familiar with the XML based configuration, the configuration above is very similar to the following XML configuration:


<http security="none" pattern="/resources/**"/><http use-expressions="true"> <intercept-url pattern="/logout" access="permitAll"/> <intercept-url pattern="/login" access="permitAll"/> <intercept-url pattern="/signup" access="permitAll"/> <intercept-url pattern="/about" access="permitAll"/> <intercept-url pattern="/**" access="hasRole(‘ROLE_USER‘)"/> <logout logout-success-url="/login?logout" logout-url="/logout" /> <form-login authentication-failure-url="/login?error" login-page="/login" login-processing-url="/login" password-parameter="password" username-parameter="username" /></http><authentication-manager> <authentication-provider> <user-service> <user name="user" password="password" authorities="ROLE_USER"/> <user name="admin" password="password" authorities="ROLE_USER,ROLE_ADMIN"/> </user-service> </authentication-provider></authentication-manager>

Similarities to the XML Namespace

After looking at our slightly more complicated example, you might be able to find some similarities between the XML namespace and the Java configuration. Here are some of the more useful points:

  • HttpSecurity is quite similar to the http namespace element. It allows configuring web based security for a certain selection (in this case all) requests.
  • WebSecurity is quite similar to any Security namespace elements that are for the web and that do not require a parent (i.e. security=none, debug, etc). It allows configuring things that impact all of web security.
  • WebSecurityConfigurerAdapter is a convenience class that allows customization to both WebSecurity and HttpSecurity. We can extend WebSecurityConfigurerAdapter multiple times (in distinct objects) to replicate the behavior of having multiple http elements.
  • By formatting our Java configuration code it is much easier to read. It can be read similar to the XML namespace equivalent where “and()” represents optionally closing an XML element.

Differences to the XML Namespace

You will notice that there are some important differences between the XML and Java configuration too.

  • When creating our users in #1 and #2, we do not specify “ROLE_” as we would with the XML configuration. Since this convention is so common, the “roles” method automatically adds “ROLE_” for you. If you did not want “ROLE_” added you could use the authorities method instead.
  • 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 information leaks. For example:
  • GET /login renders the login page instead of /spring_security_login
  • POST /login authenticates the user instead of /j_spring_security_check
  • The username parameter defaults to username instead of j_username
  • The password parameter defaults to password instead of j_password
  • Java configuration can easily map multiple request matchers to the same roles. This is apparent in #4 where we map two URLs to be accessible to anyone
  • Java configuration tries to remove redundant code. For example, instead of repeating our /login URL in the form-login element and the intercept-url element as we did with the XML, we can simply declare that users should have access to any URL related to formLogin() as shown with #5
  • When mapping HTTP requests using the hasRole method as we did in #6, we do not need to specify “ROLE_” as we would in XML. Again, this is so common of a convention that the hasRole method automatically adds “ROLE_” for you. If you did not want to automatically prefix with “ROLE_”, you could use the “access” method.

Additional Web Samples

Sample Compatibility Since the code was merged into Spring Security 3.2 M2 with no changes, the samples will be compatible with either the stand alone module or spring-security-config-3.2.0.M2+

We have given a few examples of how the Spring Security Java configuration can be used to secure your web application in order to wet your appetite. Below you can find a number of resources with additional samples.

  • There are plenty of samples in the HttpSecurity Javadoc. Be sure to check out the Javadoc on individual methods which gives examples for how to do things like openid, remember me, etc.
  • Web Samples

XML namespace to Java Config

If you are having trouble converting from the XML namespace to the Java configuration, you can refer to the tests. The convention is that the test for a given XML element will start with “Namespace”, contain the XML element name, and end with “Tests”. For example, to learn how the http element maps to Java configuration, you would refer to the NamespaceHttpTests. Another example, is that you can figure out how the remember-me namespace maps to Java configuration in the NamespaceRememberMeTests.

Feedback Please

If you encounter a bug, have an idea for improvement, etc please do not hesitate to bring it up! We want to hear your thoughts so we can ensure we get it right before the code is generally available. Trying out new features early is a good and simple way to give back to the community. This also ensures that the features you want are present and working as you think they should

Please log any issues or feature requests to the Spring Security JIRA under the category “Java Config”. After logging a JIRA, we encourage (but do not require) you to submit your changes in a pull request. You can read more about how to do this in the Contributor Guidelines

If you have questions on how to do something, please use the Spring Security forums or Stack Overflow with the tag spring-security (I will be monitoring them closely). If you have specific comments questions about this blog, feel free to leave a comment. Using the appropriate tools will help make it easier for everyone.

Conclusion

You should have a fairly good idea of how to use Spring Security Java configuration for web based security. In the next post, we will take a look at how to setup method based security with Java configuration.

Spring Security Java Config Preview: Method Security

Update

Users should refer to the Spring Security Reference which contains more up to date information.

Original Blog Post

This is the third installment of a four part blog series. In my first post, I introduced Spring Security Java configuration and discussed some of the logistics of the project. In my previous post, we walked through a few examples of configuring web based security.

In this post, I will discuss how to configure method based security using Spring Security Java configuration. Like our previous post, we will start off with a very basic example and follow it up with an example that performs a bit of customization.

MethodSecurityService

While not terribly interesting, assume that we have a service called MethodSecurityService as shown below:


public interface MethodSecurityService { @PreAuthorize("hasRole(‘ROLE_USER‘)") String requiresUserRole();}

Our implementation is just as trivial, but will ensure we focus on Spring Security rather than our services.


public class MethodSecurityServiceImpl implements MethodSecurityService { public String requiresUserRole() { return "You have ROLE_USER"; }}

Hello Method Security

By using @EnableGlobalMethodSecurity we can easily secure our methods with Java configuration. Note that methodSecurityService is not really part of our Security configuration, but we must create our MethodSecurityService using Spring so that it can have Security applied to it.


@Configuration@EnableGlobalMethodSecurity(prePostEnabled=true)public class HelloMethodSecurityConfig { @Bean public MethodSecurityService methodSecurityService() { return new MethodSecurityServiceImpl() } @Autowired public void registerGlobal(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user").password("password").roles("USER").and() .withUser("admin").password("password").roles("USER", "ADMIN"); }}

This configuration is fairly similar to the following XML configuration:


<global-method-security pre-post-annotations="enabled"/><authentication-manager> <authentication-provider> <user-service> <user name="user" password="password" authorities="ROLE_USER"/> </user-service> </authentication-provider></authentication-manager><beans:bean id="methodSecuriytService" class="MethodSecurityServiceImpl"/>

With our configuration, the invocation of requiresUserRole() on our methodSecurityService bean would require that the current user be authenticated with the role “ROLE_USER”. If the user was unauthenticated or did not have the role “ROLE_USER” a AccessDeniedException would be thrown.

Custom Method Security

There are a number of additional attributes available on the @EnableWebSecurity annotation, but if you wish to customize method security in more advanced ways you will need to extend GlobalMethodSecurityConfiguration. An example where we customize the PermissionEvaluator can be seen below:


@Configuration@EnableGlobalMethodSecurity(prePostEnabled=true)public class CustomPermissionEvaluatorWebSecurityConfig extends GlobalMethodSecurityConfiguration { @Bean public MethodSecurityService methodSecurityService() { return new MethodSecurityServiceImpl() } @Override protected MethodSecurityExpressionHandler expressionHandler() { DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler(); expressionHandler.setPermissionEvaluator(new CustomPermissionEvaluator()); return expressionHandler; } @Autowired public void registerGlobal(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user").password("password").roles("USER").and() .withUser("admin").password("password").roles("USER", "ADMIN"); }}

This is fairly similar to the following XML configuration:


<global-method-security pre-post-annotations="enabled"> <expression-handler ref="expressionHandler"/></global-method-security><authentication-manager> <authentication-provider> <user-service> <user name="user" password="password" authorities="ROLE_USER"/> </user-service> </authentication-provider></authentication-manager><beans:bean id="methodSecuriytService" class="MethodSecurityServiceImpl"/><beans:bean id="expressionHandler" class="CustomExpressionHandler"/>

Additional Method Samples

We have given a few examples of how the Spring Security Java Configuration can be used to secure your application with method level security. You can find additional samples in the spring-security-javaconfig project’s github repository.

  • Method Samples
  • Complete Web Applications (some demo Method Security too)

Feedback Please

If you encounter a bug, have an idea for improvement, etc please do not hesitate to bring it up! We want to hear your thoughts so we can ensure we get it right before the code is generally available. Trying out new features early is a good and simple way to give back to the community. This also ensures that the features you want are present and working as you think they should.

Please log any issues or feature requests to the Spring Security JIRA under the category “Java Config”. After logging a JIRA, we encourage (but do not require) you to submit your changes in a pull request. You can read more about how to do this in the Contributor Guidelines

If you have questions on how to do something, please use the Spring Security forums or Stack Overflow with the tag spring-security (I will be monitoring them closely). If you have specific comments questions about this blog, feel free to leave a comment. Using the appropriate tools will help make it easier for everyone.

Conclusion

You should now have an understanding of how to configure method based security using Spring Security Java configuration support. In the next post, we will demonstrate how Spring Security is designed for extension by walking through the OAuth Java Configuration proof of concept.

Spring Security Java Config Preview: OAuth

This is the fourth post in my five part blog series that introduces Spring Security Java configuration. In this post, we will discuss how Spring Security Java configuration can be extended by walking through Spring Security OAuth Java configuration support.

Proof of Concept

While the Spring Security Java configuration works well for very basic configuration, it is just a proof of concept. We have not ensured that all the functionality available in the XML namespace is present within its Java configuration support. It was important to ensure that Spring Security’s Java configuration would work well with the Spring extensions. However, we did not want to wait until we implemented all the configuration functionality in the extensions before releasing Spring Security Java config. In the future, we plan to solidify the Spring Security OAuth Java configuration but for now it is more of a proof of concept than a complete solution.

HelloOAuth2ServerConfiguration

Spring Security’s OAuth Java configuration supports a basic OAuth 2 server configuration. In its simplest form, it looks like this:


@Configuration@EnableWebSecuritypublic class HelloOAuth2ServerConfiguration extends OAuth2ServerConfigurerAdapter { private static final String RESOURCE_ID = "photos"; @Autowired public void registerGlobal(AuthenticationManagerBuilder auth) throws Exception { auth .apply(new InMemoryClientDetailsServiceConfigurer()) .withClient("my-client") .resourceIds(RESOURCE_ID) .authorizedGrantTypes("authorization_code","implicit") .authorities("ROLE_USER") .scopes("read","write") .secret("secret"); } @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeUrls() .anyRequest().authenticated() .and() .apply(new OAuth2ServerConfigurer()) .resourceId(RESOURCE_ID); }}

With this configuration we are now able to processes OAuth request. However, it has some limitations that will not work in many circumstances:

  • If user’s are approving requests with the OAuth Server, we would still need to a Controller that processes “/oauth/confirm_access”
  • There is no way to authenticate with a user rather than an OAuth client which means there is no way for a user to confirm access
  • Authorization is mapped to being authenticated, which is at best a naive implementation of authorization

SecurityConfigurer

Sitting these problems aside, let’s take a look at what is happening. The OAuth2ServerConfigurer is an instance of SecurityConfigurer. When implementing SecurityConfigurer, it is recommended to extend SecurityConfigurerAdapter which is a base implementation of SecurityConfigurer.

By allowing HttpSecurity to accept a SecurityConfigurer, we can add extensions (like OAuth) that update the HttpSecurity object in more complex ways. In fact, methods like HttpSecurity.formLogin() are implemented using SecurityConfigurerAdapter implementations as well. The difference is that they are part of Spring Security’s core modules and so there are convenience methods that perform the apply(SecurityConfigurerAdapter) for us.

Not only can we apply a SecurityConfigurer to the HttpSecurity object, we can also apply a SecurityConfigurer to the AuthenticationManagerBuilder. This is illustrated by the InMemoryClientDetailsServiceConfigurer. This means that the authentication mechanisms can be easily extended too.

What does this mean to you? Assume you have a more complicated Security configuration and want to share it across your company. You could allow engineers to copy paste the configuration everywhere. Alternatively, you can create your own SecurityConfigurerAdapter implementation that allows developers to focus on your company’s custom DSL.

Additional OAuth Samples

Our sample configuration we provided was very simple, but it does not illustrate what to do in more realistic situations. We will not blog about these until we feel the OAuth support has been solidified further. However, there are additional samples that can get you started if you wish to try it out.

 

  • Spring Security JavaConfig‘s sparklr application
  • The Spring Rest Stack‘s - oauth module

Feedback Please

If you encounter a bug, have an idea for improvement, etc please do not hesitate to bring it up! We want to hear your thoughts so we can ensure we get it right before the code is generally available. Trying out new features early is a good and simple way to give back to the community. This also ensures that the features you want are present and working as you think they should.

Please log any issues or feature requests to the Spring Security JIRA under the category “Java Config”. After logging a JIRA, we encourage (but do not require) you to submit your changes in a pull request. You can read more about how to do this in the Contributor Guidelines

If you have questions on how to do something, please use the Spring Security forums or Stack Overflow with the tag spring-security (I will be monitoring them closely). If you have specific comments questions about this blog, feel free to leave a comment. Using the appropriate tools will help make it easier for everyone.

Conclusion

Spring Security Java configuration used the OAuth support as a proof of concept to ensure it is ready for extension. In time, the OAuth support will be solidified into a replacement for the XML configuration. In my last post I discuss the readability of Spring Security Java Configuration.

Spring Security Java Config Preview: Readability

In this post, I will discuss how to make your Spring Security Java configuration more readable. The post is intended to elaborate on a point from Spring Security Java Config Preview: Web Security where I stated:

By formatting our Java configuration code it is much easier to read. It can be read similar to the XML namespace equivalent where “and()” represents optionally closing an XML element.

Indentation

The indentation of Spring Security’s Java configuration really impacts its readability. In general, indentation like a bullet list should be preferred.

For a more concrete example, take a look at the following code:


http // #1 .formLogin() // #2 .loginPage("/login") .failureUrl("/login?error") // #3 .and() // #4 .authorizeRequests() // #5 .antMatchers("/signup","/about").permitAll() .antMatchers("/admin/**").hasRole("ADMIN") .anyRequest().authenticated();
  • #1 formLogin updates the http object itself. The indentation of formLogin is incremented from that of http (much like they way the <form-login> is indented from <http>)
  • #2 loginPage and failureUrl update the formLogin configuration. For example, loginPage determines where Spring Security will redirect if log in is required. For this reason, each is a child of formLogin.
  • #3 and means we are done configuring the parent (in this case formLogin). This also implies that the next line will decrease indentation by one. When looking at the configuration you can read it as http is configured with formLogin andauthorizeRequests. If we had nothing else to configure, the and is not necessary.
  • #4 We decrease the indentation with authorizeRequests since it is not related to form based log in. Instead, its intent is to restrict access to various URLs.
  • #5 each antMatchers and anyRequest modifies the authorization requirements for authorizeRequests. This is why each is a child of authorizeRequests

IDE Formatters

The indentation may cause problems with code formatters. Many IDE’s will allow you to disable formatting for select blocks of code with comments. For example, in STS/Eclipse you can use the comments of @formatter:off and @formatter:on to turn off and on code formatting. An example is shown below:


// @formatter:offhttp .formLogin() .loginPage("/login") .failureUrl("/login?error") .and() .authorizeRequests() .antMatchers("/signup","/about").permitAll() .antMatchers("/admin/**").hasRole("ADMIN") .anyRequest().authenticated();// @formatter:on

For this feature to work, make sure you have it enabled:

  • Navigate to Preferences -> Java -> Code Style -> Formatter
  • Click the Edit button
  • Select the Off/On Tags tab
  • Ensure Enable Off/On tags is selected
  • You can optionally change the strings used for disabling and enabling formatting here too.
  • Click OK

Comparison to XML Namespace

Our indentation also helps us relate the Java Configuration to the XML namespace configuration. This is not always true, but it does help. Let’s compare our configuration to the relevant XML configuration below.


http .formLogin() .loginPage("/login") .failureUrl("/login?error") .and() .authorizeRequests() .antMatchers("/signup","/about").permitAll() .antMatchers("/admin/**").hasRole("ADMIN") .anyRequest().authenticated();

The relevant, but not equivalent, XML configuration can be seen below. Note that the differences between how Spring Security will behave between these configurations is due to the different default values between Java Configuration and XML configuration.


<http use-expressions="true"> <form-login login-page="/login" authentication-failure-url="/login?error" /> <!-- similar to and() --> <intercept-url pattern="/signup" access="permitAll"/> <intercept-url pattern="/about" access="permitAll"/> <intercept-url pattern="/**" access="hasRole(‘ROLE_USER‘)"/></http>
  • The first thing to notice is that the http and <http> are quite similar. One difference is that Java Configuration uses authorizeRequests to specify use-expressions="true"
  • formLogin and <form-login> are quite similar. Each child of formLogin is an XML attribute of <form-login>. Based upon our explanation of indentation, the similarities are logical since XML attributes modify XML elements.
  • The and() under formLogin is very similar to ending an XML element.
  • Each child of authorizeRequests is similar to each <intercept-urls>, except that Java Configuration specifies requires-channel differently which helps reduce configuration in many circumstances.

Summary

You should now know how to consistently indent your Spring Security Java Configuration. By doing so your code will be more readable and be easier to translate to and from the XML configuration equivalents.

 

Spring Security Java Config Preview--官方