Spring Secuirty Oauth 2 - 多用户身份验证服务

Kon*_*rad 5 java spring oauth spring-security spring-security-oauth2

我的应用程序提供的oauth2令牌服务与以下github项目中提供的服务相同:https://github.com/iainporter/oauth2-provider

它基于Spring Security OAuth2.

我提供了UserDetailsS​​ervice的自定义实现:

<bean id="userService" class="org.example.core.service.DBUserServiceImpl" />
Run Code Online (Sandbox Code Playgroud)

和以下用户身份验证管理器:

<sec:authentication-manager alias="userAuthenticationManager">
    <sec:authentication-provider user-service-ref="userService">
        <sec:password-encoder ref="passwordEncoder" />
    </sec:authentication-provider>
</sec:authentication-manager>
Run Code Online (Sandbox Code Playgroud)

现在我想提供其他用户身份验证方法(其他UserDetailsS​​ervice),例如:

<bean id="otherUserService" class="org.example.core.service.LDAPUserServiceImpl" />
Run Code Online (Sandbox Code Playgroud)

不幸的是我没有找到如何在文档中做到这一点的方法.在请求级别,我想区分哪个方法(哪个用户服务)使用:

  • 查询参数
  • http标头(例如RealmName)

Mit*_*hun 6

您需要使用DelegatingAuthenticationEntryPoint配置多个入口点.这意味着您可以使用多种方式进行身份验证.以下是示例代码:

DBUser入口点:

public class DBUserAuthencticationEntryPoint extends BasicAuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request,
            HttpServletResponse response, AuthenticationException authException)
            throws IOException, ServletException {
        super.commence(request, response, authException);
    }
}
Run Code Online (Sandbox Code Playgroud)

LDAP入口点:

public class LDAPAuthencticationEntryPoint extends BasicAuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request,
            HttpServletResponse response, AuthenticationException authException)
            throws IOException, ServletException {
         super.commence(request, response, authException);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你需要创建RequestMatchers来选择正确的入口点(基于头/域名):

DBUser请求匹配器:

RequestMatcher dbUserMatcher = new RequestMatcher() {       
    @Override
    public boolean matches(HttpServletRequest request) {
        // Logic to identify a DBUser kind of reqeust
    }
};
Run Code Online (Sandbox Code Playgroud)

LDAP用户请求匹配器:

RequestMatcher ldapMatcher = new RequestMatcher() {     
    @Override
    public boolean matches(HttpServletRequest request) {
        // Logic to identify a LDAP kind of reqeust
    }
};
Run Code Online (Sandbox Code Playgroud)

现在我们需要添加这些匹配器和入口点DelegatingAuthenticationEntryPoint.在运行时DelegatingAuthenticationEntryPoint选择入口点并根据返回的匹配器进行身份验证true.

DBUserAuthencticationEntryPoint dbUserEntryPoint = new DBUserAuthencticationEntryPoint();
LDAPAuthencticationEntryPoint ldapEntryPoint  = new LDAPAuthencticationEntryPoint();

LinkedHashMap<RequestMatcher,AuthenticationEntryPoint> entryPoints = new LinkedHashMap<RequestMatcher,AuthenticationEntryPoint>();
entryPoints.put(ldapMatcher, ldapEntryPoint);
entryPoints.put(dbUserMatcher, dbUserEntryPoint);

DelegatingAuthenticationEntryPoint delegatingAuthenticationEntryPoint  = new DelegatingAuthenticationEntryPoint(entryPoints);
Run Code Online (Sandbox Code Playgroud)

现在映射DelegatingAuthenticationEntryPointHttpSecurityconfigure()方法:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.
            authorizeRequests().
                regexMatchers("/login.*").permitAll().
                regexMatchers("/api.*").fullyAuthenticated().        
        and().
            formLogin().loginPage("/login").
        and().
            exceptionHandling().authenticationEntryPoint(delegatingAuthenticationEntryPoint);
    }
}
Run Code Online (Sandbox Code Playgroud)

配置提供程序管理器:

@Bean
public AuthenticationManager authenticationManager() {
    return new ProviderManager(Arrays.asList(provider1, provider2);
}
Run Code Online (Sandbox Code Playgroud)