WSO2 自包含 AccessToken 声明配置——"sub" 字段
WSO2 Self contained AccessToken claims configuration -- the "sub" field
我正在 WSO2IS 上工作,并且已经能够通过 Oauth2 "password" 授权类型从 WSO2IS 中获得一个独立的访问令牌,方法是遵循 this post
我还可以在应用程序中验证令牌的签名 ()
还有最后一步过不去
这是我从 WSO2IS 中得到的访问令牌示例
{iss=https://localhost:9443/oauth2/token, sub=wjz@carbon.super, aud=[J3lbMMMJFwXB6neKzXv030S9lfga], exp=1488710173, iat=1488706573, azp=J3lbMMMJFwXB6neKzXv030S9lfga}
可以看到"sub"的值为用户名,对应声明“http://wso2.org/claims/username”。
我想更改 WSO2IS 中的配置,以便 "sub" 对应于声明“http://wso2.org/claims/userid”
我把"Service Providers"下的"Claim Configuration"改了;
我还在"Claims"下的“http://wso2.org/oidc/claim”里改了"sub"。但无法取得任何成功。
有什么我遗漏的吗?
请指教
谢谢
我终于通过编码而不是配置解决了这个问题。
我通过遵循此 post 实现了自包含访问令牌(Oauth2 中的 JWT)生成器的扩展。我构建了 jar,并在 /repository/components/lib/
下上传了 jar
我刚刚检查了这个 repo ,并进行了以下更改
/**
* For a locally authenticated user, subject identifier is supposed to be as below.
* <userstore_domain>/<username>@<tenant_domain>.
*
* yet somehow, what I got is <username>@<tenant_domain>
* @param SubjectId
* @return
* @throws IdentityOAuth2Exception
*/
private static SubjectTriple parseSubjectId(String subjectId) throws IdentityOAuth2Exception{
if (StringUtils.isBlank(subjectId)){
throw new IdentityOAuth2Exception("invalid subject identifier");
}
/*
* domain may not present
*/
String sid = null;
SubjectTriple st = new SubjectTriple();
if(StringUtils.contains(subjectId, '/')){
st.domain = StringUtils.substringBeforeLast(subjectId, "/");
sid = StringUtils.substringAfterLast(subjectId, "/");
}else{
sid = subjectId;
}
st.username = StringUtils.substringBeforeLast(sid, "@");
st.profile = StringUtils.substringAfterLast(sid, "@");
return st;
}
/**
* To build id token from OauthToken request message context
*
* @param request Token request message context
* @return Signed jwt string.
* @throws IdentityOAuth2Exception
*/
protected String buildIDToken(OAuthTokenReqMessageContext request)
throws IdentityOAuth2Exception {
String issuer = OAuth2Util.getIDTokenIssuer();
long lifetimeInMillis = OAuthServerConfiguration.getInstance().
getApplicationAccessTokenValidityPeriodInSeconds() * 1000;
long curTimeInMillis = Calendar.getInstance().getTimeInMillis();
SubjectTriple triple = parseSubjectId(request.getAuthorizedUser().getAuthenticatedSubjectIdentifier());
String userId = null;
try {
userId = CarbonContext.getThreadLocalCarbonContext().getUserRealm().getUserStoreManager()
.getUserClaimValue(triple.username, Constants.LOCAL_CLAIM__UserID, triple.profile);
} catch (UserStoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String clientId = request.getOauth2AccessTokenReqDTO().getClientId();
// Set claims to jwt token.
JWTClaimsSet jwtClaimsSet = new JWTClaimsSet();
jwtClaimsSet.setIssuer(issuer);
jwtClaimsSet.setSubject(userId);
jwtClaimsSet.setAudience(Arrays.asList(clientId));
jwtClaimsSet.setClaim(Constants.AUTHORIZATION_PARTY, clientId);
jwtClaimsSet.setExpirationTime(new Date(curTimeInMillis + lifetimeInMillis));
jwtClaimsSet.setIssueTime(new Date(curTimeInMillis));
if (JWSAlgorithm.NONE.getName().equals(signatureAlgorithm.getName())) {
return new PlainJWT(jwtClaimsSet).serialize();
}
return signJWT(jwtClaimsSet, request);
}
/**
* Build a signed jwt token from authorization request message context
*
* @param request Oauth authorization message context
* @return Signed jwt string
* @throws IdentityOAuth2Exception
*/
protected String buildIDToken(OAuthAuthzReqMessageContext request)
throws IdentityOAuth2Exception {
String issuer = OAuth2Util.getIDTokenIssuer();
long lifetimeInMillis = OAuthServerConfiguration.getInstance().
getApplicationAccessTokenValidityPeriodInSeconds() * 1000;
long curTimeInMillis = Calendar.getInstance().getTimeInMillis();
OAuth2AuthorizeReqDTO dto = request.getAuthorizationReqDTO();
SubjectTriple triple = parseSubjectId(dto.getUser().getAuthenticatedSubjectIdentifier());
String userId = null;
try {
userId = CarbonContext.getThreadLocalCarbonContext().getUserRealm().getUserStoreManager()
.getUserClaimValue(triple.username, Constants.LOCAL_CLAIM__UserID, triple.profile);
} catch (UserStoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String consumerKey = dto.getConsumerKey();
JWTClaimsSet jwtClaimsSet = new JWTClaimsSet();
jwtClaimsSet.setIssuer(issuer);
jwtClaimsSet.setSubject(userId);
jwtClaimsSet.setAudience(Arrays.asList(consumerKey));
jwtClaimsSet.setClaim(Constants.AUTHORIZATION_PARTY,consumerKey);
jwtClaimsSet.setExpirationTime(new Date(curTimeInMillis + lifetimeInMillis));
jwtClaimsSet.setIssueTime(new Date(curTimeInMillis));
if (JWSAlgorithm.NONE.getName().equals(signatureAlgorithm.getName())) {
return new PlainJWT(jwtClaimsSet).serialize();
}
return signJWT(jwtClaimsSet, request);
}
进口
import com.nimbusds.jose.Algorithm;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSSigner;
import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.PlainJWT;
import com.nimbusds.jwt.SignedJWT;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.core.util.KeyStoreManager;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
import org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration;
import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception;
import org.wso2.carbon.identity.oauth2.authz.OAuthAuthzReqMessageContext;
import org.wso2.carbon.identity.oauth2.dto.OAuth2AuthorizeReqDTO;
import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext;
import org.wso2.carbon.identity.oauth2.token.OauthTokenIssuerImpl;
import org.wso2.carbon.identity.oauth2.util.OAuth2Util;
import org.wso2.carbon.user.api.UserStoreException;
import java.security.Key;
import java.security.interfaces.RSAPrivateKey;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
我正在 WSO2IS 上工作,并且已经能够通过 Oauth2 "password" 授权类型从 WSO2IS 中获得一个独立的访问令牌,方法是遵循 this post
我还可以在应用程序中验证令牌的签名 (
还有最后一步过不去
这是我从 WSO2IS 中得到的访问令牌示例
{iss=https://localhost:9443/oauth2/token, sub=wjz@carbon.super, aud=[J3lbMMMJFwXB6neKzXv030S9lfga], exp=1488710173, iat=1488706573, azp=J3lbMMMJFwXB6neKzXv030S9lfga}
可以看到"sub"的值为用户名,对应声明“http://wso2.org/claims/username”。
我想更改 WSO2IS 中的配置,以便 "sub" 对应于声明“http://wso2.org/claims/userid”
我把"Service Providers"下的"Claim Configuration"改了; 我还在"Claims"下的“http://wso2.org/oidc/claim”里改了"sub"。但无法取得任何成功。
有什么我遗漏的吗?
请指教
谢谢
我终于通过编码而不是配置解决了这个问题。
我通过遵循此 post 实现了自包含访问令牌(Oauth2 中的 JWT)生成器的扩展。我构建了 jar,并在 /repository/components/lib/
下上传了 jar我刚刚检查了这个 repo ,并进行了以下更改
/**
* For a locally authenticated user, subject identifier is supposed to be as below.
* <userstore_domain>/<username>@<tenant_domain>.
*
* yet somehow, what I got is <username>@<tenant_domain>
* @param SubjectId
* @return
* @throws IdentityOAuth2Exception
*/
private static SubjectTriple parseSubjectId(String subjectId) throws IdentityOAuth2Exception{
if (StringUtils.isBlank(subjectId)){
throw new IdentityOAuth2Exception("invalid subject identifier");
}
/*
* domain may not present
*/
String sid = null;
SubjectTriple st = new SubjectTriple();
if(StringUtils.contains(subjectId, '/')){
st.domain = StringUtils.substringBeforeLast(subjectId, "/");
sid = StringUtils.substringAfterLast(subjectId, "/");
}else{
sid = subjectId;
}
st.username = StringUtils.substringBeforeLast(sid, "@");
st.profile = StringUtils.substringAfterLast(sid, "@");
return st;
}
/**
* To build id token from OauthToken request message context
*
* @param request Token request message context
* @return Signed jwt string.
* @throws IdentityOAuth2Exception
*/
protected String buildIDToken(OAuthTokenReqMessageContext request)
throws IdentityOAuth2Exception {
String issuer = OAuth2Util.getIDTokenIssuer();
long lifetimeInMillis = OAuthServerConfiguration.getInstance().
getApplicationAccessTokenValidityPeriodInSeconds() * 1000;
long curTimeInMillis = Calendar.getInstance().getTimeInMillis();
SubjectTriple triple = parseSubjectId(request.getAuthorizedUser().getAuthenticatedSubjectIdentifier());
String userId = null;
try {
userId = CarbonContext.getThreadLocalCarbonContext().getUserRealm().getUserStoreManager()
.getUserClaimValue(triple.username, Constants.LOCAL_CLAIM__UserID, triple.profile);
} catch (UserStoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String clientId = request.getOauth2AccessTokenReqDTO().getClientId();
// Set claims to jwt token.
JWTClaimsSet jwtClaimsSet = new JWTClaimsSet();
jwtClaimsSet.setIssuer(issuer);
jwtClaimsSet.setSubject(userId);
jwtClaimsSet.setAudience(Arrays.asList(clientId));
jwtClaimsSet.setClaim(Constants.AUTHORIZATION_PARTY, clientId);
jwtClaimsSet.setExpirationTime(new Date(curTimeInMillis + lifetimeInMillis));
jwtClaimsSet.setIssueTime(new Date(curTimeInMillis));
if (JWSAlgorithm.NONE.getName().equals(signatureAlgorithm.getName())) {
return new PlainJWT(jwtClaimsSet).serialize();
}
return signJWT(jwtClaimsSet, request);
}
/**
* Build a signed jwt token from authorization request message context
*
* @param request Oauth authorization message context
* @return Signed jwt string
* @throws IdentityOAuth2Exception
*/
protected String buildIDToken(OAuthAuthzReqMessageContext request)
throws IdentityOAuth2Exception {
String issuer = OAuth2Util.getIDTokenIssuer();
long lifetimeInMillis = OAuthServerConfiguration.getInstance().
getApplicationAccessTokenValidityPeriodInSeconds() * 1000;
long curTimeInMillis = Calendar.getInstance().getTimeInMillis();
OAuth2AuthorizeReqDTO dto = request.getAuthorizationReqDTO();
SubjectTriple triple = parseSubjectId(dto.getUser().getAuthenticatedSubjectIdentifier());
String userId = null;
try {
userId = CarbonContext.getThreadLocalCarbonContext().getUserRealm().getUserStoreManager()
.getUserClaimValue(triple.username, Constants.LOCAL_CLAIM__UserID, triple.profile);
} catch (UserStoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String consumerKey = dto.getConsumerKey();
JWTClaimsSet jwtClaimsSet = new JWTClaimsSet();
jwtClaimsSet.setIssuer(issuer);
jwtClaimsSet.setSubject(userId);
jwtClaimsSet.setAudience(Arrays.asList(consumerKey));
jwtClaimsSet.setClaim(Constants.AUTHORIZATION_PARTY,consumerKey);
jwtClaimsSet.setExpirationTime(new Date(curTimeInMillis + lifetimeInMillis));
jwtClaimsSet.setIssueTime(new Date(curTimeInMillis));
if (JWSAlgorithm.NONE.getName().equals(signatureAlgorithm.getName())) {
return new PlainJWT(jwtClaimsSet).serialize();
}
return signJWT(jwtClaimsSet, request);
}
进口
import com.nimbusds.jose.Algorithm;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSSigner;
import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.PlainJWT;
import com.nimbusds.jwt.SignedJWT;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.core.util.KeyStoreManager;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
import org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration;
import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception;
import org.wso2.carbon.identity.oauth2.authz.OAuthAuthzReqMessageContext;
import org.wso2.carbon.identity.oauth2.dto.OAuth2AuthorizeReqDTO;
import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext;
import org.wso2.carbon.identity.oauth2.token.OauthTokenIssuerImpl;
import org.wso2.carbon.identity.oauth2.util.OAuth2Util;
import org.wso2.carbon.user.api.UserStoreException;
import java.security.Key;
import java.security.interfaces.RSAPrivateKey;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;