Spring Security和OAuth2使用自定义授权类型生成令牌

时间:2015-03-13 14:01:22

标签: java spring spring-security spring-security-oauth2

我使用Spring + Oauth2来保护网络服务,并且我添加了自定义授权类型(自定义授权):

<bean id="myTokenGranter" class="com.example.oauth2.MyTokenGranter" />

<oauth:authorization-server client-details-service-ref="client-details-service" token-services-ref="tokenServices">
    <oauth:refresh-token/>
    <oauth:password/>
    <oauth:custom-grant token-granter-ref="myTokenGranter" />
</oauth:authorization-server>

Spring调用实现就好了。但是,我不知道如何在这里实际生成令牌。我看到他们使用了一个名为&#34; RandomValueStringGenerator&#34;但我不确定是否有更好的方法,而且我不知道如何产生一个好的&#34;令牌应该是多长时间,或者春天是否真的检查了令牌的唯一性等等。有没有办法可以在这里调用Spring自己的发电机部件?

现在是我的tokengranter课程:

public class MyTokenGranter implements TokenGranter {

private RandomValueStringGenerator generator = new RandomValueStringGenerator();

@Override
public OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest) {
    //...logic added here later
    return new DefaultOAuth2AccessToken(generator.generate());
}

}

我无法找到一个很好的例子,在春天的ouath2来源中只有一半执行测试tokengranter。

2 个答案:

答案 0 :(得分:1)

好的,所以这可以通过org.springframework.security.oauth2.provider.token.AbstractTokenGranter来实现,通过复制或尝试传递正确的构造函数。我只是发布它给任何有同样问题的人。你也可以扩展AbstractTokenGranter,但是我没能通过正确的构造函数

这是我的实施:

public class MyTokenGranter implements TokenGranter {

@Autowired
private AuthorizationServerTokenServices tokenService;

@Autowired
private ClientDetailsService clientDetailsService;

@Autowired
private DefaultOAuth2RequestFactory defaultOauth2RequestFactory;

private String grantType;

@Override
public OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest) {
    if (!this.grantType.equals(grantType)) {
        return null;
    }
    String clientId = tokenRequest.getClientId();
    ClientDetails client = clientDetailsService.loadClientByClientId(clientId);
    validateGrantType(grantType, client);
    return getAccessToken(client, tokenRequest);
}

protected OAuth2AccessToken getAccessToken(ClientDetails client, TokenRequest tokenRequest) {
    return tokenService.createAccessToken(getOAuth2Authentication(client, tokenRequest));
}

protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
    OAuth2Request storedOAuth2Request = defaultOauth2RequestFactory.createOAuth2Request(client, tokenRequest);
    return new OAuth2Authentication(storedOAuth2Request, null);
}

protected void validateGrantType(String grantType, ClientDetails clientDetails) {
    Collection<String> authorizedGrantTypes = clientDetails.getAuthorizedGrantTypes();
    if (authorizedGrantTypes != null && !authorizedGrantTypes.isEmpty()
            && !authorizedGrantTypes.contains(grantType)) {
        throw new InvalidClientException("Unauthorized grant type: " + grantType);
    }
}

public String getGrantType() {
    return grantType;
}

public void setGrantType(String grantType) {
    this.grantType = grantType;
}

}

Xml config:

<bean id="myTokenGranter" class="com.example.MyTokenGranter">
  <property name="grantType" value="custom-grant" />
</bean>
<oauth:authorization-server client-details-service-ref="clientDetailsService" token-services-ref="tokenServices">
    <oauth:refresh-token/>
    <oauth:password/>
    <oauth:custom-grant token-granter-ref="myTokenGranter" />
</oauth:authorization-server>

答案 1 :(得分:0)

更多只是一个FYI,但如果扩展AbstractTokenGranter,则可以使用constructor-arg。例如:

public class MyTokenGranter extends AbstractTokenGranter
{
    private static final String GRANT_TYPE = "custom-grant";

    protected MyTokenGranter(
            AuthorizationServerTokenServices tokenServices,
            ClientDetailsService clientDetailsService )
    {
        super( tokenServices, clientDetailsService, GRANT_TYPE );
    }

    @Override
    protected OAuth2Authentication getOAuth2Authentication(AuthorizationRequest clientToken) 
    {
        throw new RuntimeException( "Not implemented" );
    }
}

<bean id="myTokenGranter" class="com.example.MyTokenGranter">
    <constructor-arg ref="tokenServices"/>
    <constructor-arg ref="clientDetailsService"/>
</bean>