Verifiable Credential - Presentation request gives an Internal Server Error - azure-ad-verifiable-credentials

Microsoft Entra, a new Home of Microsoft Verifiable Credential is really new and nice feature. While I am playing around the items, I found an issue which I am not sure is an issue from my code rather Its more from the platform.
To give you little detail:
Company A: I have one Microsoft Verifiable Account to create the credentials for Company A employee.
Company B: I have one Microsoft Verifiable Account to verify (who likes to give a discount to those employees who are from Company A).
Step 1: using Company A, I have created the Verifiable Credential and It is stored in my Microsoft Authenticator App successfully.
Step 2: Coming to the next part of the story, Company B generates the presentation request where It likes to verify Company A employees' identity. I am able to create that presentation request and QR code for that as well.
Issue comes: Now, when I scan that presentation QR code using the authenticator app, It finds my stored crednetial is matching with this request. so, It gives me an option to share that credential against this presentation reuqest which is good and correct. But the moment I press "Share" it wait for a second and gives me an error message.
The error message is user friendly: Oops, failed to connect.
It seems there is a problem with one of our services connecting to your device. Check your network connection and try again.
But in technical detail, It says:
Error Code: internalServerError
Error Details: A generic error has occurred on the server.; Not Found; Not Found
TimeStamp: Dec1, 2022 10:02:48 AM EST
Request ID: 438395be97f20bbcc31511351121bbaa
Correlation ID: 3sg46/0ARha0zS/XHYKGfA.6.4
It also gives an option to see the track which is way long and can not be copy in mobile clipboard. But I took a part of that and that is below:
2022-11-30 17:49:33,560 INFO/Broker: [com.microsoft.identity.common.internal.result.MsalBrokerResultAdapter:authenticationResultFromBundle][2022-11-30 17:49:33 - thread_name: pool-27-thread-2, correlation_id: b27725eb-c6fc-4a0f-bdd5-dd5f3f74270b - Android 30] Broker Result returned from Bundle, constructing authentication result ThreadPoolExecutor$Worker.run()#641 [pool-14-thread-1]
2022-11-30 17:49:33,562 INFO/App: MSAL acquire token silently success: com.microsoft.identity.client.AuthenticationResult#5709e74 MsalTokenRefreshManager$getTokenSilentlyAsync$4$1$onTaskCompleted$acquireTokenSilentParameters$1.onSuccess()#567 [main]
2022-11-30 17:49:33,563 INFO/Broker: [com.microsoft.identity.common.java.result.LocalAuthenticationResult][2022-11-30 17:49:33 - thread_name: pool-27-thread-2, correlation_id: b27725eb-c6fc-4a0f-bdd5-dd5f3f74270b - Android 30] Id Token type: IdToken ThreadPoolExecutor$Worker.run()#641 [pool-14-thread-1]
2022-11-30 17:49:33,563 INFO/Broker: [com.microsoft.identity.common.java.result.LocalAuthenticationResult][2022-11-30 17:49:33 - thread_name: pool-27-thread-2, correlation_id: b27725eb-c6fc-4a0f-bdd5-dd5f3f74270b - Android 30] Constructing LocalAuthentication result, AccessTokenRecord null: false, AccountRecord null: false, RefreshTokenRecord null or empty: false, IdTokenRecord null: false ThreadPoolExecutor$Worker.run()#641 [pool-14-thread-1]
2022-11-30 17:49:33,564 INFO/App: Token result: Success AadRemoteNgcAuthCheckUseCase$checkForAuth$2.invokeSuspend()#88 [DefaultDispatcher-worker-5]
2022-11-30 17:49:33,564 INFO/Broker: [CommandDispatcher:submitSilent][2022-11-30 17:49:33 - thread_name: pool-27-thread-2, correlation_id: b27725eb-c6fc-4a0f-bdd5-dd5f3f74270b - Android 30] Completed silent request as owner for correlation id : **b27725eb-c6fc-4a0f-bdd5-dd5f3f74270b, with the status : COMPLETED is cacheable : true ThreadPoolExecutor$Worker.run()#641 [pool-14-thread-1]
2022-11-30 17:49:33,564 INFO/App: ListSessionsUseCase request with client request ID: 09871643-7561-4d9a-8e43-567c4d0480cb RemoteAuthenticationManager.listSessions()#201 [DefaultDispatcher-worker-5]
Just to troubleshoot:
I have tried to restart my phone.
Connected with wi-fi and data card.
I tried to check the previous Company A issuer Credential flow is still working and giving me the credential and all are working.
So, it is not an issue from my device and neither is the issue with authenticator connectivity issue from my side.

I think your implementation is based on the following Azure sample.
If so, please comment out the line on VerifierController.cs file under PresentationCallback() method which has a statement like //payload = presentationResponse["issuers"].ToString(). The data in the incoming request payload doesn't have "issuers". Instead of commenting out, you can also use the following:
payload = presentationResponse["verifiedCredentialsData"][0]["issuer"];

Related

Flutter App + Google Calendar API : events.insert not returning 'conferenceData'

I am following this github code as an example to create a google calendar event in a workspace calendar using a service account.
I followed various examples on how to authenticate and connect using a service account and now I am able to create an event and it shows up in the workspace calendar as well successfully.
However, the event that is returned does not have the 'conferenceData' from which I could fetch the 'conferenceId' to create the google meet link.
Below is the insert code that I use, which works but does not return the said conference data.
await calendar.events.insert(event, calendarId,
conferenceDataVersion: 1, sendUpdates: "none")
.then((value) {
print("Event Status: ${value.status}");
if (value.status == "confirmed") {
print(value.toJson().toString());
String joiningLink;
String eventId;
eventId = value.id;
joiningLink = "https://meet.google.com/${value.conferenceData?.conferenceId}";
print('Event added to Google Calendar : $joiningLink');
}
}
});
Here's the output I get printed to the console:
I/flutter ( 2934): Event Status: confirmed
I/flutter ( 2934): {created: 2022-07-26T16:12:20.000Z, creator: Instance of 'EventCreator', description: xxxx-desc, end: Instance of 'EventDateTime', etag: "3317703881666000", eventType: default, htmlLink: https://www.google.com/calendar/event?eid=djc1b2gyY3RzZ2p1YWGo4aWtmdWIydG5pZ3R2aGNvNEBn, iCalUID: v75oh2ctsgjuahtircv#google.com, id: v75oh2ctv7itndnc, kind: calendar#event, location: Google Meet, organizer: Instance of 'EventOrganizer', reminders: Instance of 'EventReminders', sequence: 0, start: Instance of 'EventDateTime', status: confirmed, summary: xxxxxxx, updated: 2022-07-26T16:12:20.833Z}
I/flutter ( 2934): Event added to Google Calendar : https://meet.google.com/null
Any suggestions on how to get the conferenceData and hence the conferenceId?
*** EDIT ****
Something else turned up while I was digging around:
While it doesn't matter for my use case, but google api won't allow me to add attendees - even if it is the service account email id.
Error creating event DetailedApiRequestError(status: 403, message:
Service accounts cannot invite attendees without Domain-Wide
Delegation of Authority.)
I don't understand, domain-wide delegation is already done for this account and that is why I am able to authenticate and create a calendar event in the first place.
Is my understanding wrong?
I found this answer that could get you in the right direction. You need to add the conferenceData.createRequest values in the insert() method in order to get a Google Meet link from the new event.
About the error related to Domain-Wide Delegation:
It is expected to get this error when the service account is not impersonating any user in the Google Workspace organization, you can review this section from Google Developers under "Delegate domain wide authority" and try to update the code in order to impersonate a different user. Looking around I found here that the optional argument that you could when using a service account in your case is impersonatedUser.

Error report for execution and query intent in the test suite of the google action

Our project passed “Turn on” execution and query in the test
suite of the google action.
But “Turn off” execution and query failed and I couldn’t find in our part.
After “Turn off” execution, I responded “false” for “on” attribute but
error report was shown - actual state: {"on":true,"online":true}.
Below is the exchanged data and the error report.
Google action request for execution:
{"inputs":[{"context":{"locale_country":"US","locale_language":"en"},"intent":"action.devices.EXECUTE","payload":{"commands":[{"devices":[{"id":"eg_cam_87901"}],"execution":[{"command":"action.devices.commands.OnOff","params":{"on":false}}]}]}}],"requestId":"960820806239759768"}
Our Response for execution:
{"requestId":"960820806239759768","payload":{"commands":[{"ids":["eg_cam_87901"],"status":"SUCCESS","state":{"online":false,"on":false,"currentToggleSettings":null}}]}}
Google action error report
Turn off the bedroom
AssertionError: Expected state to include: {"on":false}, actual state: {"on":true,"online":true}: expected false to be true
Google action request for query:
{"inputs":[{"intent":"action.devices.QUERY","payload":{"devices":[{"id":"eg_cam_87901"}]}}],"requestId":"4409204964431192716"}
Our Response for query:
{"requestId":"4409204964431192716","payload":{"devices":{"eg_cam_87901":{"online":false,"status":"SUCCESS","on":false,"currentToggleSettings":null}}}}
Google action error report
Query after 'Turn off the bedroom'
Error: the string "Error from HA: deviceOffline" was thrown, throw an Error :) at new f (js/app_compiled.js?f77b3b67-f1c5-4a38-8a20-fe5eafbc2c40:18143:10) at Runner.fail (js/app_compiled.js?f77b3b67-f1c5-4a38-8a20-fe5eafbc2c40:4491:11) at js/app_compiled.js?f77b3b67-f1c5-4a38-8a20-fe5eafbc2c40:4802:18 at done (js/app_compiled.js?f77b3b67-f1c5-4a38-8a20-fe5eafbc2c40:4189:5) at js/app_compiled.js?f77b3b67-f1c5-4a38-8a20-fe5eafbc2c40:4236:11 at w.Ic (js/app_compiled.js?f77b3b67-f1c5-4a38-8a20-fe5eafbc2c40:18137:24) at r.run (js/app_compiled.js?f77b3b67-f1c5-4a38-8a20-fe5eafbc2c40:18129:169) at js/app_compiled.js?f77b3b67-f1c5-4a38-8a20-fe5eafbc2c40:18171:310 at w.Jl (js/app_compiled.js?f77b3b67-f1c5-4a38-8a20-fe5eafbc2c40:18137:454) at r.Ms (js/app_compiled.js?f77b3b67-f1c5-4a38-8a20-fe5eafbc2c40:18130:301) at h (js/app_compiled.js?f77b3b67-f1c5-4a38-8a20-fe5eafbc2c40:18126:375) at y.Jl [as Ic] (js/app_compiled.js?f77b3b67-f1c5-4a38-8a20-fe5eafbc2c40:18139:326) at q (js/app_compiled.js?f77b3b67-f1c5-4a38-8a20-fe5eafbc2c40:18167:89) at e (js/app_compiled.js?f77b3b67-f1c5-4a38-8a20-fe5eafbc2c40:18158:235) at XMLHttpRequest.w (js/app_compiled.js?f77b3b67-f1c5-4a38-8a20-fe5eafbc2c40:18167:241)
You've got a couple issues here.
First, you need to verify that your sync response includes the appropriate device attributes - your execution/query responses both return NULL for your currentToggleSettings instead of the string of the availableToggles in your sync response. If you are just using OnOff for your device, you don't actually even need to implement any of the Toggle trait features. Again, verify what is in your initial sync response.
Second, you're returning online: false as well as on:false, which is why you're getting the following error:
Error: the string "Error from HA: deviceOffline" was thrown
online:false should only be used when you intend to return the TTS response of "the device is not available right now" when a user issues a command/query, and when the device cannot be controlled. This should also include status:ERRROR in your response. You can read more about handling errors and exceptions in the docs.
Returning online:true, on:false or online:true, on:true when responding to an execute/query request should fix the deviceOffline error.

Updating SLA via REST (PyOTRS)

I'm working on a little project right now and therefor I tried to update the Service Level Agreement (SLA) of a ticket which has no SLA assigned yet, by using PyOTRS, but it didn't work. Getting the Information SLA or SLAID of a Ticket did work with this code:
from pyotrs import Client
client = Client("http://otrs.example.com", "root#localhost", "password")
client.session_create()
myticket = client.ticket_get_by_id("1")
print(myticket.field_get(("SLA")))
But Updating the SLA or SLAID didn't work with the following code (It worked for other attributes like Owner, Responsible, etc.). So my Question is, is it possible to update the SLA/SLAID and if yes, what am I doing wrong?
from pyotrs import Client
client = Client("http://otrs.example.com", "root#localhost", "password")
client.session_create()
myticket = client.ticket_update(1, SLAID="1")
This is the Error Message I get:
OTRS Error Code: TicketUpdate.InvalidParameter
OTRS Error Message: TicketUpdate: Ticket->SLAID or Ticket->SLA parameter is invalid!
We faced the same issue and were able to solve it.
As a precondition, the SLA must be assigned to a Service in OTRS.
Afterwards you have to send SLAID and ServiceID to the system to get a ticket with SLA created.

Cannot Validate AccessToken with IdentityServer

We are using IdentityServer for authentication and we are validating the access token using JwtSecurityTokenHandler ValidateToken. This used to work fine, but after we upgraded our client application to ASP.NET Core 1.0 RTM (from RC1), the validation fails. The received error is:
IDX10501: Signature validation failed. Unable to match 'kid'
When I look at the KeyID of the used certificate and the kid of the token, I can see that they are different. I checked the IdentityServer jwks-endpoint to check that I had the correct certificate and noticed that the kid and certificate key id are different from that endpoint too. From what I've understood, they are supposed to be the same?
Any ideas why the code broke during the upgrade since the certificate, token and IdentityServer are still the same and only the client app core was upgraded.
EDIT (More information)
I suspect that ValidateIssuerSigningKey is false by default and the key has not even been validated before (thus it was working). Now it seems that the ValidateIssuerSigningKey is being ignored (as bad practice?) and thus the validation fails.
Workaround/Fix
By setting the IssuerSigningKeyResolver manually and giving the key to use in validation explicitly, fixes the issue and validation passes. Not sure how good the workaround is and why the default doesn't work, but at least I can move on for now.
simplified code...
new JwtSecurityTokenHandler().ValidateToken(authTokens.AccessToken,
new TokenValidationParameters()
{
IssuerSigningKeys = keys,
ValidAudience = audience,
ValidIssuer = issuer,
IssuerSigningKeyResolver = (arbitrarily, declaring, these, parameters) => new List<X509SecurityKey> { securityKey }
}, out securityToken);
The Client and API should refer to the same instance of IdentityServer. We are running IdentityServerHost in Azure, which has different slots (main and staging) and two applications inconsistently referred to different slots. The Client received access token issued by IdSrv-main provider and passed it to API, that expected it from different provider IdSrv-staging. API validated it and returned error.
The problem is that the errror doesn't give a hint to the actual cause of the issue. MS should provide much more detailed error message to help debugging.
The current error message is not sufficient to identify the cause.

Getting information on ride requests in sandbox mode

Using Uber's API, I managed to make a trip request, and then change it's status to accepted via the PUT command described in the docs.
However, if afterwards I make a GET request to fetch ride's attributes, I get status = accepted, but driver, eta, location and vehicle are null. Thus, I can't test that the whole flow works.
Am I missing something?
Actually, once the trip in sandbox mode is set to status "Accepted" you should be able to see all those attributes. I just tested this myself and it worked fine.
The flow I followed was:
1) POST to https://sandbox-api.uber.com/v1/requests (with the proper params and auth headers) to create a sandbox trip
2) PUT to https://sandbox-api.uber.com/v1/sandbox/requests/{trip_UUID from step 1) with JSON body: {"status": "accepted"}
3) GET https://sandbox-api.uber.com/v1/requests/current OR GET https://sandbox-api.uber.com/v1/requests/{trip_UUID from step 1}
Could you provide some more details on the exact flow you followed?
According to the /v1/requests/{request_id} endpoint documentation
Note: The following fields are populated only when a trip is active:
driver
vehicle
pickup
destination
The meaning of the "accepted" status is:
accepted The Request has been accepted by a driver and is "en route"
to the start location (i.e. start_latitude and start_longitude).
I think by "trip is active" they mean the request status needs to be in_progress
in_progress The Request is "en route" from the start location to the
end location.
Try to change the status of the request to in_progress using the PUT /v1/sandbox/requests/{request_id} sandbox endpoint.
After this you should be able to get access to the driver, vehicle, pickup and destination fields.