azure-sdk-for-java icon indicating copy to clipboard operation
azure-sdk-for-java copied to clipboard

Refactor AuthorizationChallengeHandler class

Open samvaity opened this issue 1 year ago • 1 comments

Closes #39628

Design:

  1. Define an interface to handle different types of authentication challenges:
public interface ChallengeHandler {
    void handleChallenge(HttpRequest request, Response<?> response);
    boolean canHandle(Response<?> response);
    static ChallengeHandler of(ChallengeHandler... handlers) {
        return new CompositeChallengeHandler(Arrays.asList(handlers));
    }
}
  1. Implement the ChallengeHandler for Basic Authentication
public class BasicAuthChallengeHandler implements ChallengeHandler {}
  1. Implement the ChallengeHandler for Digest Authentication
public class DigestAuthChallengeHandler implements ChallengeHandler {}
  1. Create a CustomAuthenticator that uses the challenge handler
public class CustomAuthenticator implements Authenticator {
    private final Map<String, ChallengeHandler> handlers = new ConcurrentHashMap<>();

    public CustomAuthenticator(Map<String, ChallengeHandler> handlers) {
        this.handlers.putAll(handlers);
    }
  1. OkhttpClientBuilder to use the authenticator as before. with updated ProxyAuthencticator that uses the inner class of

  2. internal to ChallengeHandler CompositeChallengeHandler

CompositeChallengeHandler(List<ChallengeHandler> handlers) {
        this.handlers = handlers;
    }

    @Override
    public boolean canHandle(Response<?> response) {
    }
    
     @Override
      public void handleChallenge(HttpRequest request, Response<?> response) {
     // prefer digest auth handler first
     }

samvaity avatar Sep 23 '24 18:09 samvaity

I'm in preference for this design

public interface ChallengeHandler {
    Request handleChallenge(Response response);
}

As it is agnostic to the underlying challenge kind. The current design in azure-core is tied too much into Basic and Digest auth and isn't easy to evolve.

We will want to have support for multiple challenge handlers at once for cases where the possible challenge could be different based on endpoints being called (ex, one endpoint challenges with Basic and another challenges with Digest). So, we may want to provide a way to do something like:

ChallengeHandler.of(ChallengeHandler...)

alzimmermsft avatar Sep 23 '24 20:09 alzimmermsft