在 JWT Grant 中,我如何将 JWT 令牌中包含的授权声明关联到与交换的访问令牌关联的范围?
In the JWT Grant how can I associate the authorization claims contained in a JWT token to the scopes associated to the exchanged access token?
这是我需要完成此集成的最后一块:
我有一个生成 JWT 令牌的外部身份提供者。这些令牌包含包含用户权限的声明 "auth",例如:"auth" : [ "editor", "reviewer"]
.
在 WSO2 中,我有一个 API,它的某些端点需要 "editor" 范围 :
- 我正在使用 JWT Grant 从外部 IP 交换 JWT 以获取 WSO2 访问令牌以调用 API。
我需要在 WSO2 创建访问令牌时将其与 JWT 的 "auth" 声明中包含的范围相关联。
这可能吗?有没有可以实现的扩展点?
这应该可以通过扩展 JWT 授权类型和覆盖 validateScope 方法来实现。您可以从 JWT 检索范围并将其设置为 tokReqMsgCtx。然后你应该能够像下面这样设置范围。
@Override
public boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) {
// Create scopes array
// String scopes[] = getScopesFromJWT();
tokReqMsgCtx.setScope(scopes);
return true;
}
例如,看看这是如何为 SAML2 承载授权类型 [1] 完成的。
如果您使用的是 JWT 授权类型,它是在 "repository/conf/identity/identity.xml" 文件的 SupportedGrantTypes 部分中配置的。配置中提到了相关的 GrantTypeHandlerImplClass。
<SupportedGrantType>
<GrantTypeName>urn:ietf:params:oauth:grant-type:jwt-bearer</GrantTypeName
<GrantTypeHandlerImplClass>org.wso2.carbon.identity.oauth2.grant.jwt.JWTBearerGrantHandler</GrantTypeHandlerImplClass>
....
</SupportedGrantType>
有关编写自定义授权类型的信息,请参阅文档[2]。
[2]https://docs.wso2.com/display/IS560/Writing+a+Custom+OAuth+2.0+Grant+Type
这就是我最终解决它的方法 JWTBearerGrantHandler
:
public class JWTBearerGrantHandlerJWTAuthAware extends JWTBearerGrantHandler {
private static final Log LOG = LogFactory.getLog(JWTBearerGrantHandlerJWTAuthAware.class);
@Override
public boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) throws IdentityOAuth2Exception {
LOG.debug("validateScope()");
try {
final RequestParameter[] requestParameters = tokReqMsgCtx.getOauth2AccessTokenReqDTO().getRequestParameters();
RequestParameter assertion = null;
for (RequestParameter rp : requestParameters) {
if (rp.getKey().equals("assertion")) {
assertion = rp;
}
}
if (assertion != null) {
final String jwtString = assertion.getValue()[0];
try {
final JWT jwt = JWTParser.parse(jwtString);
final Object auth = jwt.getJWTClaimsSet().getClaim("auth");
if (auth != null) {
final JSONArray roles = (JSONArray) ((Map) auth).get("roles");
final String[] rolesArray = roles.toArray(new String[0]);
LOG.debug("validateScope() rolesArray " + rolesArray);
tokReqMsgCtx.setScope(rolesArray);
}
} catch (ParseException e) {
e.printStackTrace();
}
}
}catch (Exception e) {
e.printStackTrace();
}
return true;
}
@Override
public boolean issueRefreshToken() throws IdentityOAuth2Exception {
return false;
}
}
然后只需编辑 repository/conf/identity/identity.xml
以引用您的扩展授权处理程序:
<SupportedGrantType>
<GrantTypeName>urn:ietf:params:oauth:grant-type:jwt-bearer</GrantTypeName>
<!--<GrantTypeHandlerImplClass>org.wso2.carbon.identity.oauth2.grant.jwt.JWTBearerGrantHandler</GrantTypeHandlerImplClass>-->
<GrantTypeHandlerImplClass>xxx.JWTBearerGrantHandlerJWTAuthAware</GrantTypeHandlerImplClass>
<GrantTypeValidatorImplClass>org.wso2.carbon.identity.oauth2.grant.jwt.JWTGrantValidator</GrantTypeValidatorImplClass>
</SupportedGrantType>
这是我需要完成此集成的最后一块:
我有一个生成 JWT 令牌的外部身份提供者。这些令牌包含包含用户权限的声明 "auth",例如:
"auth" : [ "editor", "reviewer"]
.在 WSO2 中,我有一个 API,它的某些端点需要 "editor" 范围 :
- 我正在使用 JWT Grant 从外部 IP 交换 JWT 以获取 WSO2 访问令牌以调用 API。
我需要在 WSO2 创建访问令牌时将其与 JWT 的 "auth" 声明中包含的范围相关联。
这可能吗?有没有可以实现的扩展点?
这应该可以通过扩展 JWT 授权类型和覆盖 validateScope 方法来实现。您可以从 JWT 检索范围并将其设置为 tokReqMsgCtx。然后你应该能够像下面这样设置范围。
@Override
public boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) {
// Create scopes array
// String scopes[] = getScopesFromJWT();
tokReqMsgCtx.setScope(scopes);
return true;
}
例如,看看这是如何为 SAML2 承载授权类型 [1] 完成的。
如果您使用的是 JWT 授权类型,它是在 "repository/conf/identity/identity.xml" 文件的 SupportedGrantTypes 部分中配置的。配置中提到了相关的 GrantTypeHandlerImplClass。
<SupportedGrantType>
<GrantTypeName>urn:ietf:params:oauth:grant-type:jwt-bearer</GrantTypeName
<GrantTypeHandlerImplClass>org.wso2.carbon.identity.oauth2.grant.jwt.JWTBearerGrantHandler</GrantTypeHandlerImplClass>
....
</SupportedGrantType>
有关编写自定义授权类型的信息,请参阅文档[2]。
[2]https://docs.wso2.com/display/IS560/Writing+a+Custom+OAuth+2.0+Grant+Type
这就是我最终解决它的方法 JWTBearerGrantHandler
:
public class JWTBearerGrantHandlerJWTAuthAware extends JWTBearerGrantHandler {
private static final Log LOG = LogFactory.getLog(JWTBearerGrantHandlerJWTAuthAware.class);
@Override
public boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) throws IdentityOAuth2Exception {
LOG.debug("validateScope()");
try {
final RequestParameter[] requestParameters = tokReqMsgCtx.getOauth2AccessTokenReqDTO().getRequestParameters();
RequestParameter assertion = null;
for (RequestParameter rp : requestParameters) {
if (rp.getKey().equals("assertion")) {
assertion = rp;
}
}
if (assertion != null) {
final String jwtString = assertion.getValue()[0];
try {
final JWT jwt = JWTParser.parse(jwtString);
final Object auth = jwt.getJWTClaimsSet().getClaim("auth");
if (auth != null) {
final JSONArray roles = (JSONArray) ((Map) auth).get("roles");
final String[] rolesArray = roles.toArray(new String[0]);
LOG.debug("validateScope() rolesArray " + rolesArray);
tokReqMsgCtx.setScope(rolesArray);
}
} catch (ParseException e) {
e.printStackTrace();
}
}
}catch (Exception e) {
e.printStackTrace();
}
return true;
}
@Override
public boolean issueRefreshToken() throws IdentityOAuth2Exception {
return false;
}
}
然后只需编辑 repository/conf/identity/identity.xml
以引用您的扩展授权处理程序:
<SupportedGrantType>
<GrantTypeName>urn:ietf:params:oauth:grant-type:jwt-bearer</GrantTypeName>
<!--<GrantTypeHandlerImplClass>org.wso2.carbon.identity.oauth2.grant.jwt.JWTBearerGrantHandler</GrantTypeHandlerImplClass>-->
<GrantTypeHandlerImplClass>xxx.JWTBearerGrantHandlerJWTAuthAware</GrantTypeHandlerImplClass>
<GrantTypeValidatorImplClass>org.wso2.carbon.identity.oauth2.grant.jwt.JWTGrantValidator</GrantTypeValidatorImplClass>
</SupportedGrantType>