@POST
@Produces("application/json")
public Response accessRequest(@PathParam("realm") String realmId,
MultivaluedMap<String, String> formData)
{
Realm realm = identityManager.getRealm(realmId);
if (realm == null) throw new NotFoundException();
String code = formData.getFirst("code");
if (code == null)
{
logger.debug("code not specified");
Map<String, String> error = new HashMap<String, String>();
error.put("error", "invalid_request");
error.put("error_description", "code not specified");
return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
}
String client_id = formData.getFirst("client_id");
if (client_id == null)
{
logger.debug("client_id not specified");
Map<String, String> error = new HashMap<String, String>();
error.put("error", "invalid_request");
error.put("error_description", "client_id not specified");
return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
}
User client = identityManager.getUser(realm, client_id);
if (client == null)
{
logger.debug("Could not find user");
Map<String, String> error = new HashMap<String, String>();
error.put("error", "invalid_client");
error.put("error_description", "Could not find user");
return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
}
if (!client.isEnabled())
{
logger.debug("user is not enabled");
Map<String, String> error = new HashMap<String, String>();
error.put("error", "invalid_client");
error.put("error_description", "User is not enabled");
return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
}
boolean authenticated = authenticate(realm, client, formData);
if (!authenticated)
{
Map<String, String> error = new HashMap<String, String>();
error.put("error", "unauthorized_client");
return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
}
JWSInput input = new JWSInput(code, providers);
boolean verifiedCode = false;
try
{
verifiedCode = RSAProvider.verify(input, realm.getPublicKey());
}
catch (Exception ignored)
{
logger.debug("Failed to verify signature", ignored);
}
if (!verifiedCode)
{
Map<String, String> res = new HashMap<String, String>();
res.put("error", "invalid_grant");
res.put("error_description", "Unable to verify code signature");
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res).build();
}
String key = input.readContent(String.class);
AccessCode accessCode = null;
synchronized (accessCodeMap)
{
accessCode = accessCodeMap.remove(key);
}
if (accessCode == null)
{
Map<String, String> res = new HashMap<String, String>();
res.put("error", "invalid_grant");
res.put("error_description", "Code not found");
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res).build();
}
if (accessCode.isExpired())
{
Map<String, String> res = new HashMap<String, String>();
res.put("error", "invalid_grant");
res.put("error_description", "Code is expired");
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res).build();
}
if (!accessCode.getToken().isActive())
{
Map<String, String> res = new HashMap<String, String>();
res.put("error", "invalid_grant");
res.put("error_description", "Token expired");
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res).build();
}
if (!client.getId().equals(accessCode.getClient().getId()))
{
Map<String, String> res = new HashMap<String, String>();
res.put("error", "invalid_grant");
res.put("error_description", "Auth error");
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res).build();
}
AccessTokenResponse res = accessTokenResponse(realm.getPrivateKey(), accessCode.getToken());
return Response.ok(res).build();
}