use of com.nimbusds.oauth2.sdk.pkce.CodeChallengeMethod in project OpenConext-oidcng by OpenConext.
the class AuthorizationEndpoint method createAndSaveAuthorizationCode.
private AuthorizationCode createAndSaveAuthorizationCode(AuthorizationRequest authorizationRequest, OpenIDClient client, User user) {
URI redirectionURI = authorizationRequest.getRedirectionURI();
Scope scope = authorizationRequest.getScope();
List<String> scopes = scope != null ? scope.toStringList() : Collections.emptyList();
// Optional code challenges for PKCE
CodeChallenge codeChallenge = authorizationRequest.getCodeChallenge();
String codeChallengeValue = codeChallenge != null ? codeChallenge.getValue() : null;
CodeChallengeMethod codeChallengeMethod = authorizationRequest.getCodeChallengeMethod();
String codeChallengeMethodValue = codeChallengeMethod != null ? codeChallengeMethod.getValue() : (codeChallengeValue != null ? CodeChallengeMethod.getDefault().getValue() : null);
List<String> idTokenClaims = getClaims(authorizationRequest);
String code = tokenGenerator.generateAuthorizationCode();
Nonce nonce = authorizationRequest instanceof AuthenticationRequest ? AuthenticationRequest.class.cast(authorizationRequest).getNonce() : null;
AuthorizationCode authorizationCode = new AuthorizationCode(code, user.getSub(), client.getClientId(), scopes, redirectionURI, codeChallengeValue, codeChallengeMethodValue, nonce != null ? nonce.getValue() : null, idTokenClaims, redirectionURI != null, tokenValidity(10 * 60));
authorizationCodeRepository.insert(authorizationCode);
return authorizationCode;
}
use of com.nimbusds.oauth2.sdk.pkce.CodeChallengeMethod in project OpenConext-oidcng by OpenConext.
the class TokenEndpoint method handleAuthorizationCodeGrant.
private ResponseEntity handleAuthorizationCodeGrant(AuthorizationCodeGrant authorizationCodeGrant, OpenIDClient client) {
String code = authorizationCodeGrant.getAuthorizationCode().getValue();
MDCContext.mdcContext("code", "code");
AuthorizationCode authorizationCode = concurrentAuthorizationCodeRepository.findByCodeNotAlreadyUsedAndMarkAsUsed(code);
if (authorizationCode == null) {
/*
* Now it become's tricky. Did we get an 'null' because the code was bogus or because it was already
* used? To both satisfy the - highly theoretical - risk of the audit race condition and the OIDC certification
* demand of deleting access_token issued with the re-used authorization code we need to query again.
*
* If they code was bogus this will result in a 404 exception by the authorizationCodeRepository#findByCode
* and if we find something then we know there was a re-use issue.
*/
AuthorizationCode byCode = authorizationCodeRepository.findByCode(code);
accessTokenRepository.deleteByAuthorizationCodeId(byCode.getId());
throw new TokenAlreadyUsedException("Authorization code already used");
}
if (!authorizationCode.getClientId().equals(client.getClientId())) {
throw new UnauthorizedException("Client is not authorized for the authorization code");
}
if (authorizationCodeGrant.getRedirectionURI() != null && !authorizationCodeGrant.getRedirectionURI().toString().equals(authorizationCode.getRedirectUri())) {
throw new RedirectMismatchException("Redirects do not match");
}
if (authorizationCode.isRedirectURIProvided() && authorizationCodeGrant.getRedirectionURI() == null) {
throw new RedirectMismatchException("Redirect URI is mandatory if specified in code request");
}
if (authorizationCode.isExpired(Clock.systemDefaultZone())) {
throw new UnauthorizedException("Authorization code expired");
}
CodeVerifier codeVerifier = authorizationCodeGrant.getCodeVerifier();
String codeChallenge = authorizationCode.getCodeChallenge();
if (codeVerifier != null) {
if (codeChallenge == null) {
throw new CodeVerifierMissingException("code_verifier present, but no code_challenge in the authorization_code");
}
CodeChallengeMethod codeChallengeMethod = CodeChallengeMethod.parse(authorizationCode.getCodeChallengeMethod());
CodeChallenge computed = CodeChallenge.compute(codeChallengeMethod, codeVerifier);
// Constant time comparison
if (!MessageDigest.isEqual(codeChallenge.getBytes(), computed.getValue().getBytes())) {
LOG.error(String.format("CodeVerifier %s with method %s does not match codeChallenge %s. Expected codeChallenge is %s", codeVerifier.getValue(), codeChallengeMethod, codeChallenge, computed.getValue()));
throw new CodeVerifierMissingException("code_verifier does not match code_challenge");
}
}
User user = userRepository.findUserBySub(authorizationCode.getSub());
MDCContext.mdcContext(user);
// User information is encrypted in access token
LOG.debug("Deleting user " + user.getSub());
userRepository.delete(user);
Map<String, Object> body = tokenEndpointResponse(Optional.of(user), client, authorizationCode.getScopes(), authorizationCode.getIdTokenClaims(), false, authorizationCode.getNonce(), Optional.of(authorizationCode.getAuthTime()), Optional.of(authorizationCode.getId()));
return new ResponseEntity<>(body, responseHttpHeaders, HttpStatus.OK);
}
use of com.nimbusds.oauth2.sdk.pkce.CodeChallengeMethod in project java-oauth-server by authlete.
the class Federation method buildAuthenticationRequest.
// ------------------------------------------------------------
// Authentication Request
// ------------------------------------------------------------
private AuthenticationRequest buildAuthenticationRequest(State state, CodeVerifier verifier, CodeChallengeMethod method) throws IOException {
// The authorization endpoint of the OpenID provider.
URI endpoint = authorizationEndpoint();
// response_type
ResponseType responseType = new ResponseType("code");
// scope
Scope scope = buildAuthenticationRequestScope();
// client_id (from federation configuration)
ClientID clientId = clientId();
// redirect_uri (from federation configuration)
URI redirectUri = redirectUri();
// Start to build an authentication request.
AuthenticationRequest.Builder builder = new AuthenticationRequest.Builder(responseType, scope, clientId, redirectUri).endpointURI(endpoint);
// state
if (state != null) {
builder.state(state);
}
// code_challenge & code_challenge_method
if (verifier != null && method != null) {
// code_challenge is computed from the verifier and the method.
builder.codeChallenge(verifier, method);
}
return builder.build();
}
use of com.nimbusds.oauth2.sdk.pkce.CodeChallengeMethod in project java-oauth-server by authlete.
the class Federation method createFederationRequest.
// ------------------------------------------------------------
// Federation Flow
// ------------------------------------------------------------
/**
* Create an authentication request that is to be sent to the authorization
* endpoint of the OpenID Provider.
*/
public URI createFederationRequest(String state, String codeVerifier) throws IOException {
// state
State st = (state != null) ? new State(state) : null;
// Code verifier that is to be used to calculate code_challenge.
CodeVerifier verifier = (codeVerifier != null) ? new CodeVerifier(codeVerifier) : null;
// code_challenge_method
CodeChallengeMethod method = (verifier != null) ? CodeChallengeMethod.S256 : null;
// Create an authentication request that is to be sent to
// the authorization endpoint.
AuthenticationRequest request = buildAuthenticationRequest(st, verifier, method);
return request.toURI();
}
Aggregations