Skip to content

Commit

Permalink
Release 1.1.0
Browse files Browse the repository at this point in the history
Changed behaviours:

- `AssertionExtensionInputsBuilder.appid(Optional<AppId>)` now fails
  fast if the argument is `null`
- `ClientAssertionExtensionOutputsBuilder.appid(Optional<Boolean>)` now
  fails fast if the argument is `null`

New features:

- Public API methods that take `Optional` parameters now come with
  `Optional`-less aliases.
  • Loading branch information
emlun committed Mar 25, 2019
2 parents 8aaf483 + aad92ec commit 9de35cf
Show file tree
Hide file tree
Showing 35 changed files with 978 additions and 59 deletions.
16 changes: 16 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
== Version 1.1.0 ==

Changed behaviours:

* `AssertionExtensionInputsBuilder.appid(Optional<AppId>)` now fails fast if the
argument is `null`
* `ClientAssertionExtensionOutputsBuilder.appid(Optional<Boolean>)` now fails
fast if the argument is `null`


New features:

* Public API methods that take `Optional` parameters now come with
`Optional`-less aliases.


== Version 1.0.1 ==

Bugfixes:
Expand Down
4 changes: 2 additions & 2 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ Maven:
<dependency>
<groupId>com.yubico</groupId>
<artifactId>webauthn-server-core</artifactId>
<version>1.0.0</version>
<version>1.1.0</version>
<scope>compile</scope>
</dependency>
----------

Gradle:

----------
compile 'com.yubico:webauthn-server-core:1.0.0'
compile 'com.yubico:webauthn-server-core:1.1.0'
----------


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ public class AssertionRequest {
* </p>
*/
@NonNull
@Builder.Default
private final Optional<String> username = Optional.empty();
private final Optional<String> username;

@JsonCreator
private AssertionRequest(
Expand All @@ -75,6 +74,8 @@ public static AssertionRequestBuilder.MandatoryStages builder() {
}

public static class AssertionRequestBuilder {
private Optional<String> username = Optional.empty();

public static class MandatoryStages {
private final AssertionRequestBuilder builder = new AssertionRequestBuilder();

Expand All @@ -86,6 +87,31 @@ public AssertionRequestBuilder publicKeyCredentialRequestOptions(PublicKeyCreden
return builder.publicKeyCredentialRequestOptions(publicKeyCredentialRequestOptions);
}
}

/**
* The username of the user to authenticate, if the user has already been identified.
* <p>
* If this is absent, this indicates that this is a request for an assertion by a <a
* href="https://www.w3.org/TR/2019/PR-webauthn-20190117/#client-side-resident-public-key-credential-source">client-side-resident
* credential</a>, and identification of the user has been deferred until the response is received.
* </p>
*/
public AssertionRequestBuilder username(@NonNull Optional<String> username) {
this.username = username;
return this;
}

/**
* The username of the user to authenticate, if the user has already been identified.
* <p>
* If this is absent, this indicates that this is a request for an assertion by a <a
* href="https://www.w3.org/TR/2019/PR-webauthn-20190117/#client-side-resident-public-key-credential-source">client-side-resident
* credential</a>, and identification of the user has been deferred until the response is received.
* </p>
*/
public AssertionRequestBuilder username(@NonNull String username) {
return this.username(Optional.of(username));
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,15 @@ public class FinishAssertionOptions {
* @see <a href="https://tools.ietf.org/html/rfc8471">The Token Binding Protocol Version 1.0</a>
*/
@NonNull
@Builder.Default
private final Optional<ByteArray> callerTokenBindingId = Optional.empty();
private final Optional<ByteArray> callerTokenBindingId;

public static FinishAssertionOptionsBuilder.MandatoryStages builder() {
return new FinishAssertionOptionsBuilder.MandatoryStages();
}

public static class FinishAssertionOptionsBuilder {
private Optional<ByteArray> callerTokenBindingId = Optional.empty();

public static class MandatoryStages {
private final FinishAssertionOptionsBuilder builder = new FinishAssertionOptionsBuilder();

Expand All @@ -83,6 +84,27 @@ public FinishAssertionOptionsBuilder response(PublicKeyCredential<AuthenticatorA
}
}
}

/**
* The <a href="https://tools.ietf.org/html/rfc8471#section-3.2">token binding ID</a> of the connection to the
* client, if any.
*
* @see <a href="https://tools.ietf.org/html/rfc8471">The Token Binding Protocol Version 1.0</a>
*/
public FinishAssertionOptionsBuilder callerTokenBindingId(@NonNull Optional<ByteArray> callerTokenBindingId) {
this.callerTokenBindingId = callerTokenBindingId;
return this;
}

/**
* The <a href="https://tools.ietf.org/html/rfc8471#section-3.2">token binding ID</a> of the connection to the
* client, if any.
*
* @see <a href="https://tools.ietf.org/html/rfc8471">The Token Binding Protocol Version 1.0</a>
*/
public FinishAssertionOptionsBuilder callerTokenBindingId(@NonNull ByteArray callerTokenBindingId) {
return this.callerTokenBindingId(Optional.of(callerTokenBindingId));
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,15 @@ public class FinishRegistrationOptions {
* @see <a href="https://tools.ietf.org/html/rfc8471">The Token Binding Protocol Version 1.0</a>
*/
@NonNull
@Builder.Default
private final Optional<ByteArray> callerTokenBindingId = Optional.empty();
private final Optional<ByteArray> callerTokenBindingId;

public static FinishRegistrationOptionsBuilder.MandatoryStages builder() {
return new FinishRegistrationOptionsBuilder.MandatoryStages();
}

public static class FinishRegistrationOptionsBuilder {
private Optional<ByteArray> callerTokenBindingId = Optional.empty();

public static class MandatoryStages {
private final FinishRegistrationOptionsBuilder builder = new FinishRegistrationOptionsBuilder();

Expand All @@ -84,5 +85,26 @@ public FinishRegistrationOptionsBuilder response(PublicKeyCredential<Authenticat
}
}
}

/**
* The <a href="https://tools.ietf.org/html/rfc8471#section-3.2">token binding ID</a> of the connection to the
* client, if any.
*
* @see <a href="https://tools.ietf.org/html/rfc8471">The Token Binding Protocol Version 1.0</a>
*/
public FinishRegistrationOptionsBuilder callerTokenBindingId(@NonNull Optional<ByteArray> callerTokenBindingId) {
this.callerTokenBindingId = callerTokenBindingId;
return this;
}

/**
* The <a href="https://tools.ietf.org/html/rfc8471#section-3.2">token binding ID</a> of the connection to the
* client, if any.
*
* @see <a href="https://tools.ietf.org/html/rfc8471">The Token Binding Protocol Version 1.0</a>
*/
public FinishRegistrationOptionsBuilder callerTokenBindingId(@NonNull ByteArray callerTokenBindingId) {
return this.callerTokenBindingId(Optional.of(callerTokenBindingId));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,8 @@ public class RelyingParty {
* @see <a href="https://www.w3.org/TR/2019/PR-webauthn-20190117/#sctn-appid-extension">§10.1. FIDO AppID Extension
* (appid)</a>
*/
@Builder.Default
@NonNull
private final Optional<AppId> appId = Optional.empty();
private final Optional<AppId> appId;

/**
* The argument for the {@link PublicKeyCredentialCreationOptions#getAttestation() attestation} parameter in
Expand All @@ -165,9 +164,8 @@ public class RelyingParty {
* @see PublicKeyCredentialCreationOptions#getAttestation()
* @see <a href="https://www.w3.org/TR/2019/PR-webauthn-20190117/#sctn-attestation">§6.4. Attestation</a>
*/
@Builder.Default
@NonNull
private final Optional<AttestationConveyancePreference> attestationConveyancePreference = Optional.empty();
private final Optional<AttestationConveyancePreference> attestationConveyancePreference;

/**
* A {@link MetadataService} instance to use for looking up device attestation metadata. This matters only if {@link
Expand All @@ -180,9 +178,8 @@ public class RelyingParty {
* @see PublicKeyCredentialCreationOptions#getAttestation()
* @see <a href="https://www.w3.org/TR/2019/PR-webauthn-20190117/#sctn-attestation">§6.4. Attestation</a>
*/
@Builder.Default
@NonNull
private final Optional<MetadataService> metadataService = Optional.empty();
private final Optional<MetadataService> metadataService;

/**
* The argument for the {@link PublicKeyCredentialCreationOptions#getPubKeyCredParams() pubKeyCredParams} parameter
Expand Down Expand Up @@ -291,7 +288,7 @@ public PublicKeyCredentialCreationOptions startRegistration(StartRegistrationOpt
.challenge(generateChallenge())
.pubKeyCredParams(preferredPubkeyParams)
.excludeCredentials(
Optional.of(credentialRepository.getCredentialIdsForUsername(startRegistrationOptions.getUser().getName()))
credentialRepository.getCredentialIdsForUsername(startRegistrationOptions.getUser().getName())
)
.authenticatorSelection(startRegistrationOptions.getAuthenticatorSelection())
.extensions(startRegistrationOptions.getExtensions())
Expand Down Expand Up @@ -336,7 +333,7 @@ FinishRegistrationSteps _finishRegistration(
public AssertionRequest startAssertion(StartAssertionOptions startAssertionOptions) {
PublicKeyCredentialRequestOptionsBuilder pkcro = PublicKeyCredentialRequestOptions.builder()
.challenge(generateChallenge())
.rpId(Optional.of(identity.getId()))
.rpId(identity.getId())
.allowCredentials(
startAssertionOptions.getUsername().map(un ->
new ArrayList<>(credentialRepository.getCredentialIdsForUsername(un)))
Expand Down Expand Up @@ -404,6 +401,10 @@ public static RelyingPartyBuilder.MandatoryStages builder() {
}

public static class RelyingPartyBuilder {
private @NonNull Optional<AppId> appId = Optional.empty();
private @NonNull Optional<AttestationConveyancePreference> attestationConveyancePreference = Optional.empty();
private @NonNull Optional<MetadataService> metadataService = Optional.empty();

public static class MandatoryStages {
private final RelyingPartyBuilder builder = new RelyingPartyBuilder();

Expand All @@ -429,5 +430,120 @@ public RelyingPartyBuilder credentialRepository(CredentialRepository credentialR
}
}
}

/**
* The extension input to set for the <code>appid</code> extension when initiating authentication operations.
*
* <p>
* If this member is set, {@link #startAssertion(StartAssertionOptions) startAssertion} will automatically set the
* <code>appid</code> extension input, and {@link #finishAssertion(FinishAssertionOptions) finishAssertion} will
* adjust its verification logic to also accept this AppID as an alternative to the RP ID.
* </p>
*
* <p>
* By default, this is not set.
* </p>
*
* @see AssertionExtensionInputs#getAppid()
* @see <a href="https://www.w3.org/TR/2019/PR-webauthn-20190117/#sctn-appid-extension">§10.1. FIDO AppID Extension
* (appid)</a>
*/
public RelyingPartyBuilder appId(@NonNull Optional<AppId> appId) {
this.appId = appId;
return this;
}

/**
* The extension input to set for the <code>appid</code> extension when initiating authentication operations.
*
* <p>
* If this member is set, {@link #startAssertion(StartAssertionOptions) startAssertion} will automatically set the
* <code>appid</code> extension input, and {@link #finishAssertion(FinishAssertionOptions) finishAssertion} will
* adjust its verification logic to also accept this AppID as an alternative to the RP ID.
* </p>
*
* <p>
* By default, this is not set.
* </p>
*
* @see AssertionExtensionInputs#getAppid()
* @see <a href="https://www.w3.org/TR/2019/PR-webauthn-20190117/#sctn-appid-extension">§10.1. FIDO AppID Extension
* (appid)</a>
*/
public RelyingPartyBuilder appId(@NonNull AppId appId) {
return this.appId(Optional.of(appId));
}

/**
* The argument for the {@link PublicKeyCredentialCreationOptions#getAttestation() attestation} parameter in
* registration operations.
*
* <p>
* Unless your application has a concrete policy for authenticator attestation, it is recommended to leave this
* parameter undefined.
* </p>
*
* <p>
* By default, this is not set.
* </p>
*
* @see PublicKeyCredentialCreationOptions#getAttestation()
* @see <a href="https://www.w3.org/TR/2019/PR-webauthn-20190117/#sctn-attestation">§6.4. Attestation</a>
*/
public RelyingPartyBuilder attestationConveyancePreference(@NonNull Optional<AttestationConveyancePreference> attestationConveyancePreference) {
this.attestationConveyancePreference = attestationConveyancePreference;
return this;
}

/**
* The argument for the {@link PublicKeyCredentialCreationOptions#getAttestation() attestation} parameter in
* registration operations.
*
* <p>
* Unless your application has a concrete policy for authenticator attestation, it is recommended to leave this
* parameter undefined.
* </p>
*
* <p>
* By default, this is not set.
* </p>
*
* @see PublicKeyCredentialCreationOptions#getAttestation()
* @see <a href="https://www.w3.org/TR/2019/PR-webauthn-20190117/#sctn-attestation">§6.4. Attestation</a>
*/
public RelyingPartyBuilder attestationConveyancePreference(@NonNull AttestationConveyancePreference attestationConveyancePreference) {
return this.attestationConveyancePreference(Optional.of(attestationConveyancePreference));
}

/**
* A {@link MetadataService} instance to use for looking up device attestation metadata. This matters only if {@link
* #getAttestationConveyancePreference()} is non-empty and not set to {@link AttestationConveyancePreference#NONE}.
*
* <p>
* By default, this is not set.
* </p>
*
* @see PublicKeyCredentialCreationOptions#getAttestation()
* @see <a href="https://www.w3.org/TR/2019/PR-webauthn-20190117/#sctn-attestation">§6.4. Attestation</a>
*/
public RelyingPartyBuilder metadataService(@NonNull Optional<MetadataService> metadataService) {
this.metadataService = metadataService;
return this;
}

/**
* A {@link MetadataService} instance to use for looking up device attestation metadata. This matters only if {@link
* #getAttestationConveyancePreference()} is non-empty and not set to {@link AttestationConveyancePreference#NONE}.
*
* <p>
* By default, this is not set.
* </p>
*
* @see PublicKeyCredentialCreationOptions#getAttestation()
* @see <a href="https://www.w3.org/TR/2019/PR-webauthn-20190117/#sctn-attestation">§6.4. Attestation</a>
*/
public RelyingPartyBuilder metadataService(@NonNull MetadataService metadataService) {
return this.metadataService(Optional.of(metadataService));
}
}
}
Loading

0 comments on commit 9de35cf

Please sign in to comment.