Spring Security Authentication Provider – Spring安全认证供应商

最后修改: 2013年 6月 2日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’ll learn how to set up an Authentication Provider in Spring Security, allowing for additional flexibility compared to the standard scenario using a simple UserDetailsService.

在本教程中,我们将学习如何在Spring Security中设置Authentication Provider,与使用简单的UserDetailsService的标准场景相比,允许更多的灵活性。

2. The Authentication Provider

2.认证提供者

Spring Security provides a variety of options for performing authentication. These options follow a simple contract; an Authentication request is processed by an AuthenticationProvider, and a fully authenticated object with full credentials is returned.

Spring Security为执行认证提供了多种选择。这些选项遵循一个简单的契约;一个Authentication请求由AuthenticationProvider处理,并返回一个带有完整凭证的完全认证对象。

The standard and most common implementation is the DaoAuthenticationProvider, which retrieves the user details from a simple, read-only user DAO, the UserDetailsService. This User Details Service only has access to the username in order to retrieve the full user entity, which is enough for most scenarios.

标准和最常见的实现是DaoAuthenticationProvider,它从一个简单的、只读的用户DAO,即UserDetailsService中检索用户细节。这个用户详情服务仅能访问用户名,以便检索完整的用户实体,这对大多数场景来说已经足够了。

More custom scenarios will still need to access the full Authentication request to be able to perform the authentication process. For example, when authenticating against some external, third party service (such as Crowd), both the username and password from the authentication request will be necessary.

更多的自定义场景仍然需要访问完整的Authentication请求,以便能够执行认证过程。例如,当针对一些外部的第三方服务(例如Crowd)进行认证时,认证请求中的用户名密码都将是必要的

For these more advanced scenarios, we’ll need to define a custom Authentication Provider:

对于这些更高级的场景,我们需要定义一个自定义的认证提供者

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Override
    public Authentication authenticate(Authentication authentication) 
      throws AuthenticationException {
 
        String name = authentication.getName();
        String password = authentication.getCredentials().toString();
        
        if (shouldAuthenticateAgainstThirdPartySystem()) {
 
            // use the credentials
            // and authenticate against the third-party system
            return new UsernamePasswordAuthenticationToken(
              name, password, new ArrayList<>());
        } else {
            return null;
        }
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}

Notice that the granted authorities set on the returned Authentication object are empty. This is because authorities are, of course, application specific.

请注意,在返回的Authentication对象上设置的授予权限是空的。这是因为授权当然是特定于应用程序的。

3. Register the Auth Provider

3.注册认证提供者

Now that we’ve defined the Authentication Provider, we need to specify it in the XML Security Configuration using the available namespace support:

现在我们已经定义了认证提供者,我们需要使用可用的命名空间支持在XML安全配置中指定它。

<http use-expressions="true">
    <intercept-url pattern="/**" access="isAuthenticated()"/>
    <http-basic/>
</http>

<authentication-manager>
    <authentication-provider
      ref="customAuthenticationProvider" />
</authentication-manager>

4. Java Configuration

4.Java配置[/strong]

Next, we’ll take a look at the corresponding Java configuration:

接下来,我们来看看相应的Java配置。

@Configuration
@EnableWebSecurity
@ComponentScan("com.baeldung.security")
public class SecurityConfig {

    @Autowired
    private CustomAuthenticationProvider authProvider;

    @Bean
    public AuthenticationManager authManager(HttpSecurity http) throws Exception {
        AuthenticationManagerBuilder authenticationManagerBuilder = 
            http.getSharedObject(AuthenticationManagerBuilder.class);
        authenticationManagerBuilder.authenticationProvider(authProvider);
        return authenticationManagerBuilder.build();
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .anyRequest()
            .authenticated()
            .and()
            .httpBasic();
        return http.build();
    }

}

5. Performing Authentication

5.进行认证

Requesting Authentication from the Client is basically the same with or without this custom authentication provider on the back end.

无论后端是否有这个定制的认证提供者,从客户端请求认证基本上都是一样的。

We’ll use a simple curl command to send an authenticated request:

我们将使用一个简单的curl命令来发送一个认证的请求。

curl --header "Accept:application/json" -i --user user1:user1Pass 
    http://localhost:8080/spring-security-custom/api/foo/1

For the purposes of this example, we secured the REST API with Basic Authentication.

在这个例子中,我们用基本认证来保护REST API。

And we get back the expected 200 OK from the server:

而我们从服务器上得到了预期的200 OK。

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=B8F0EFA81B78DE968088EBB9AFD85A60; Path=/spring-security-custom/; HttpOnly
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sun, 02 Jun 2013 17:50:40 GMT

6. Conclusion

6.结论

In this article, we explored an example of a custom authentication provider for Spring Security.

在这篇文章中,我们探讨了一个为Spring Security定制认证提供商的例子。

The full implementation of this article can be found in the GitHub project.

本文的完整实现可以在GitHub项目中找到。