当前位置: 首页 > 知识库问答 >
问题:

Spring Security OAuth2,在2.0版中具有自定义TokenGranter。

苏嘉志
2023-03-14

在OAuth2的早期版本中,可以通过将自定义令牌授予者添加到< code >中的xml配置来添加它

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

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

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

这导致依赖项解析异常,因为构造Granter所需的令牌服务不能自动连接。

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

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

}

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

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

共有3个答案

葛威
2023-03-14

我找不到一种方法来做到这一点,因为对ClientDetailService的依赖使得从getTokenGranter方法获取默认授予者变得困难。我从AuthorizationServerEndpoint sConfigrer#TokenGranter()复制了代码,并将我的clientDetailService和其他bean直接传递给构造函数。请注意,我添加了创建一个DefaultOAuth2Request estFactory以传递给授予者和endpoint:

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());
    }

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

闻人博
2023-03-14

这里有另一条路。从这里复制。

在这个例子中,一个新的自定义TokenGranter,名为CustomTokenGranter,被添加到默认TokenGrantersCompositeTokenGranter中。我喜欢这个例子,因为它使用AuthorizationServerEndpoint sConfigrer的公共方法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);
    }
公良弘毅
2023-03-14

您还需要添加默认设置,例如使用< code > CompositeTokenGranter :

        List<TokenGranter> tokenGranters = getTokenGranters(); // implementation up to you
        tokenGranter = new CompositeTokenGranter(tokenGranters);
        endpoints.tokenGranter(tokenGranter);
 类似资料:
  • 我有一个元注释,它注释了我的测试类: 而我的测试类看起来是: 然后我得到了这个异常:的多个声明详细信息:

  • 我正在做表A和表B的左连接,并试图将结果提取到自定义POJO中,该POJO具有表A和表B中的字段,如下所示: 它适用于除myCode字段之外的所有字段,myCode字段是连接这两个表的字段。对我来说,myCode的值是从正确的表B中获取的,表A中的所有记录在表B中都没有相应的条目。我想知道jooQ如何决定映射到POJO的字段,以及是否在任何地方记录了这种行为。 我的目标是将表A和表B中的所有字段提

  • 问题内容: 这是我的http服务器: 我需要在myHander内部访问实例t1。 有什么办法吗? 谢谢! 问题答案: 有一种方法可以将属性设置为class: 您必须注意,在所有使用myHandler的地方都将是t1的相同实例

  • 问题内容: 我将Google App Engine用作我的android和Web应用程序的服务器,我使用Eclipse开发了使用Android Studio和Web应用程序的android应用程序。我在App Engine中部署了两个版本,第一个是Android应用程序,第二个是Web应用程序。我有自己的域名,该域名指向应用引擎的默认版本。我的问题是如何通过自定义域名指向第二版。我阅读了Googl

  • 问题内容: 如何在Go中创建只能接受有效值的自定义类型?例如,我要创建一个名为“名称”的类型,其基础类型为字符串。但是,它只能接受值“ John”,“ Rob”或“ Paul”。其他任何值都将返回错误。我已经以非常简单的方式创建了以下程序,以表示我想要实现的目标。 http://play.golang.org/p/jzZwALsiXz 编写此代码的最佳方法是什么? 问题答案: 您可以执行以下操作(

  • 我正在努力裁剪javax。验证。ConstraintValidator和javax。验证。根据我的需要限制ValidatorContext。我从格式错误的请求正文收到的响应消息始终采用以下形状: <代码> 此消息也以500而不是400错误请求的形式返回。我无法获得工作到解决方案来执行以下操作: 仅包括<代码> 我有以下代码: 向上面的代码发送格式错误的有效负载将导致如下消息: 我希望能够收到以下信