public async Task <object> RedeemToken([FromBody] ExternalLogin options) { // check for server-generated nonce, and make sure it was issued recently if (!IssuedNonces.Any(o => o.Hash == options.Nonce)) { this.ThrowLocalizedServiceException(Constants.InvalidNonce); } Nonce nonce = IssuedNonces.FirstOrDefault(o => o.Hash == options.Nonce); if (nonce.Processing) { this.ThrowLocalizedServiceException(Constants.InProgressNonce); } if (nonce.Created.AddMinutes(30) < DateTime.UtcNow) { IssuedNonces.Remove(nonce); this.ThrowLocalizedServiceException(Constants.ExpiredNonce); } nonce.Update(true); // swap the external access token for a local application token var identity = await this.externalAuthService.RedeemToken(options); if (identity == null) { this.ThrowLocalizedServiceException(Constants.UnknownUser); } // remove the original nonce, and revoke the external access token, as they are longer required IssuedNonces.Remove(nonce); this.externalAuthService.RevokeToken(options.ProviderId, options.AccessToken); return(await this.tokenService.IssueToken(identity, identity.Name)); }