vlambda博客
学习文章列表

读书笔记《spring-security-third-edition》迁移到 Spring Security 4.2

迁移到 Spring Security 4.2

在最后一章中,我们将回顾与从 Spring Security 3 迁移到 Spring Security 4.2 时常见的迁移问题相关的信息。我们将花更多时间讨论 Spring Security 3 和 Spring Security 4 之间的区别,因为这是大多数用户都会遇到的问题。这是因为从 Spring Security 3 到 Spring Security 4.2 的更新包含大量非被动重构。

在本章的最后,我们还将重点介绍 Spring Security 4.2 中的一些新特性。但是,我们没有明确涵盖从 Spring Security 3 到 Spring Security 4.2 的更改。这是因为通过解释 Spring Security 3 和 Spring Security 4 之间的差异,用户应该能够轻松地更新到 Spring Security 4.2,因为对 Spring Security 4.2 的更改是被动的。

在本章的课程中,我们将讨论以下主题:

  • Reviewing important enhancements in Spring Security 4.2.
  • Understanding configuration changes required in your existing Spring version.
  • Reviewing Security 3 applications when moving them to Spring Security 4.2.
  • Illustrating the overall movement of important classes and packages in Spring Security 4.
  • Highlighting some of the new features found in Spring Security 4.2. Once you have completed the review of this chapter, you will be in a good position to migrate an existing application from Spring Security 3 to Spring Security 4.2.
  • Migrating from Spring Security 3.

您可能正计划将现有应用程序迁移到 Spring Security 4.2,或者您可能正在尝试向 Spring Security 3 应用程序添加功能并正在本书的页面中寻找指导。在本章中,我们将尝试解决您的两个问题。

首先,我们将介绍 Spring Security 3 和 4.2 之间的重要区别——在特性和配置方面。其次,我们将提供一些关于映射配置或类名更改的指导。这将更好地使您能够将书中的示例从 Spring Security 4.2 转换回 Spring Security 3(如果适用)。

一个非常重要的迁移说明是 Spring Security 3+ 要求迁移到 Spring Framework 4 和 Java 5 (1.5) 或更高版本。请注意,在许多情况下,迁移这些其他组件对您的应用程序的影响可能比升级 Spring Security 更大!

介绍

随着针对应用程序的攻击不断发展,Spring Security 也必须如此。在主要发布版本中,Spring Security 团队借此机会进行了一些非被动更改,重点关注以下内容:

可以在 JIRA 中找到 3.x 和 4.x 之间的非被动更改的完整列表 https://jira.spring.io/browse/SEC-2916?jql=project%20%3D%20SEC%20AND%20fixVersion%20in%20(4.0. 0%2C%204.0.0.M1%2C%204.0.0.M2%2C%204.0.0.RC1%2C%204.0.0.RC2)%20AND%20labels%20%3D%20passivity

样本迁移

Spring Security 4.2 中的增强功能

Spring Security 4.2 有很多显着的变化,这个版本也带来了对 Spring Framework 5 的早期支持。你可以找到 4.2.0.M1、4.2.0.RC1 和 4.2.0.RELEASE 的更新日志,其中涵盖80多个问题。社区贡献了绝大多数这些功能。

Spring Security 4.2 中的显着增强,自 Spring Security 3 以来得到了改进,包括以下特性及其支持数量:

网页改进:

以下项目与 Spring Security 与基于 Web 的应用程序的交互有关:

  • #3812: Jackson support
  • #4116: Referrer policy
  • #3938: Added HTTP response splitting prevention
  • #3949: Added bean reference support to @AuthenticationPrincipal
  • #3978: Support for Standford WebAuth and Shibboleth using the newly added RequestAttributeAuthenticationFilter
  • #4076: Document proxy server configuration
  • #3795: ConcurrentSessionFilter supports InvalidSessionStrategy
  • #3904: Added CompositeLogoutHandler

Spring Security 配置改进:

以下项目与Spring Security的配置有关:

  • #3956: Central configuration of the default role prefix. See the issue for details
  • #4102: Custom default configuration in WebSecurityConfigurerAdapter
  • #3899: concurrency-control@max-sessions supports unlimited sessions.
  • #4097: intercept-url@request-matcher-ref adds more powerful request matching support to the XML namespace
  • #3990: Support for constructing RoleHierarchy from Map (such as YML).
  • #4062: Custom cookiePath to CookieCsrfTokenRepository.
  • #3794: Allowing the configuration of InvalidSessionStrategy on SessionManagementConfigurer
  • #4020: Fixing exposed beans for defaultMethodExpressionHandler can prevent Method Security

Spring Security 4.x 中的其他变化

以下项目是值得注意的杂项更改,因为其中许多可能会影响升级到 Spring Security 4.x:

  • #4080: Spring 5 support
  • #4095 - Added UserBuilder
  • #4018: Fixes after csrf() is invoked, future MockMvc invocations use original CsrfTokenRepository
  • General dependency version updates

请注意,列出的数字指的是 GitHub 拉取请求或问题。

其他更无害的更改包括对代码库和框架配置的一般重组和清理,以便整体结构和使用更有意义。 Spring Security 的作者在以前不存在的地方增加了可扩展性,特别是在登录和 URL 重定向方面。

如果您已经在 Spring Security 3 环境中工作,那么如果您不突破框架的界限,您可能找不到令人信服的升级理由。但是,如果您发现 Spring Security 3 的可用扩展点、代码结构或可配置性存在限制,您将欢迎我们在本章其余部分详细讨论的许多细微更改。

Spring Security 4 中的配置更改

Spring Security 4 中的许多更改将在基于 XML 的配置中的命名空间样式中可见。我们将在本章中主要介绍基于 Java 的配置,但也会注意到一些基于 XML 的显着变化。尽管本章无法详细介绍所有细微更改,但我们将尝试涵盖在您迁移到 Spring Security 4 时最有可能影响您的那些更改。

弃用

在 Spring Security 4 中删除了一些弃用以清理混乱。

以下是 XML 和 JavaConfig 弃用的最终提交,其中包含 177 个更改文件,其中 537 个添加和 5,023 个删除:https://github.com/spring-projects/spring-security/commit/6e204fff72b80196a83245cbc3bd0cd401feda00

如果您使用的是 XML 命名空间或基于 Java 的配置,那么在许多情况下您将不会被弃用。如果您(或您使用的非 Spring 库)不直接使用 API,那么您将不会受到影响。您可以轻松搜索您的工作区以找到这些列出的弃用。

spring-security-core 弃用

本节描述了 spring-security-core 模块中所有已弃用的 API。

org.springframework.security.access.SecurityConfig

SecurityConfig.createSingleAttributeList(String) 接口已被删除,以支持使用 SecurityConfig.createList(String…)。这意味着,如果您有如下内容:

     List<ConfigAttribute> attrs = SecurityConfig.createSingleAttributeList
     ("ROLE_USER");

它将需要替换为以下代码:

    List<ConfigAttribute> attrs = SecurityConfig.createList("ROLE_USER");

UserDetailsS​​erviceWrapper

UserDetailsS​​erviceWrapper 已被弃用,取而代之的是使用 RoleHierarchyAuthoritiesMapper。例如,您可能有如下内容:

@Bean
public AuthenticationManager authenticationManager(List<AuthenticationProvider> providers) {
      return new ProviderManager(providers);
}
@Bean
public AuthenticationProvider authenticationProvider(UserDetailsServiceWrapper userDetailsService) {
      DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
      provider.setUserDetailsService(userDetailsService);
      return provider;
}
@Bean
public UserDetailsServiceWrapper userDetailsServiceWrapper(RoleHierarchy roleHierarchy) {
      UserDetailsServiceWrapper wrapper = new UserDetailsServiceWrapper();
      wrapper.setRoleHierarchy(roleHierarchy);
      wrapper.setUserDetailsService(userDetailsService());
      return wrapper;
}

需要将其替换为以下内容:

@Bean
public AuthenticationManager authenticationManager(List<AuthenticationProvider> providers) {
      return new ProviderManager(providers);
}
@Bean
public AuthenticationProvider authenticationProvider(UserDetailsService userDetailsService, GrantedAuthoritiesMapper authoritiesMapper) {
      DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
      provider.setUserDetailsService(userDetailsService);
      provider.setAuthoritiesMapper(authoritiesMapper);
      return provider;
}
@Bean
public RoleHierarchyAuthoritiesMapper roleHierarchyAuthoritiesMapper(RoleHierarchy roleHierarchy) {
      return new RoleHierarchyAuthoritiesMapper(roleHierarchy);
}

UserDetailsWrapper

UserDetailsWrapper 已被弃用,取而代之的是使用 RoleHierarchyAuthoritiesMapper。通常,用户不会直接使用 UserDetailsWrapper 类。但是,如果是,他们可以使用 RoleHierarchyAuthoritiesMapper,例如,可能存在以下代码:

    UserDetailsWrapper authenticate = new UserDetailsWrapper
    (userDetails, roleHiearchy);

如果是这样,则需要将其替换为以下代码段:

    Collection<GrantedAuthority> allAuthorities = roleHiearchy.
    getReachableGrantedAuthorities(userDetails.getAuthorities());
    UserDetails authenticate = new User(userDetails.getUsername(), 
    userDetails.getPassword(), allAuthorities);

AbstractAccessDecisionManager

AbstractAccessDecisionManager 的默认构造函数已与 setDecisionVoters 方法一起被弃用。自然,这会影响 AffirmativeBasedConsensusBasedUnanimousBased 子类。例如,您可能正在使用以下代码片段:

    AffirmativeBased adm = new AffirmativeBased();
    adm.setDecisionVoters(voters);

如果是这样,则需要将其迁移到以下代码段:

    AffirmativeBased adm = new AffirmativeBased(voters);

身份验证异常

AuthenticationException 中接受 extraInformation 的构造函数已被移除,以防止 UserDetails 意外泄漏目的。具体来说,我们删除了以下代码:

    public AccountExpiredException(String msg, Object extraInformation) {
      ...
    }

这会影响子类 AccountStatusExceptionAccountExpiredExceptionBadCredentialsExceptionCredentialsExpiredExceptionDisabledException、< kbd>LockedException 和 UsernameNotFoundException。如果您使用这些构造函数中的任何一个,只需删除附加参数即可。例如,更改了以下代码片段:

    new LockedException("Message", userDetails);

前面的代码片段应该改为下面的代码片段:

    new LockedException("Message");

匿名身份验证提供者

AnonymousAuthenticationProvider 默认构造函数和 setKey 方法已被弃用,取而代之的是使用构造函数注入。例如,您可能有以下代码片段:

    AnonymousAuthenticationProvider provider = new 
    AnonymousAuthenticationProvider();
    provider.setKey(key);

前面的代码片段应改为以下代码:

    AnonymousAuthenticationProvider provider = new 
    AnonymousAuthenticationProvider(key);

AuthenticationDetailsS​​ourceImpl

AuthenticationDetailsS​​ourceImpl 类已被弃用,取而代之的是编写自定义 AuthenticationDetailsS​​ource。例如,您可能有以下情况:

    AuthenticationDetailsSourceImpl source = new 
    AuthenticationDetailsSourceImpl();
    source.setClazz(CustomWebAuthenticationDetails.class);

您应该直接实现 AuthenticationDetailsS​​ource 类以返回 CustomSource 对象:

public class CustomWebAuthenticationDetailsSource implements AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> {
      public WebAuthenticationDetails buildDetails(HttpServletRequest context) {
            return new CustomWebAuthenticationDetails(context);
      }
}

提供者管理器

ProviderManager 类删除了已弃用的默认构造函数和相应的设置方法,以支持使用构造函数注入。它还删除了 clearExtraInformation 属性,因为 AuthenticationException 异常删除了额外信息属性。

例如,您可能有以下内容:

ProviderManager provider = new ProviderManager();
provider.setParent(parent);
provider.setProviders(providers);
provider.setClearExtraInformation(true);

如果是这样,则应将前面的代码更改为以下代码:

ProviderManager provider = new ProviderManager(providers, parent);

clearExtraInformation 属性已被删除,因为 AuthenticationException 异常已删除额外信息属性。没有替代品。

RememberMeAuthenticationProvider

RememberMeAuthenticationProvider 类具有默认构造函数,并删除了 setKey 方法以支持构造函数注入。例如,看看下面的代码:

    RememberMeAuthenticationProvider provider = new 
    RememberMeAuthenticationProvider();
    provider.setKey(key);

前面的代码片段应迁移到以下内容:

    RememberMeAuthenticationProvider provider = new 
    RememberMeAuthenticationProvider(key);

GrantedAuthorityImpl

GrantedAuthorityImpl 被删除以支持 SimpleGrantedAuthority,或实现您自己的 GrantAuthority 对象。例如:

    new GrantedAuthorityImpl(role);

这应该替换为以下内容:

    new SimpleGrantedAuthority(role);

InMemoryDaoImpl

InMemoryDaoImpl 被替换为 InMemoryUserDetailsManager。例如:

InMemoryDaoImpl uds = new InMemoryDaoImpl();
uds.setUserProperties(properties);

这应该替换为:

InMemoryUserDetailsManager uds = new InMemoryUserDetailsManager(properties);
spring-security-web

spring-security-web 弃用

本节描述了 spring-security-web 模块中所有已弃用的 API。

过滤链代理

FilterChainProxy 删除了 setFilterChainMap 方法以支持构造函数注入。例如,您可能有以下情况:

FilterChainProxy filter = new FilterChainProxy();
filter.setFilterChainMap(filterChainMap);

它应该替换为:

FilterChainProxy filter = new FilterChainProxy(securityFilterChains);

FilterChainProxy 也移除了 getFilterChainMap 以支持使用 getFilterChains,例如:

    FilterChainProxy securityFilterChain = ...
    Map<RequestMatcher,List<Filter>> mappings = 
    securityFilterChain.getFilterChainMap();
    for(Map.Entry<RequestMatcher, List<Filter>> entry : mappings.entrySet()) {
          RequestMatcher matcher = entry.getKey();
          boolean matches = matcher.matches(request);
          List<Filter> filters = entry.getValue();
    }

这应该替换为以下代码:

    FilterChainProxy securityFilterChain = ...
    List<SecurityFilterChain> mappings = securityFilterChain.getFilterChains();
    for(SecurityFilterChain entry : mappings) {
          boolean matches = entry.matches(request);
          List<Filter> filters = entry.getFilters();
    }

异常翻译过滤器

ExceptionTranslationFiltersetAuthenticationEntryPoint 方法的默认构造函数已被删除,以支持使用构造函数注入:

ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
filter.setAuthenticationEntryPoint(entryPoint);
filter.setRequestCache(requestCache);

这可以用以下代码替换:

    ExceptionTranslationFilter filter = new 
    ExceptionTranslationFilter(entryPoint, requestCache);

AbstractAuthenticationProcessingFilter

AbstractAuthenticationProcessingFilter 类已删除其 successfulAuthentication(HttpServletRequest,HttpServletResponse,Authentication) 方法。因此,您的应用程序可能会覆盖以下方法:

    protected void successfulAuthentication(HttpServletRequest request, 
    HttpServletResponse response, Authentication authResult) throws IOException,    
    ServletException {
    }

它应该替换为以下代码:

    protected void successfulAuthentication(HttpServletRequest request,
     HttpServletResponse response, FilterChain chain, Authentication 
     authResult) throws IOException, ServletException {
    }

匿名身份验证过滤器

AnonymousAuthenticationFilter 类具有默认构造函数,并删除了 setKeysetPrincipal 方法以支持构造函数注入。例如,看看下面的代码片段:

    AnonymousAuthenticationFilter filter = new 
    AnonymousAuthenticationFilter();
    filter.setKey(key);
    filter.setUserAttribute(attrs);

这应该替换为以下代码:

    AnonymousAuthenticationFilter filter = new   
    AnonymousAuthenticationFilter(key,attrs.getPassword(),
    attrs.getAuthorities());

LoginUrlAuthenticationEntryPoint

LoginUrlAuthenticationEntryPoint 默认构造函数和 setLoginFormUrl 方法已被删除,以支持构造函数注入。例如:

    LoginUrlAuthenticationEntryPoint entryPoint = new 
    LoginUrlAuthenticationEntryPoint();
    entryPoint.setLoginFormUrl("/login");

这应该替换为以下代码:

    LoginUrlAuthenticationEntryPoint entryPoint = new   
    LoginUrlAuthenticationEntryPoint(loginFormUrl);

PreAuthenticatedGrantedAuthoritiesUserDetailsS​​ervice

PreAuthenticatedGrantedAuthoritiesUserDetailsS​​ervice 接口删除了 createuserDetails 以支持 createUserDetails

新方法在这种情况下进行了更正(U 而不是 u)。

这意味着如果您有一个覆盖 createuserDetailsPreAuthenticatedGrantedAuthoritiesUserDetailsS​​ervice 类的子类,则 SubclassPreAuthenticatedGrantedAuthoritiesUserDetailsS​​ervice 将扩展 PreAuthenticatedGrantedAuthoritiesUserDetailsS​​ervice

{
      @Override
      protected UserDetails createuserDetails(Authentication token,
                  Collection<? extends GrantedAuthority> authorities) {
            // customize
      }
}

应将其更改为覆盖 createUserDetails

public class SubclassPreAuthenticatedGrantedAuthoritiesUserDetailsService extends PreAuthenticatedGrantedAuthoritiesUserDetailsService {
      @Override
      protected UserDetails createUserDetails(Authentication token,
                  Collection<? extends GrantedAuthority> authorities) {
            // customize
      }
}

AbstractRememberMeServices

AbstractRememberMeServices 及其子类 PersistentTokenBasedRememberMeServicesTokenBasedRememberMeServices 删除了默认构造函数 setKeysetUserDetailsS​​ervice< /kbd> 方法支持构造函数注入。

PersistentTokenBasedRememberMeServices

AbstractRememberMeServices 及其子类的更改具有类似于以下示例的用法:

PersistentTokenBasedRememberMeServices services = new PersistentTokenBasedRememberMeServices();
services.setKey(key);
services.setUserDetailsService(userDetailsService);
services.setTokenRepository(tokenRepository);

但是现在应该将实现用法替换为:

PersistentTokenBasedRememberMeServices services = new PersistentTokenBasedRememberMeServices(key, userDetailsService, tokenRepository);

RememberMeAuthenticationFilter

RememberMeAuthenticationFilter 默认构造函数、setAuthenticationManagersetRememberMeServices 方法已被移除以支持构造函数注入,如下所示:

RememberMeAuthenticationFilter filter = new RememberMeAuthenticationFilter();
filter.setAuthenticationManager(authenticationManager);
filter.setRememberMeServices(rememberMeServices);

这应该替换为:

RememberMeAuthenticationFilter filter = new RememberMeAuthenticationFilter(authenticationManager,rememberMeServices);

AbstractRememberMeServices 及其子类 PersistentTokenBasedRememberMeServicesTokenBasedRememberMeServices 删除了默认构造函数 setKeysetUserDetailsS​​ervice< /kbd> 方法支持构造函数注入。例如:

TokenBasedRememberMeServices services = new TokenBasedRememberMeServices();
services.setKey(key);
services.setUserDetailsService(userDetailsService);

这应该替换为:

TokenBasedRememberMeServices services = new TokenBasedRememberMeServices(key, userDetailsService);

ConcurrentSessionControlStrategy

ConcurrentSessionControlStrategy 已替换为 ConcurrentSessionControlAuthenticationStrategy。以前,ConcurrentSessionControlStrategy 无法与 SessionFixationProtectionStrategy 分离。现在它完全解耦了。例如:

ConcurrentSessionControlStrategy strategy = new ConcurrentSessionControlStrategy(sessionRegistry);

这可以替换为:

List<SessionAuthenticationStrategy> delegates = new ArrayList<SessionAuthenticationStrategy>();
delegates.add(new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry));
delegates.add(new SessionFixationProtectionStrategy());
delegates.add(new RegisterSessionAuthenticationStrategy(sessionRegistry));
CompositeSessionAuthenticationStrategy strategy = new CompositeSessionAuthenticationStrategy(delegates);

SessionFixationProtectionStrategy

SessionFixationProtectionStrategy 删除了 setRetainedAttributes 方法,有利于用户继承 SessionFixationProtectionStrategy 并覆盖 extractAttributes 方法。看下面的代码:

SessionFixationProtectionStrategy strategy = new SessionFixationProtectionStrategy();
strategy.setRetainedAttributes(attrsToRetain);

它应该替换为:

public class AttrsSessionFixationProtectionStrategy extends SessionFixationProtectionStrategy {
      private final Collection<String> attrsToRetain;
      public AttrsSessionFixationProtectionStrategy(
                  Collection<String> attrsToRetain) {
            this.attrsToRetain = attrsToRetain;
      }
      @Override
      protected Map<String, Object> extractAttributes(HttpSession session) {
            Map<String,Object> attrs = new HashMap<String, Object>();
            for(String attr : attrsToRetain) {
                  attrs.put(attr, session.getAttribute(attr));
            }
            return attrs;
      }
}
SessionFixationProtectionStrategy strategy = new AttrsSessionFixationProtectionStrategy(attrsToRetain);

BasicAuthenticationFilter

移除了 BasicAuthenticationFilter 默认构造函数、setAuthenticationManagersetRememberMeServices 方法,以支持构造函数注入:

BasicAuthenticationFilter filter = new BasicAuthenticationFilter();
filter.setAuthenticationManager(authenticationManager);
filter.setAuthenticationEntryPoint(entryPoint);
filter.setIgnoreFailure(true);

这应该替换为:

BasicAuthenticationFilter filter = new BasicAuthenticationFilter(authenticationManager,entryPoint);

使用此构造函数会自动将 ignoreFalure 设置为 true

SecurityContextPersistenceFilter

SecurityContextPersistenceFilter 删除了 setSecurityContextRepository 以支持构造函数注入。例如:

SecurityContextPersistenceFilter filter = new SecurityContextPersistenceFilter();
filter.setSecurityContextRepository(securityContextRepository);

这应该替换为:

SecurityContextPersistenceFilter filter = new SecurityContextPersistenceFilter(securityContextRepository);

RequestCacheAwareFilter

RequestCacheAwareFilter 删除了 setRequestCache 以支持构造函数注入。例如:

RequestCacheAwareFilter filter = new RequestCacheAwareFilter();
filter.setRequestCache(requestCache);

这应该替换为:

RequestCacheAwareFilter filter = new RequestCacheAwareFilter(requestCache);

ConcurrentSessionFilter

ConcurrentSessionFilter 删除了默认构造函数 setExpiredUrlsetSessionRegistry 方法以支持构造函数注入。例如:

ConcurrentSessionFilter filter = new ConcurrentSessionFilter();
filter.setSessionRegistry(sessionRegistry);
filter.setExpiredUrl("/expired");

这应该替换为:

ConcurrentSessionFilter filter = new ConcurrentSessionFilter(sessionRegistry,"/expired");

SessionManagementFilter

SessionManagementFilter 删除了 setSessionAuthenticationStrategy 方法以支持构造函数注入。例如:

SessionManagementFilter filter = new SessionManagementFilter(securityContextRepository);
filter.setSessionAuthenticationStrategy(sessionAuthenticationStrategy);

这应该替换为:

SessionManagementFilter filter = new SessionManagementFilter(securityContextRepository, sessionAuthenticationStrategy);

RequestMatcher

RequestMatcher 及其实现已从 org.springframework.security.web.util 包移至 org.springframework.security.web.util.matcher 。具体来说:

org.springframework.security.web.util.RequestMatcher  org.springframework.security.web.util.matcher.RequestMatcher
org.springframework.security.web.util.AntPathRequestMatcher org.springframework.security.web.util.matcher.AntPathRequestMatcher
org.springframework.security.web.util.AnyRequestMatcher org.springframework.security.web.util.matcher.AnyRequestMatcher.INSTANCE
org.springframework.security.web.util.ELRequestMatcher org.springframework.security.web.util.matcher.ELRequestMatcher
org.springframework.security.web.util.IpAddressMatcher org.springframework.security.web.util.matcher.IpAddressMatcher
org.springframework.security.web.util.RequestMatcherEditor  org.springframework.security.web.util.matcher.RequestMatcherEditor
org.springframework.security.web.util.RegexRequestMatcher org.springframework.security.web.util.matcher.RegexRequestMatcher

WebSecurityExpressionHandler

WebSecurityExpressionHandler 已被删除以支持使用 SecurityExpressionHandler

这意味着您可能有以下情况:

WebSecurityExpressionHandler handler = ...

这需要更新为:

SecurityExpressionHandler<FilterInvocation> handler = ...

您可以像这样实现 WebSecurityExpressionHandler

public class CustomWebSecurityExpressionHandler implements WebSecurityExpressionHandler {
      ...
}

然后它必须更新为:

public class CustomWebSecurityExpressionHandler implements SecurityExpressionHandler<FilterInvocation> {
     ...
}

@AuthenticationPrincipal

org.springframework.security.web.bind.annotation.AuthenticationPrincipal 已被弃用,取而代之的是 org.springframework.security.core.annotation.AuthenticationPrincipal。例如:

import org.springframework.security.web.bind.annotation.AuthenticationPrincipal;
// ...

@RequestMapping("/messages/inbox")
public ModelAndView findMessagesForUser(@AuthenticationPrincipal CustomUser customUser) {
      // .. find messages for this user and return them ...
}

这应该替换为:

import org.springframework.security.core.annotation.AuthenticationPrincipal;
// ...

@RequestMapping("/messages/inbox")
public ModelAndView findMessagesForUser(@AuthenticationPrincipal CustomUser customUser) {
      // .. find messages for this user and return them ...
}

Migrating default filter URLs

JAAS

不幸的是,我们没有空间来讨论 Spring Security 的 JAAS 集成。但是,在 https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#jaas-sample。事实上,还有关于 JAAS 集成的优秀文档,可以在 Spring Security 参考中找到 https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#jaas。查看 JAAS 参考文档时,您会注意到,从 Spring Security 4.2 开始,添加了对使用具有任意 JAAS 配置实现的 JAAS 登录模块的支持。 Spring Security 4.2 还在 <http> 元素中添加了 jaas-api-provision 属性,这确保为可能也依赖于JAAS 主题。

Summary

本章回顾了将现有 Spring Security 3 项目升级到 Spring Security 4.2 时会发现的主要和次要更改。在本章中,我们回顾了可能推动升级的框架的重大改进。我们还检查了升级要求、依赖项和常见代码类型,以及会阻止应用程序在升级后工作的配置更改。我们还涵盖了对 Spring Security 作者作为代码库重组的一部分所做的整体代码重组更改的调查(在高层次上)。

如果这是您阅读的第一章,我们希望您回到本书的其余部分,并以本章为指导,让您升级到 Spring Security 4.2 尽可能顺利!