Spring Security(Third Edition)
上QQ阅读APP看书,第一时间看更新

Updating our configuration

Now that we have created all the code required for an additional parameter, we need to configure Spring Security to be aware of it. The following code snippet includes the required updates to our SecurityConfig.java file to support our additional parameter:

//src/main/java/com/packtpub/springsecurity/configuration/
SecurityConfig.java

@Override
protected void configure(final HttpSecurity http) throws Exception {
http.authorizeRequests()
...
.and().exceptionHandling()
.accessDeniedPage("/errors/403")
.authenticationEntryPoint(
loginUrlAuthenticationEntryPoint())
.and().formLogin()
.loginPage("/login/form")
.loginProcessingUrl("/login")
.failureUrl("/login/form?error")
.usernameParameter("username")
.passwordParameter("password")
.defaultSuccessUrl("/default", true)
.permitAll()
...
// Add custom UsernamePasswordAuthenticationFilter
.addFilterAt(
domainUsernamePasswordAuthenticationFilter(),
UsernamePasswordAuthenticationFilter.class)
;
}
@Bean
public DomainUsernamePasswordAuthenticationFilter domainUsernamePasswordAuthenticationFilter()
throws Exception {
DomainUsernamePasswordAuthenticationFilter dupaf = new DomainUsernamePasswordAuthenticationFilter(
super.authenticationManagerBean());
dupaf.setFilterProcessesUrl("/login");
dupaf.setUsernameParameter("username");
dupaf.setPasswordParameter("password");
dupaf.setAuthenticationSuccessHandler(
new SavedRequestAwareAuthenticationSuccessHandler(){{
setDefaultTargetUrl("/default");
}}
);
dupaf.setAuthenticationFailureHandler(
new SimpleUrlAuthenticationFailureHandler(){{
setDefaultFailureUrl("/login/form?error");
}}
);
dupaf.afterPropertiesSet();
return dupaf;
}
@Bean
public LoginUrlAuthenticationEntryPoint loginUrlAuthenticationEntryPoint(){
return new LoginUrlAuthenticationEntryPoint("/login/form");
}

The preceding code snippet configures standard beans in our Spring Security configuration. We have shown this to demonstrate that it can be done. However, throughout much of the rest of the book, we include standard bean configuration in its own file, as this makes the configuration less verbose. If you are having trouble, or prefer not to type all of this, you may copy it from chapter03.06-calendar.

The following are a few highlights from the configuration updates:

  • We overrode  defaultAuthenticationEntryPoint and added a reference  to o.s.s.web.authentication.LoginUrlAuthenticationEntryPoint, which determines what happens when a request for a protected resource occurs and the user is not authenticated. In our case, we are redirected to a login page.
  • We removed the formLogin() method and used a .addFilterAt() method to insert our custom filter into FilterChainProxy. The position indicates the order in which the delegates of FilterChain are considered and cannot overlap with another filter, but can replace the filter at the current position. We replaced UsernamePasswordAuthenticationFilter with our custom filter.
  • We added the configuration for our custom filter, which refers to the authentication manager created by the configure(AuthenticationManagerBuilder) method.

Take a look at the following diagram for your reference:

You can now restart the application and try the following steps, depicted in the preceding diagram, to understand how all the pieces fit together:

  1. Visit http://localhost:8080/events.
  2. Spring Security will intercept the secured URL and use the LoginUrlAuthenticationEntryPoint object to process it.
  3. The LoginUrlAuthenticationEntryPoint object will send the user to the login page. Enter admin1 as the username, example.com as the domain, and admin1 as the password.
  4. The DomainUsernamePasswordAuthenticationFilter object will intercept the process of the login request. It will then obtain the username, domain, and password from the HTTP request and create a DomainUsernamePasswordAuthenticationToken object.
  5. The DomainUsernamePasswordAuthenticationFilter object submits DomainUsernamePasswordAuthenticationToken to CalendarUserAuthenticationProvider.
  6. The CalendarUserAuthenticationProvider interface validates DomainUsernamePasswordAuthenticationToken and then returns an authenticated DomainUsernamePasswordAuthenticationToken object (that is, isAuthenticated() returns true).
  7. The DomainUserPasswordAuthenticationFilter object updates SecurityContext with DomainUsernamePasswordAuthenticationToken and places it on SecurityContextHolder.

Your code should look like chapter03.06-calendar.