Spring Security OAuth2,版本2.0中带有自定义TokenGranter.+

Chr*_*ler 8 java spring spring-security-oauth2 spring-java-config

在以前版本的OAuth2中,可以通过将自定义标记granter添加到<authorization-server>元素中的xml配置来添加它.

我想知道如何使用AuthorizationServerConfigurerAdapter使用Java Config扩展授权服务器,而不会丢失包含隐式,客户端凭据,刷新令牌和授权代码授权类型的默认配置.

首次尝试使用@Component创建TokenGranter:

@Component("customTokenGranter")
public class CustomTokenGranter {
     //implementation
}
Run Code Online (Sandbox Code Playgroud)

这导致依赖性解决异常,因为构造Granter所需的tokenServices无法自动装配.

第二次尝试使用configure方法

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception
{
    endpoints
        .tokenGranter(new CustomTokenGranter(endpoints.getTokenServices(),
                endpoints.getClientDetailsService(), endpoints.getOAuth2RequestFactory()));

}
Run Code Online (Sandbox Code Playgroud)

使用此选项,将不会注册默认授权类型.

我也尝试了低阶的第二种配置,但没有成功.我还可以做些什么来添加自定义授权类型?

Dav*_*yer 10

您还需要添加默认值,例如使用CompositeTokenGranter:

        List<TokenGranter> tokenGranters = getTokenGranters(); // implementation up to you
        tokenGranter = new CompositeTokenGranter(tokenGranters);
        endpoints.tokenGranter(tokenGranter);
Run Code Online (Sandbox Code Playgroud)

  • 我通过为原始CompositeTokenGranter开发一个装饰器来解决它,它可以使用endpoints.getTokenGranter()的结果进行初始化.装饰器还有一个add方法来添加额外的granters.然后在grant方法中,我首先尝试自定义granters,然后委托给原始的CompositeTokenGranter. (2认同)
  • 在调用`endpoints.getTokenGranter()`时没有遇到问题吗?因为“ clientDetailsS​​ervice”(在“端点”内)在此阶段未正确初始化。而且您也无法使用“ endpoints.clientDetailsS​​ervice(clientDetailsS​​ervice)”将其设置为“ yooture.web.config.SecurityOauth2Configuration.AuthorizationServerConfiguration.configure( ClientDetailsS​​erviceConfigurer)仍将被调用,并再次覆盖一些引用。 (2认同)

lor*_*m2k 5

由于对 ClientDetailService 的依赖使得很难从 getTokenGranter 方法中获取默认授予者,因此我找不到一种方法来做到这一点。我从 AuthorizationServerEndpointsConfigurer#tokenGranter() 复制了代码并将我的 clientDetailService 和其他 bean 直接传递给构造函数。请注意,我添加以创建一个 DefaultOAuth2RequestFactory 以传递给授予者和端点:

public TokenGranter tokenGranter() {

            ClientDetailsService clientDetails = clientDetailsService;
            AuthorizationServerTokenServices tokenServices = tokenServices();
            AuthorizationCodeServices authorizationCodeServices = authorizationCodeServices();
            OAuth2RequestFactory requestFactory = requestFactory();

            List<TokenGranter> tokenGranters = new ArrayList<TokenGranter>();

            tokenGranters.add(new AuthorizationCodeTokenGranter(tokenServices, authorizationCodeServices,
                    clientDetails, requestFactory));
            tokenGranters.add(new RefreshTokenGranter(tokenServices, clientDetails, requestFactory));
            tokenGranters.add(new ImplicitTokenGranter(tokenServices, clientDetails, requestFactory));
            tokenGranters.add(new ClientCredentialsTokenGranter(tokenServices, clientDetails, requestFactory));
            tokenGranters.add(new ResourceOwnerPasswordTokenGranter(authenticationManager, tokenServices,
                        clientDetails, requestFactory));
            tokenGranters.add(new CustomTokenGranter(authenticationManager, tokenServices(), clientDetailsService,
                    requestFactory));

            return new CompositeTokenGranter(tokenGranters);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {

        endpoints
                .tokenServices(tokenServices())
                .tokenStore(tokenStore())
                .tokenEnhancer(tokenEnhancer())
                .authorizationCodeServices(authorizationCodeServices())
                .userApprovalHandler(userApprovalHandler())
                .authenticationManager(authenticationManager)
                .requestFactory(requestFactory())
                .tokenGranter(tokenGranter());
    }
Run Code Online (Sandbox Code Playgroud)

话虽如此,我最终删除了该代码并简单地添加了另一个 AuthenticationProvider ,因为我的新授权类型无论如何都使用 UsernamePasswordAuthenticationToken 的子类,这是密码授权默认使用的身份验证类型。


Jos*_*nez 5

这是另一种方式。 从这里复制。

在此示例中,TokenGranter名为的新自定义CustomTokenGranter添加到,CompositeTokenGranter带有default TokenGranters。我喜欢这个例子,因为它使用AuthorizationServerEndpointsConfigurer的public方法getTokenGranter()检索默认值TokenGranter

@Configuration
@EnableAuthorizationServer
protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager);
        endpoints.tokenGranter(tokenGranter(endpoints));
    }

    private TokenGranter tokenGranter(final AuthorizationServerEndpointsConfigurer endpoints) {
        List<TokenGranter> granters = new ArrayList<TokenGranter>(Arrays.asList(endpoints.getTokenGranter()));
        granters.add(new CustomTokenGranter(endpoints.getTokenServices(), endpoints.getClientDetailsService(), endpoints.getOAuth2RequestFactory(), "custom"));
        return new CompositeTokenGranter(granters);
    }
Run Code Online (Sandbox Code Playgroud)