11

在以前版本的 OAuth2 中,可以通过将自定义令牌授予者添加到<authorization-server>元素中的 xml 配置中来添加它。

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

第一次尝试是使用 @Component 创建 TokenGranter:

@Component("customTokenGranter")
public class CustomTokenGranter {
     //implementation
}

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

第二次尝试是使用配置方法

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

}

使用它,将不会注册默认授权类型。

我还尝试了第二个较低阶的配置,但没有成功。我还能做些什么来添加我的自定义授权类型?

4

4 回答 4

11

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

        List<TokenGranter> tokenGranters = getTokenGranters(); // implementation up to you
        tokenGranter = new CompositeTokenGranter(tokenGranters);
        endpoints.tokenGranter(tokenGranter);
于 2014-08-12T17:32:10.670 回答
11

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

在此示例中,将一个TokenGranter名为的新自定义CustomTokenGranter添加到CompositeTokenGranter具有默认值的 a 中TokenGranters。我喜欢这个例子,因为它使用AuthorizationServerEndpointsConfigurer' 的公共方法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);
    }
于 2018-05-09T15:55:59.543 回答
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());
    }

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

于 2015-03-17T22:50:06.383 回答
2

根据文档,我们有:

资助类型

AuthorizationEndpoint 支持的授权类型可以通过 AuthorizationServerEndpointsConfigurer 进行配置。默认情况下,除了密码之外的所有授权类型都受支持(有关如何打开它的详细信息,请参见下文)。以下属性会影响授权类型:

authenticationManager:通过注入 AuthenticationManager 来启用密码授权。……

请参阅文档。所以你可以像这样注入 AuthenticationManager :

    @Configuration
    @EnableAuthorizationServer
    public class AuthorizationServerConfigurer extends AuthorizationServerConfigurerAdapter {

        @Autowired
        private AuthenticationManager authenticationManager;

        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            endpoints
                    .authenticationManager(authenticationManager)
........
于 2017-08-21T05:23:03.243 回答