Spring security 使用LDAP在Spring oauth/token请求上验证客户端id和客户端机密

Spring security 使用LDAP在Spring oauth/token请求上验证客户端id和客户端机密,spring-security,spring-oauth2,Spring Security,Spring Oauth2,我正在研究如何使用LDAP对客户机id和客户机机密进行身份验证 注意:此Kotlin代码 @Configuration @EnableAuthorizationServer class OAuth2AuthorizationServerConfig() : AuthorizationServerConfigurerAdapter() { 我对Spring比较陌生,似乎这不是我应该尝试的事情?然而,这似乎是一个有用的选择。为什么?因为它允许我将客户机机密管理委托给LDAP目录,并有效地允许我的o

我正在研究如何使用LDAP对客户机id和客户机机密进行身份验证

注意:此Kotlin代码

@Configuration
@EnableAuthorizationServer
class OAuth2AuthorizationServerConfig() : AuthorizationServerConfigurerAdapter() {
我对Spring比较陌生,似乎这不是我应该尝试的事情?然而,这似乎是一个有用的选择。为什么?因为它允许我将客户机机密管理委托给LDAP目录,并有效地允许我的ops团队更改机密(以某种托管方式)。有了这个,我的应用程序就不需要知道这个秘密了。这看起来很整洁

oauth的终点是基本身份验证——这似乎是Spring通过
@EnableAuthorizationServer
注释给我的。向
http://somehost/oauth/token
指定
授权类型
客户端凭据

我创建代码来获取任意令牌(沙盒)…我只想指定客户端和应用于该客户端的作用域,而不是指定秘密

@Throws(Exception::class)
override fun configure(
        clients: ClientDetailsServiceConfigurer
) {
    // Inlining will create a store per credential entry
    val serviceBuilder = clients.inMemory()
    serviceBuilder.withClient("user").secret("test").scopes("XXX")
}
我尝试了大量不同的想法,将
LDAP身份验证提供程序添加到
ProviderManager
中的托管提供程序集中,但迄今为止都失败了。如果我在运行时调试到
authenticate
方法中,我总是只有
AnonymousAuthenticationProvider
DaoAuthenticationProvider

下面可能显示了我的经验不足,但这里有一个示例,请阅读下面可能出现的问题-只是想看看我是否可以注入
ldapaauthenticationprovider

@Autowired
lateinit var providerMan: AuthenticationManager

@Throws(Exception::class)
override fun configure(endpoints: AuthorizationServerEndpointsConfigurer) {
    (providerMan as ProviderManager).providers.add(0,
            LdapAuthenticationProvider(
                    PasswordComparisonAuthenticator(PasswordPolicyAwareContextSource("ldap://something"))
            )
    )
}
所以问题很简单。。。
有没有办法添加一个
ldapaauthenticationprovider
,这样我就可以使用LDAP来验证客户端id和客户端机密?

要在LDAP中拥有客户端id和机密,您需要一个基于LDAP的
clientdetailssservice
实现,而这在Spring-Security-OAuth中是不存在的。也许将该实现构建为通往
ldapaauthenticationprovider
的桥梁是可行的,但我不确定这是否是一个好主意。无论如何,您必须自己构建实现。

我想为社区的答案添加一些细节

我有一个原型工作感谢的建议。 我正在使用连接到LDAP服务器

解决方案相当简单-只需创建一个
ClientDetailsService
,检索与传递给
loadClientByClientId
的clientId匹配的LDAP条目,并返回一个适当的
ClientDetails
对象(使用Spring提供的
BaseClientDetails

您还需要创建一个自定义的
密码编码器
,或者如果Spring为您提供了必要的:

override fun configure(security: AuthorizationServerSecurityConfigurer) {
    security.passwordEncoder(SomePasswordEncoder)
}

默认设置为纯文本密码编码器。

从何处获取客户端密码?一般来说,您无法从LDAP获取密码。我的理解是,用于连接LDAP目录(在我的情况下为AD)的绑定用户必须具有密码属性的权限。因此,您可以使用自定义
客户端详细信息服务中的
客户端机密
作为用户的LDAP密码(
客户端id
)?然后从LDAP获取该用户的密码,对吗?如果密码错误,您会在
ClientDetails服务
中引发异常,对吗?不,对于我当前的原型,我只返回带有客户端密钥集的ClientDetails。Spring管道通过Spring提供给AuthorizationServer的DaoAuthenticationProvider进行客户端\u秘密比较。我已经读了更多,并且看到我可能需要考虑LDAP比较请求来做密码比较(您的初始注释)。我“认为”这意味着我需要一个自定义密码编码器,但我还不知道如何使用,因为编码器在运行时没有clientid:-(.如何使用Ldap比较操作验证密码?…我遇到了一个障碍-…因为
loadClientByClientId(String clientid)
不知道客户端密码我无法使用Ldap比较操作来验证密码。
密码编码器匹配(…)
方法不知道客户端id?有进一步的建议吗?好吧,我可以通过将
MyClientDetailsService
a
@Component
@Autowire
放入我的
AuthorizationServerConfigurerAdapter
中来“破解”它。然后保留客户端id并将
MyClientDetailsService
传递给我的自定义
密码编码器
然后在运行时,PasswordEncoder可以请求Ldap密码,与传递到
匹配项中的
rawPassword
进行比较,我从
MyClientDetailsService
中持有的客户端ID看起来有点奇怪/诡异?我对所有的内部结构都不太熟悉,但从JDBC实现来看de>loadClientByClientId(String clientId)
似乎不需要(或应该)验证密码。Spring Security似乎设置了一个专用的身份验证提供程序,使用ClientDetailUserDetails服务将客户端详细信息包装成用户详细信息,并在加载客户端详细信息后比较密码。