本文介绍了在Spring Security中实现自定义身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想就Spring Security中的问题向您寻求帮助。
我有一个要求,其中我必须根据用户选择的选项验证登录凭证。选项1将通过第三方服务验证登录用户。选项2是使用数据库身份验证级别的正常验证。我该如何实现呢?

I would like to ask for your help regarding my problem in Spring Security.I have a requirement wherein I have to validate a login credential based on the option selected by the user. Option 1 would be validating the logged in user via third party service. Option 2 would be the normal validation using database authentication level. How can I implement this?

推荐答案




  1. 提供委托的 org.springframework.security.authentication.AuthenticationProvider 的自定义实现对相应后端的身份验证(第三方服务,另一个 AuthenticationProvider 等)。

  2. 将用户选择的选项传递给自定义 AuthenticationProvider ,使其能够选择正确的身份验证后端。

  3. 配置自定义 AuthenticationProvider 作为默认身份验证提供程序。

  1. Provide a custom implementation of org.springframework.security.authentication.AuthenticationProvider that delegates the authentication to the appropriate backend (third-party service, another AuthenticationProvider, etc.).
  2. Pass the user-selected option to the custom AuthenticationProvider to enable it to choose the correct authentication backend.
  3. Configure the custom AuthenticationProvider as the default authentication provider.







AuthenticationProvider 是具有单个方法的接口。因此,自定义实现可能如下所示:

AuthenticationProvider is an interface with a single method. Therefore, a custom implementation may look like:

class DelegatingAuthenticationProvider implements AuthenticationProvider {
  @Autowired
  private ThirdPartyAuthenticationService service;

  @Autowired
  @Qualifier("anotherAuthenticationProvider")
  private AuthenticationProvider provider;

  @Override
  public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
    // Get the user selection.
    String selection = (String) authentication.getDetails();

    // Take action depending on the selection.
    Authentication result;
    if("ThirdParty".equals(selection)) {
      // Authenticate using "service" and generate a new
      // Authentication "result" appropriately.
    }
    else {
      // Authenticate using "provider" and generate a new
      // Authentication "result" appropriately.
    }

    return result;
  }
}



上面的 AuthenticationProvider 实现从身份验证详细信息属性中选择用户选择c $ c>对象。据推测,用户选择必须从 HttpServletRequest 中选取,然后在<$之前添加到 Authentication 对象中。 c $ c> AuthenticationProvider 被调用。这意味着,另一个组件可以访问身份验证 HttpServletRequest 对象,并在<$ c $之前调用c> AuthenticationProvider 需要实现。

The AuthenticationProvider implementation above picks up the user selection from the details property of the Authentication object. Presumably, the user selection would have to be picked up from the HttpServletRequest and added to the Authentication object before the AuthenticationProvider is invoked. This means, another component that has access to both the Authentication and HttpServletRequest objects and is invoked before the AuthenticationProvider needs to be implemented.

身份验证对象是由实现 AbstractAuthenticationProcessingFilter 。此类有一个名为 attemptAuthentication 的方法,它接受 HttpServletRequest 对象并返回身份验证对象。因此,这似乎是实施所需内容的良好候选者。对于基于用户名密码的身份验证,实现类是 UsernamePasswordAuthenticationFilter 。此类返回 UsernamePasswordAuthenticationToken 的新实例,该实例是身份验证的实现。因此,扩展 UsernamePasswordAuthenticationFilter 的类应该足够了。

The Authentication object is created by an implementation of AbstractAuthenticationProcessingFilter. This class has a method named attemptAuthentication that accepts an HttpServletRequest object and returns an Authentication object. So it seems this would be a good candidate for implementing what is needed. For username-password based authentication, the implementation class is UsernamePasswordAuthenticationFilter. This class returns a new instance of UsernamePasswordAuthenticationToken, which is an implementation of Authentication. So, a class extending UsernamePasswordAuthenticationFilter should be sufficient.

class ExtendedUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
  @Override
  public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
    ...
    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, password);
    authentication.setDetails(obtainUserSelection(request));

    ...

    return authentication;
  }
}

obtainUserSelection 是一种私有方法,可以让用户从请求中选择。

obtainUserSelection is a private method that gets the user selection out of the request.

在Spring Security配置中配置 AuthenticationProvider 并过滤实现。具体步骤将根据是使用XML还是Java配置而有所不同。

Configure the AuthenticationProvider and filter implementations in the Spring Security configuration. The exact steps will vary depending on whether XML or Java configuration is used.

这篇关于在Spring Security中实现自定义身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 03:11