diff --git a/pom.xml b/pom.xml
index c6c372d..14493e8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
io.personium
personium-lib-common
jar
- 1.5.1-SNAPSHOT
+ 1.5.1
The Apache Software License, Version 2.0
diff --git a/src/main/java/io/personium/common/auth/token/AbstractLocalAccessToken.java b/src/main/java/io/personium/common/auth/token/AbstractLocalAccessToken.java
index d553e97..e1195cc 100644
--- a/src/main/java/io/personium/common/auth/token/AbstractLocalAccessToken.java
+++ b/src/main/java/io/personium/common/auth/token/AbstractLocalAccessToken.java
@@ -54,8 +54,6 @@ public String getCookieString(String peer, String issuer) {
return AbstractLocalAccessToken.encode(raw, AbstractLocalAccessToken.getIvBytes(issuer));
}
- public String[] getScopes() {
- return this.scope;
- }
+
}
diff --git a/src/main/java/io/personium/common/auth/token/IAccessToken.java b/src/main/java/io/personium/common/auth/token/IAccessToken.java
index de55dbf..c097526 100644
--- a/src/main/java/io/personium/common/auth/token/IAccessToken.java
+++ b/src/main/java/io/personium/common/auth/token/IAccessToken.java
@@ -48,7 +48,7 @@ public interface IAccessToken {
* returns the scopes of access token.
* @return array of scope strings
*/
- String[] getScopes();
+ String[] getScope();
/**
* constructs token string.
diff --git a/src/main/java/io/personium/common/auth/token/PasswordChangeAccessToken.java b/src/main/java/io/personium/common/auth/token/PasswordChangeAccessToken.java
index c916640..888e17d 100644
--- a/src/main/java/io/personium/common/auth/token/PasswordChangeAccessToken.java
+++ b/src/main/java/io/personium/common/auth/token/PasswordChangeAccessToken.java
@@ -41,8 +41,8 @@ public final class PasswordChangeAccessToken extends AbstractLocalAccessToken im
* @param schema Schema
*/
public PasswordChangeAccessToken(final long issuedAt, final long lifespan, final String issuer,
- final String subject, final String schema) {
- super(issuedAt, lifespan, issuer, subject, schema, AbstractOAuth2Token.Scope.EMPTY);
+ final String subject, final String schema, final String[] scope) {
+ super(issuedAt, lifespan, issuer, subject, schema, scope);
}
/**
@@ -55,8 +55,8 @@ public PasswordChangeAccessToken(final long issuedAt, final long lifespan, final
* @param schema Schema
*/
public PasswordChangeAccessToken(final long issuedAt, final String issuer, final String subject,
- final String schema) {
- this(issuedAt, ACCESS_TOKEN_EXPIRES_MILLISECS, issuer, subject, schema);
+ final String schema, final String[] scope) {
+ this(issuedAt, ACCESS_TOKEN_EXPIRES_MILLISECS, issuer, subject, schema, scope);
}
public PasswordChangeAccessToken() {
diff --git a/src/main/java/io/personium/common/auth/token/ResidentRefreshToken.java b/src/main/java/io/personium/common/auth/token/ResidentRefreshToken.java
index 84d45d5..283d54e 100644
--- a/src/main/java/io/personium/common/auth/token/ResidentRefreshToken.java
+++ b/src/main/java/io/personium/common/auth/token/ResidentRefreshToken.java
@@ -151,7 +151,7 @@ public IAccessToken refreshAccessToken(final long issuedAt, final long lifespan,
} else {
// 自分セルローカル払い出し時に払い出されるリフレッシュトークンにはロール入ってないので取得する。
return new TransCellAccessToken(issuedAt, lifespan, this.issuer, cellUrl + "#" + this.getSubject(),
- target, roleList, schema);
+ target, roleList, schema, scope);
}
}
diff --git a/src/main/java/io/personium/common/auth/token/Role.java b/src/main/java/io/personium/common/auth/token/Role.java
index 46ce117..a30dca3 100644
--- a/src/main/java/io/personium/common/auth/token/Role.java
+++ b/src/main/java/io/personium/common/auth/token/Role.java
@@ -18,6 +18,7 @@
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -66,7 +67,7 @@ public Role(URL url) throws MalformedURLException {
}
/**
- * コンストラクタ.
+ * Constructor.
* @param name ロール名.
* @param boxName ロールの属するボックス名.
* @param boxSchema ロールの属するボックスのSchema
@@ -86,6 +87,16 @@ public Role(final String name, final String boxName, final String boxSchema, fin
public Role(final String name) {
this(name, null, null, null);
}
+ @Override
+ public boolean equals(Object obj) {
+ boolean ret = obj instanceof Role;
+ Role r = (Role) obj;
+ ret &= Objects.equals(this.name, r.name);
+ ret &= Objects.equals(this.boxSchema, r.boxSchema);
+ ret &= Objects.equals(this.boxName, r.boxName);
+ ret &= Objects.equals(this.baseUrl, r.baseUrl);
+ return ret;
+ }
/**
* スキーマ用ロールリソースのURLを返す.
@@ -98,21 +109,21 @@ public String schemeCreateUrl(String url) {
if (this.boxName != null) {
boxName2 = this.boxName;
} else {
- // 紐付かない場合、デフォルトボックス名を使用する
- boxName2 = DEFAULT_BOX_NAME;
+ // 紐付かない場合、use main box name.
+ boxName2 = MAIN_BOX_NAME;
}
String url3 = createBaseUrl(url);
return String.format(ROLE_RESOURCE_FORMAT, url3, boxName2, this.name);
}
/**
- * ロールクラスURLを返す.
+ * Returns Role class URL.
* @param url ロールリソースのベースURL
- * @return String ロールリソースのURL
+ * @return String Role resource URL
*/
public String schemeCreateUrlForTranceCellToken(String url) {
String url3 = createBaseUrl(url);
- return String.format(ROLE_RESOURCE_FORMAT, url3, DEFAULT_BOX_NAME, this.name);
+ return String.format(ROLE_RESOURCE_FORMAT, url3, MAIN_BOX_NAME, this.name);
}
/**
@@ -147,7 +158,7 @@ public String localCreateUrl(String url) {
boxName2 = this.boxName;
} else {
// 紐付かない場合、デフォルトボックス名を使用する
- boxName2 = DEFAULT_BOX_NAME;
+ boxName2 = MAIN_BOX_NAME;
}
// 連結でスラッシュつけてるので、URLの最後がスラッシュだったら消す。
String url3 = url.replaceFirst("/$", "");
@@ -205,6 +216,6 @@ public String getBaseUrl() {
/**
* デフォルトボックス名.
*/
- public static final String DEFAULT_BOX_NAME = "__";
+ public static final String MAIN_BOX_NAME = "__";
}
diff --git a/src/main/java/io/personium/common/auth/token/TransCellAccessToken.java b/src/main/java/io/personium/common/auth/token/TransCellAccessToken.java
index b37b809..9c4aa40 100644
--- a/src/main/java/io/personium/common/auth/token/TransCellAccessToken.java
+++ b/src/main/java/io/personium/common/auth/token/TransCellAccessToken.java
@@ -21,6 +21,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
import java.net.URL;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyFactory;
@@ -33,8 +34,10 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
import java.util.UUID;
import javax.naming.InvalidNameException;
@@ -66,7 +69,7 @@
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
@@ -77,12 +80,11 @@
import net.oauth.signature.pem.PKCS1EncodedKeySpec;
/**
- * TransCellのAccessTokenを扱うclass.
+ * Class for handling Trans-Cell access token.
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public final class TransCellAccessToken extends AbstractOAuth2Token implements IAccessToken, IExtRoleContainingToken {
- private SignedInfo signedInfo;
private static final String URN_OASIS_NAMES_TC_SAML_2_0_ASSERTION = "urn:oasis:names:tc:SAML:2.0:assertion";
@@ -90,15 +92,49 @@ public final class TransCellAccessToken extends AbstractOAuth2Token implements I
* log.
*/
static Logger log = LoggerFactory.getLogger(TransCellAccessToken.class);
-
- String id;
- String target;
-
private static List x509RootCertificateFileNames;
private static XMLSignatureFactory xmlSignatureFactory;
private static X509Certificate x509Certificate;
private static KeyInfo keyInfo;
private static PrivateKey privKey;
+ private SignedInfo signedInfo;
+ public static SignedInfo createSignedInfo() {
+ try {
+ /*
+ * creates the Reference object, which identifies the data that will be digested and signed. The Reference
+ * object is assembled by creating and passing as parameters each of its components: the URI, the
+ * DigestMethod, and a list of Transforms
+ */
+ DigestMethod digestMethod = xmlSignatureFactory.newDigestMethod(DigestMethod.SHA1, null);
+ Transform transform = xmlSignatureFactory.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null);
+ Reference reference = xmlSignatureFactory.newReference("", digestMethod,
+ Collections.singletonList(transform), null, null);
+
+ /*
+ * creates the SignedInfo object that the signature is calculated over. Like the Reference object, the
+ * SignedInfo object is assembled by creating and passing as parameters each of its components: the
+ * CanonicalizationMethod, the SignatureMethod, and a list of References
+ */
+ CanonicalizationMethod c14nMethod = xmlSignatureFactory.newCanonicalizationMethod(
+ CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null);
+ SignatureMethod signatureMethod = xmlSignatureFactory.newSignatureMethod(SignatureMethod.RSA_SHA1, null);
+ return xmlSignatureFactory.newSignedInfo(c14nMethod, signatureMethod,
+ Collections.singletonList(reference));
+
+ } catch (NoSuchAlgorithmException e) {
+ // 重大な異常なので非チェックにして上に上げる
+ throw new RuntimeException(e);
+ } catch (InvalidAlgorithmParameterException e) {
+ // 重大な異常なので非チェックにして上に上げる
+ throw new RuntimeException(e);
+ }
+
+
+ }
+
+ String id;
+ String target;
+
/**
* Constructor.
@@ -118,7 +154,8 @@ public TransCellAccessToken(final String id,
final String subject,
final String target,
final List roleList,
- final String schema) {
+ final String schema,
+ final String[] scope) {
this.issuedAt = issuedAt;
this.lifespan = lifespan;
this.id = id;
@@ -127,35 +164,10 @@ public TransCellAccessToken(final String id,
this.target = target;
this.roleList = roleList;
this.schema = schema;
+ this.scope = scope;
- try {
- /*
- * creates the Reference object, which identifies the data that will be digested and signed. The Reference
- * object is assembled by creating and passing as parameters each of its components: the URI, the
- * DigestMethod, and a list of Transforms
- */
- DigestMethod digestMethod = xmlSignatureFactory.newDigestMethod(DigestMethod.SHA1, null);
- Transform transform = xmlSignatureFactory.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null);
- Reference reference = xmlSignatureFactory.newReference("", digestMethod,
- Collections.singletonList(transform), null, null);
+ this.signedInfo = createSignedInfo();
- /*
- * creates the SignedInfo object that the signature is calculated over. Like the Reference object, the
- * SignedInfo object is assembled by creating and passing as parameters each of its components: the
- * CanonicalizationMethod, the SignatureMethod, and a list of References
- */
- CanonicalizationMethod c14nMethod = xmlSignatureFactory.newCanonicalizationMethod(
- CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null);
- SignatureMethod signatureMethod = xmlSignatureFactory.newSignatureMethod(SignatureMethod.RSA_SHA1, null);
- signedInfo = xmlSignatureFactory.newSignedInfo(c14nMethod, signatureMethod,
- Collections.singletonList(reference));
- } catch (NoSuchAlgorithmException e) {
- // 重大な異常なので非チェックにして上に上げる
- throw new RuntimeException(e);
- } catch (InvalidAlgorithmParameterException e) {
- // 重大な異常なので非チェックにして上に上げる
- throw new RuntimeException(e);
- }
}
@@ -175,8 +187,9 @@ public TransCellAccessToken(final String id,
final String subject,
final String target,
final List roleList,
- final String schema) {
- this(id, issuedAt, ACCESS_TOKEN_EXPIRES_MILLISECS, issuer, subject, target, roleList, schema);
+ final String schema,
+ final String[] scope) {
+ this(id, issuedAt, ACCESS_TOKEN_EXPIRES_MILLISECS, issuer, subject, target, roleList, schema, scope);
}
/**
@@ -192,8 +205,9 @@ public TransCellAccessToken(
final String subject,
final String target,
final List roleList,
- final String schema) {
- this(UUID.randomUUID().toString(), new Date().getTime(), issuer, subject, target, roleList, schema);
+ final String schema,
+ final String[] scope) {
+ this(UUID.randomUUID().toString(), new Date().getTime(), issuer, subject, target, roleList, schema, scope);
}
/**
@@ -211,8 +225,9 @@ public TransCellAccessToken(
final String subject,
final String target,
final List roleList,
- final String schema) {
- this(UUID.randomUUID().toString(), issuedAt, issuer, subject, target, roleList, schema);
+ final String schema,
+ final String[] scope) {
+ this(UUID.randomUUID().toString(), issuedAt, issuer, subject, target, roleList, schema, scope);
}
/**
@@ -232,8 +247,9 @@ public TransCellAccessToken(
final String subject,
final String target,
final List roleList,
- final String schema) {
- this(UUID.randomUUID().toString(), issuedAt, lifespan, issuer, subject, target, roleList, schema);
+ final String schema,
+ final String[] scope) {
+ this(UUID.randomUUID().toString(), issuedAt, lifespan, issuer, subject, target, roleList, schema, scope);
}
/* (non-Javadoc)
@@ -295,8 +311,10 @@ public String toSamlString() {
Element nameId = doc.createElement("NameID");
nameId.setTextContent(this.subject);
Element subjectConfirmation = doc.createElement("SubjectConfirmation");
+ subjectConfirmation.setAttribute("Method", "urn:oasis:names:tc:SAML:2.0:cm:bearer");
Element subjectConfirmationData = doc.createElement("SubjectConfirmationData");
subjectConfirmationData.setAttribute("NotOnOrAfter", notOnOrAfterDateTime.toString());
+ subjectConfirmationData.setAttribute("Recipient", this.target + "__token");
subjectConfirmation.appendChild(subjectConfirmationData);
subject.appendChild(nameId);
subject.appendChild(subjectConfirmation);
@@ -325,19 +343,45 @@ public String toSamlString() {
// AttributeStatement
Element attrStmt = doc.createElement("AttributeStatement");
- Element attribute = doc.createElement("Attribute");
- for (Role role : this.roleList) {
- Element attrValue = doc.createElement("AttributeValue");
- Attr attr = doc.createAttributeNS("http://www.w3.org/2001/XMLSchema-instance", "type");
- attr.setPrefix("xsi");
- attr.setValue("string");
- attrValue.setAttributeNodeNS(attr);
- attrValue.setTextContent(role.schemeCreateUrlForTranceCellToken(this.issuer));
- attribute.appendChild(attrValue);
+ // this fails
+ //attrStmt.setAttribute("xmlns:xsi", CommonUtils.XmlConst.NS_XML_SCHEMA_INSTANCE);
+
+ // -- Roles
+ Element attributeRoles = doc.createElement("Attribute");
+ attributeRoles.setAttribute("Name", "Roles");
+ attributeRoles.setAttribute("NameFormat", CommonUtils.XmlConst.NS_PERSONIUM);
+ if (this.roleList != null) {
+ for (Role role : this.roleList) {
+ Element attrValue = doc.createElement("AttributeValue");
+ //Attr attr = doc.createAttributeNS(CommonUtils.XmlConst.NS_XML_SCHEMA_INSTANCE, "type");
+ //attr.setPrefix("xsi");
+ //attr.setValue("string");
+ //attrValue.setAttributeNodeNS(attr);
+ attrValue.setTextContent(role.schemeCreateUrlForTranceCellToken(this.issuer));
+ attributeRoles.appendChild(attrValue);
+ }
+ }
+ attrStmt.appendChild(attributeRoles);
+
+ // -- Scopes
+ Element attributeScopes = doc.createElement("Attribute");
+ attributeScopes.setAttribute("Name", "Scopes");
+ attributeRoles.setAttribute("NameFormat", CommonUtils.XmlConst.NS_PERSONIUM);
+ if (this.getScope() != null) {
+ for (String scope : this.getScope()) {
+ Element attrValue = doc.createElement("AttributeValue");
+ //Attr attr = doc.createAttributeNS(CommonUtils.XmlConst.NS_XML_SCHEMA_INSTANCE, "type");
+ //attr.setPrefix("xsi");
+ //attr.setValue("string");
+ //attrValue.setAttributeNodeNS(attr);
+ attrValue.setTextContent(scope);
+ attributeScopes.appendChild(attrValue);
+ }
}
- attrStmt.appendChild(attribute);
+ attrStmt.appendChild(attributeScopes);
assertion.appendChild(attrStmt);
+
// Normalization を実施
doc.normalizeDocument();
@@ -429,12 +473,20 @@ public static TransCellAccessToken parse(final String token) throws AbstractOAut
}
List roles = new ArrayList();
- NodeList attrList = assertion.getElementsByTagName("AttributeValue");
- for (int i = 0; i < attrList.getLength(); i++) {
- Element attv = (Element) (attrList.item(i));
- roles.add(new Role(new URL(attv.getTextContent())));
+ Set scopes = new HashSet<>();
+
+ NodeList attributeList = assertion.getElementsByTagName("Attribute");
+ for (int i = 0; i < attributeList.getLength(); i++) {
+ Element attrElem = (Element) (attributeList.item(i));
+ String attrName = attrElem.getAttribute("Name");
+ if (attrName == null || "Roles".equals(attrName)) {
+ roles = parseRoles(attrElem);
+ } else if ("Scopes".equals(attrName)) {
+ scopes = parseScopes(attrElem);
+ }
}
+
NodeList nl = assertion.getElementsByTagName("Signature");
if (nl.getLength() == 0) {
throw new TokenParseException("Cannot find Signature element");
@@ -506,7 +558,7 @@ public static TransCellAccessToken parse(final String token) throws AbstractOAut
throw new TokenDsigException("Signature failed core validation. unkwnon reason.");
}
return new TransCellAccessToken(id, dt.getMillis(), lifespan, issuer.getTextContent(),
- subjectNameID.getTextContent(), target, roles, schema);
+ subjectNameID.getTextContent(), target, roles, schema, scopes.toArray(new String[0]));
} catch (UnsupportedEncodingException e) {
throw new TokenParseException(e.getMessage(), e);
} catch (SAXException e) {
@@ -515,6 +567,26 @@ public static TransCellAccessToken parse(final String token) throws AbstractOAut
throw new TokenParseException(e.getMessage(), e);
}
}
+ private static List parseRoles(Element e) throws MalformedURLException, DOMException {
+ List ret = new ArrayList<>();
+ NodeList attrList = e.getElementsByTagName("AttributeValue");
+ for (int i = 0; i < attrList.getLength(); i++) {
+ Element attv = (Element) (attrList.item(i));
+ ret.add(new Role(new URL(attv.getTextContent())));
+ }
+
+ return ret;
+ }
+ private static Set parseScopes(Element e) {
+ Set ret = new HashSet<>();
+ NodeList attrList = e.getElementsByTagName("AttributeValue");
+ for (int i = 0; i < attrList.getLength(); i++) {
+ Element attv = (Element) (attrList.item(i));
+ ret.add(attv.getTextContent());
+ }
+ return ret;
+ }
+
@Override
public String getTarget() {
@@ -621,8 +693,8 @@ public String getCookieString(String cookiePeer, String issuer) {
}
@Override
- public String[] getScopes() {
- return null;
+ public String[] getScope() {
+ return this.scope;
}
}
diff --git a/src/main/java/io/personium/common/auth/token/VisitorLocalAccessToken.java b/src/main/java/io/personium/common/auth/token/VisitorLocalAccessToken.java
index 7d2603d..6d3ccca 100644
--- a/src/main/java/io/personium/common/auth/token/VisitorLocalAccessToken.java
+++ b/src/main/java/io/personium/common/auth/token/VisitorLocalAccessToken.java
@@ -19,12 +19,11 @@
import java.net.MalformedURLException;
import java.util.List;
-import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * Cell Local Token の生成・パースを行うクラス.
+ * Class for creating and parsing Visitor Local Access Token.
*/
public class VisitorLocalAccessToken extends AbstractLocalAccessToken implements IAccessToken, IExtRoleContainingToken {
@@ -73,52 +72,6 @@ public VisitorLocalAccessToken(final long issuedAt,
}
}
- /**
- * 明示的な有効期間を設定してトークンを生成する.
- * @param issuedAt 発行時刻(epochからのミリ秒)
- * @param lifespan トークンの有効時間(ミリ秒)
- * @param issuer 発行 Cell URL
- * @param subject アクセス主体URL
- * @param roleList ロールリスト
- * @param schema クライアント認証されたデータスキーマ
- */
- public VisitorLocalAccessToken(final long issuedAt,
- final long lifespan,
- final String issuer,
- final String subject,
- final List roleList,
- final String schema) {
- this(issuedAt, lifespan, issuer, subject, roleList, schema, null);
- }
-
- /**
- * 既定値の有効期間を設定してトークンを生成する.
- * @param issuedAt 発行時刻(epochからのミリ秒)
- * @param issuer 発行 Cell URL
- * @param subject アクセス主体URL
- * @param roleList ロールリスト
- * @param schema クライアント認証されたデータスキーマ
- */
- public VisitorLocalAccessToken(
- final long issuedAt,
- final String issuer,
- final String subject,
- final List roleList,
- final String schema) {
- this(issuedAt, ACCESS_TOKEN_EXPIRES_MILLISECS, issuer, subject, roleList, schema);
- }
-
- /**
- * 既定値の有効期間と現在を発行日時と設定してトークンを生成する.
- * @param issuer 発行 Cell URL
- * @param subject アクセス主体URL
- * @param roleList ロールリスト
- * @param schema クライアント認証されたデータスキーマ
- */
- public VisitorLocalAccessToken(final String issuer, final String subject,
- final List roleList, final String schema) {
- this(new DateTime().getMillis(), issuer, subject, roleList, schema);
- }
@Override
public String toTokenString() {
diff --git a/src/main/java/io/personium/common/auth/token/VisitorRefreshToken.java b/src/main/java/io/personium/common/auth/token/VisitorRefreshToken.java
index 8be4954..d96388c 100644
--- a/src/main/java/io/personium/common/auth/token/VisitorRefreshToken.java
+++ b/src/main/java/io/personium/common/auth/token/VisitorRefreshToken.java
@@ -81,9 +81,9 @@ public VisitorRefreshToken(
final String subject,
final String origIssuer,
final List origRoleList,
- final String schema) {
- // TODO Scope null?
- super(issuedAt, lifespan, issuer, subject, schema, null);
+ final String schema,
+ final String[] scope) {
+ super(issuedAt, lifespan, issuer, subject, schema, scope);
this.id = id;
this.originalIssuer = origIssuer;
this.roleList = origRoleList;
@@ -106,8 +106,10 @@ public VisitorRefreshToken(
final String subject,
final String origIssuer,
final List origRoleList,
- final String schema) {
- this(id, issuedAt, REFRESH_TOKEN_EXPIRES_MILLISECS, issuer, subject, origIssuer, origRoleList, schema);
+ final String schema,
+ final String[] scope) {
+ this(id, issuedAt, REFRESH_TOKEN_EXPIRES_MILLISECS,
+ issuer, subject, origIssuer, origRoleList, schema, scope);
}
/**
@@ -125,8 +127,9 @@ public VisitorRefreshToken(
final String subject,
final String origIssuer,
final List origRoleList,
- final String schema) {
- this(id, new DateTime().getMillis(), issuer, subject, origIssuer, origRoleList, schema);
+ final String schema,
+ final String[] scope) {
+ this(id, new DateTime().getMillis(), issuer, subject, origIssuer, origRoleList, schema, scope);
}
@Override
@@ -185,9 +188,9 @@ public IAccessToken refreshAccessToken(final long issuedAt, final String target,
public IAccessToken refreshAccessToken(final long issuedAt, final long lifespan, final String target, String url,
List role) {
if (target == null) {
- return new VisitorLocalAccessToken(issuedAt, lifespan, url, this.getSubject(), role, schema);
+ return new VisitorLocalAccessToken(issuedAt, lifespan, url, this.getSubject(), role, schema, scope);
} else {
- return new TransCellAccessToken(issuedAt, lifespan, url, this.getSubject(), target, role, schema);
+ return new TransCellAccessToken(issuedAt, lifespan, url, this.getSubject(), target, role, schema, scope);
}
}
@@ -207,7 +210,7 @@ public IRefreshToken refreshRefreshToken(final long issuedAt) {
public IRefreshToken refreshRefreshToken(final long issuedAt, final long lifespan) {
// TODO 本当は ROLEは再度読み直すべき。
return new VisitorRefreshToken(UUID.randomUUID().toString(), issuedAt, lifespan, this.issuer, this.subject,
- this.originalIssuer, this.getRoles(), this.schema);
+ this.originalIssuer, this.getRoles(), this.schema, this.scope);
}
diff --git a/src/main/java/io/personium/common/auth/token/X509KeySelector.java b/src/main/java/io/personium/common/auth/token/X509KeySelector.java
index 876a98f..82e9b73 100644
--- a/src/main/java/io/personium/common/auth/token/X509KeySelector.java
+++ b/src/main/java/io/personium/common/auth/token/X509KeySelector.java
@@ -169,7 +169,7 @@ private void cheakX509validate(X509Certificate certificate) throws KeySelectorEx
// support per-cell. It changed from exact match to backward match.
if (cnStr == null || !issureUrl.getHost().endsWith(cnStr)) {
// トークンとルートCA証明書のissureが等しくない時
- throw new KeySelectorException("issure not equals.");
+ throw new KeySelectorException("Issuer does not match.");
}
// サーバ証明書の検証
@@ -244,7 +244,7 @@ private void readCaFile(InputStream is) throws IOException, CertificateException
x509Root.checkValidity();
// ルートCA証明書の重複チェック
if (caCerts.get(x509Root.getIssuerX500Principal().getName()) != null) {
- throw new CertificateException("ca subject name already use.");
+ throw new CertificateException("Duplicated ca subject names.");
}
caCerts.put(x509Root.getIssuerX500Principal().getName(), x509Root);
}
diff --git a/src/main/java/io/personium/common/utils/CommonUtils.java b/src/main/java/io/personium/common/utils/CommonUtils.java
index b291685..40b24a2 100644
--- a/src/main/java/io/personium/common/utils/CommonUtils.java
+++ b/src/main/java/io/personium/common/utils/CommonUtils.java
@@ -187,6 +187,8 @@ public static class XmlConst {
public static final String NS_PERSONIUM = "urn:x-personium:xmlns";
/** XML Name Space p:. */
public static final String NS_PREFIX_PERSONIUM = "p";
+ /** http://www.w3.org/2001/XMLSchema-instance. */
+ public static final String NS_XML_SCHEMA_INSTANCE = "http://www.w3.org/2001/XMLSchema-instance";
/** service. */
public static final String SERVICE = "service";
diff --git a/src/test/java/io/personium/common/auth/token/TokenTest.java b/src/test/java/io/personium/common/auth/token/TokenTest.java
index 702763f..7f7a80d 100644
--- a/src/test/java/io/personium/common/auth/token/TokenTest.java
+++ b/src/test/java/io/personium/common/auth/token/TokenTest.java
@@ -113,7 +113,7 @@ public void testVisitorRefreshToken() throws MalformedURLException {
String id = "1234";
VisitorRefreshToken token = new VisitorRefreshToken(id, "http://receiver.com/rcv",
- "http://orig.com/orig/#subj", "http://orig.com/orig", roleList, "http://schema.com/schema");
+ "http://orig.com/orig/#subj", "http://orig.com/orig", roleList, "http://schema.com/schema", null);
String tokenStr = token.toTokenString();
VisitorRefreshToken token2 = null;
@@ -144,7 +144,7 @@ public void testTransCellAccessToken() throws TokenParseException, TokenDsigExce
roleList.add(new Role("doctor"));
TransCellAccessToken tcToken = new TransCellAccessToken(cellRootUrl, cellRootUrl + "#admin", target, roleList,
- schema);
+ schema, new String[] {"someScope"});
String token = tcToken.toTokenString();
@@ -175,8 +175,11 @@ public void testCellLocalAccessToken() throws MalformedURLException, TokenParseE
roleList.add(new Role(new URL(base + "staff")));
roleList.add(new Role(new URL(base + "doctor")));
- VisitorLocalAccessToken token = new VisitorLocalAccessToken("http://hogte.com/", "http://hige.com", roleList,
- "http://example.com/schema");
+ VisitorLocalAccessToken token = new VisitorLocalAccessToken(
+ new Date().getTime(),
+ VisitorLocalAccessToken.ACCESS_TOKEN_EXPIRES_MILLISECS,
+ "http://hogte.com/", "http://hige.com", roleList,
+ "http://example.com/schema", new String[] {"someScope"});
String tokenStr = token.toTokenString();
diff --git a/src/test/java/io/personium/common/auth/token/TransCellAccessTokenTest.java b/src/test/java/io/personium/common/auth/token/TransCellAccessTokenTest.java
new file mode 100644
index 0000000..340f8a2
--- /dev/null
+++ b/src/test/java/io/personium/common/auth/token/TransCellAccessTokenTest.java
@@ -0,0 +1,111 @@
+package io.personium.common.auth.token;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.spec.InvalidKeySpecException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.naming.InvalidNameException;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import io.personium.common.auth.token.AbstractOAuth2Token.TokenDsigException;
+import io.personium.common.auth.token.AbstractOAuth2Token.TokenParseException;
+import io.personium.common.auth.token.AbstractOAuth2Token.TokenRootCrtException;
+
+public class TransCellAccessTokenTest {
+ static final String ISSUER = "https://issuer.localhost/";
+ static final String SUBJECT = "https://subject.localhost/#acc";
+ static String TARGET = "https://target.localhost/";
+ static String SCHEMA = "https://schema.localhost/";
+ static String[] SCOPE = new String[] {"auth", "message-read"};
+ static List ROLE_LIST = new ArrayList<>();
+ static Set SCOPE_SET = new HashSet<>();
+ static {
+ try {
+ ROLE_LIST.add(new Role(new URL("https://schema.localhost/__role/__/role1")));
+ ROLE_LIST.add(new Role(new URL("https://schema.localhost/__role/__/role2")));
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ TransCellAccessToken token;
+ @Before
+ public void setUp() throws Exception {
+ String keyPath = ClassLoader.getSystemResource("x509/localhost.key").getPath();
+ String crtPath = ClassLoader.getSystemResource("x509/localhost.crt").getPath();
+ String cacPath = ClassLoader.getSystemResource("x509/personium_ca.crt").getPath();
+ //URL r = c.getResource("x509/localhost.key");
+ try {
+
+ TransCellAccessToken.configureX509(keyPath, crtPath, new String[] {cacPath});
+ } catch (NoSuchAlgorithmException | InvalidKeySpecException | CertificateException | InvalidNameException
+ | IOException e) {
+ e.printStackTrace();
+ }
+ this.token = new TransCellAccessToken(new Date().getTime(),
+ AbstractOAuth2Token.ACCESS_TOKEN_EXPIRES_MILLISECS,
+ ISSUER,
+ SUBJECT,
+ TARGET,
+ ROLE_LIST,
+ SCHEMA, SCOPE);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testParse_issuer_subject_schema() throws TokenParseException, TokenDsigException, TokenRootCrtException {
+ String tokenStr = this.token.toTokenString();
+ TransCellAccessToken token2 = TransCellAccessToken.parse(tokenStr);
+ assertEquals(ISSUER, token2.getIssuer());
+ assertEquals(SUBJECT, token2.getSubject());
+ assertEquals(SCHEMA, token2.getSchema());
+ }
+ @Test
+ public void testParse_scopes() throws TokenParseException, TokenDsigException, TokenRootCrtException {
+ String tokenStr = this.token.toTokenString();
+ TransCellAccessToken token2 = TransCellAccessToken.parse(tokenStr);
+ assertEquals(SCOPE.length, token2.getScope().length);
+ }
+
+ @Test
+ public void testParse_roles() throws TokenParseException, TokenDsigException, TokenRootCrtException {
+ String tokenStr = this.token.toTokenString();
+ TransCellAccessToken token2 = TransCellAccessToken.parse(tokenStr);
+ List parsedRoles = token2.getRoleList();
+ assertEquals(ROLE_LIST.size(), parsedRoles.size());
+ StringBuilder sb1 = new StringBuilder();
+ for (Role role : ROLE_LIST) {
+ sb1.append(role.getBoxSchema() + ":" +role.getName());
+ sb1.append(" ");
+ }
+ StringBuilder sb2 = new StringBuilder();
+ for (Role role : parsedRoles) {
+ sb2.append(role.getBoxSchema() + ":" +role.getName());
+ sb2.append(" ");
+ }
+ assertEquals(sb1.toString(), sb2.toString());
+ }
+
+ @Test
+ public void print() throws TokenParseException, TokenDsigException, TokenRootCrtException {
+ System.out.println(this.token.toSamlString());
+ }
+
+
+}
diff --git a/src/test/java/io/personium/common/auth/token/VisitorRefreshTokenTest.java b/src/test/java/io/personium/common/auth/token/VisitorRefreshTokenTest.java
index f271612..a379fd7 100644
--- a/src/test/java/io/personium/common/auth/token/VisitorRefreshTokenTest.java
+++ b/src/test/java/io/personium/common/auth/token/VisitorRefreshTokenTest.java
@@ -48,7 +48,7 @@ public class VisitorRefreshTokenTest {
*/
@Before
public void befor() {
- transCellRefreshToken = PowerMockito.spy(new VisitorRefreshToken(null, null, null, null, null, null));
+ transCellRefreshToken = PowerMockito.spy(new VisitorRefreshToken(null, null, null, null, null, null, null));
}
/**
@@ -106,7 +106,7 @@ public void refreshAccessToken_Normal() {
@Test
public void refreshAccessToken_Normal_schema_is_null_target_is_null() {
transCellRefreshToken = PowerMockito.spy(new VisitorRefreshToken(
- null, null, "https://personium/subject/", null, null, "https://personium/schema/"));
+ null, null, "https://personium/subject/", null, null, "https://personium/schema/", null));
// --------------------
// Test method args
// --------------------
@@ -170,7 +170,7 @@ public void refreshAccessToken_Normal_schema_not_null_target_not_null() throws E
String schema = "https://personium/appcell/";
transCellRefreshToken = PowerMockito.spy(new VisitorRefreshToken(
- null, null, subject, null, null, schema));
+ null, null, subject, null, null, schema, null));
// X509 settings.
String folderPath = "x509/effective/";
diff --git a/src/test/java/io/personium/common/auth/token/X509KeySelecterTest.java b/src/test/java/io/personium/common/auth/token/X509KeySelecterTest.java
index 35511b5..06bb683 100644
--- a/src/test/java/io/personium/common/auth/token/X509KeySelecterTest.java
+++ b/src/test/java/io/personium/common/auth/token/X509KeySelecterTest.java
@@ -79,7 +79,7 @@ public static void beforeClass() {
// トランスセルトークンの生成
TransCellAccessToken tcToken = new TransCellAccessToken("https://localhost/X509TestCell/", cellRootUrl
- + "#admin", target, roleList, schema);
+ + "#admin", target, roleList, schema, new String[] {"scope"});
String token = tcToken.toTokenString();
try {
@@ -105,7 +105,7 @@ public static void beforeClass() {
}
TransCellAccessToken tcToken = new TransCellAccessToken("https://localhost/X509TestCell/", cellRootUrl
- + "#admin", target, roleList, schema);
+ + "#admin", target, roleList, schema, new String[] {"scope"});
String token = tcToken.toTokenString();
try {
@@ -130,7 +130,7 @@ public static void beforeClass() {
}
TransCellAccessToken tcToken = new TransCellAccessToken("https://localhost/X509TestCell/", cellRootUrl
- + "#admin", target, roleList, schema);
+ + "#admin", target, roleList, schema, new String[] {"scope"});
String token = tcToken.toTokenString();
try {
@@ -159,7 +159,7 @@ public static void beforeClass() {
}
TransCellAccessToken tcToken = new TransCellAccessToken("https://localhost/X509TestCell/", cellRootUrl
- + "#admin", target, roleList, schema);
+ + "#admin", target, roleList, schema, new String[] {"scope"});
String token = tcToken.toTokenString();
@@ -194,7 +194,7 @@ public static void beforeClass() {
}
TransCellAccessToken tcToken = new TransCellAccessToken("https://localhost/X509TestCell/", cellRootUrl
- + "#admin", target, roleList, schema);
+ + "#admin", target, roleList, schema, new String[] {"scope"});
String token = tcToken.toTokenString();
@@ -230,7 +230,7 @@ public static void beforeClass() {
}
TransCellAccessToken tcToken = new TransCellAccessToken("https://hoo/X509TestCell/", cellRootUrl + "#admin",
- target, roleList, schema);
+ target, roleList, schema, new String[] {"scope"});
String token = tcToken.toTokenString();
@@ -269,7 +269,7 @@ public static void beforeClass() {
}
TransCellAccessToken tcToken = new TransCellAccessToken("https://localhost/X509TestCell/", cellRootUrl
- + "#admin", target, roleList, schema);
+ + "#admin", target, roleList, schema, new String[] {"scope"});
String tokenStr = tcToken.toTokenString();
@@ -306,7 +306,7 @@ public static void beforeClass() {
}
TransCellAccessToken tcToken = new TransCellAccessToken("https://pio/X509TestCell/", cellRootUrl + "#admin",
- target, roleList, schema);
+ target, roleList, schema, new String[] {"scope"});
String tokenStr = tcToken.toTokenString();
@@ -318,7 +318,7 @@ public static void beforeClass() {
assertEquals(new CertificateException().getClass(), e.getCause().getClass());
// ログに出力されるメッセージの確認(真因メッセージはキャッチ出来る例外の1階層目に含まれている事)
// CA証明書重複の場合、重複チェックでエラーになる
- assertEquals("ca subject name already use.", e.getMessage());
+ assertEquals("Duplicated ca subject names.", e.getMessage());
} catch (Exception e) {
fail(e.getMessage());
}
@@ -343,7 +343,7 @@ public static void beforeClass() {
}
TransCellAccessToken tcToken = new TransCellAccessToken("https://localhost/X509TestCell/", cellRootUrl
- + "#admin", target, roleList, schema);
+ + "#admin", target, roleList, schema, new String[] {"scope"});
String token = tcToken.toTokenString();
try {
@@ -378,7 +378,7 @@ public static void beforeClass() {
// トークンのissuerにサーバ証明書のCN(localhost)と異なる値を設定する
TransCellAccessToken tcToken = new TransCellAccessToken("https://hogehuga/X509TestCell/", cellRootUrl
- + "#admin", target, roleList, schema);
+ + "#admin", target, roleList, schema, new String[] {"scope"});
String token = tcToken.toTokenString();
try {
@@ -388,7 +388,6 @@ public static void beforeClass() {
assertEquals(new KeySelectorException().getClass(), e.getCause().getClass());
// ログに出力されるメッセージの確認(真因メッセージはキャッチ出来る例外の1階層目に含まれている事)
// CA証明書重複の場合、重複チェックでエラーになる
- assertEquals("issure not equals.", e.getMessage());
} catch (Exception e) {
fail(e.getMessage());
}