question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Use typed client and entities for tan verification

See original GitHub issue

Current Implementation

The current tan verification look like this: https://github.com/corona-warn-app/cwa-server/blob/3b98beb268bac511c00f8e13bcbb4978a8cdb4fd/services/submission/src/main/java/app/coronawarn/server/services/submission/verification/TanVerifier.java#L102-L115

There are a couple of issues I would see here:

  1. The tan entity is build from a string which can cause bugs, encoding issues an more.
  2. When the interface of the verification server changes (and this a repo owned by the same organization) this has to be modified as well and can cause runtime bugs without proper system testing

Suggested Enhancement

I would suggest two things

  1. Create a DTO (Pojo) for the tan payload and pass that to the rest template to let Jackson handle serialization
  2. If a dependency between cwa projects is “allowed” (which I would think is perfectly fine) I would actually move that entity to the verification server project in a separate maven module. I would add Spring Feign client and use that in the CWA server. Feign is like the reverse version of @RestController and supports the same annotations. It will create the client implementation from the given interface at runtime.

The client would look like this:

@FeignClient(name = "verification-server", url = "${services.submission.verification.baseUrl}")
public interface StoreClient {

    @RequestMapping(method = RequestMethod.POST, value = "${services.submission.verification.path}", consumes = "application/json")
    ValidationResult validateTan(Tan tan); // both classes should be Pojos
}

The usage would look like this (I did not actually implemented that!):

 private boolean verifyWithVerificationService(String tanString) {
   Tan tan = Tan.from(tanString); // This should also do the UUID verification!
    
    ValidationResult result = verificationServer.validateTan(tan);

    return result != null;
  }

Expected Benefits

  • Compilation breaks when interface changes
  • Less risk of bugs

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:7 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
odrotbohmcommented, May 27, 2020

I like those suggestions. The introduction of a value object for a TAN is something I thought about suggesting as well. Would bind the verification logic into a value and make the using code more expressive and safe.

Although I am more of a hypermedia guy and thus not a big fan of hard coding URIs in clients, I think Feign would be fine here, although I think that – unless also used in other places – the benefit of using that over RestTemplate/WebClient is not that significant.

What I do think needs improvement is the setup of whatever client API is ended up being used. Remote calls definitely need a timeout as otherwise the system is stuck in case the downstream service is not answering at all for whatever reasons.

1reaction
christian-kirschnickcommented, May 30, 2020

I haven’t really looked at the verification server but calling as POST to verify a TAN seems to me a bit unRESTy to be honest. But this is probably worth another issue…

It actually explained in the documentation:

The HTTP method POST is used instead of GET for added security, so data (e.g. the registration token or the TAN) can be transferred in the body.

However, I would still doubt that it’s necessary.

Correct me if I’m wrong, but when doing backend-to-backend http call, the whole request - both URL params and and body - are within the same TCP packet. So as long as either:

  • Both backends are within a secure environment or
  • The use TLS I don’t think moving the tan to the body helps to improve security in any way.

This is probably only important when doing a frontend-to-backend call which is not the case here.

The main reason to go with POST here (which transports the secret in the http body) is due to the sensitive nature of the TAN. We don’t want the TAN to come up in any of our infrastructure / http access logs by chance.

This does not only apply to TANs but to all other sensitive data we are processing.

Read more comments on GitHub >

github_iconTop Results From Across the Web

TAN Verification - How to Check/Verify Tan Number
Find out all about TAN and TAN verification. Know the complete TAN verification process by name and number, TAN verification FAQs and more!...
Read more >
Search TAN - Sandbox - API Docs
Use Search TAN API to verify and get details for a particular TAN. ... tan of a business entity & returns detailed information...
Read more >
TERM: Transaction Authentication Number (TAN) - Kount
A type of single-use password used for an online banking transaction in conjunction with a standard ID and password. Search for Glossary Terms....
Read more >
Web Authentication: An API for accessing Public Key ... - W3C
The authenticator returns a response to the client, which in turn returns a response to the Relying Party script. If the user declined...
Read more >
cwa-verification-server/architecture-overview.md at master
The use case creates a TAN. Only a specific number of TANs can be generated for a specific Registration Token, as of writing...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found