Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request log remote user #7537

Merged
merged 2 commits into from
Oct 16, 2023

Conversation

zUniQueX
Copy link
Member

Closes #7506

Currently, a request log implementation cannot get the information of a requesting user from the dropwizard-auth module, because the information doesn't leave the servlet level. This PR modifies the Jetty Authentication with the new Dropwizard authentication information and exposes the authenticated user through the HttpServletRequest#getRemoteUser() method.

@zUniQueX zUniQueX requested a review from a team as a code owner September 19, 2023 18:50
@zUniQueX zUniQueX self-assigned this Oct 15, 2023
Copy link
Member

@joschi joschi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@joschi joschi added this to the 4.0.3 milestone Oct 15, 2023
@zUniQueX zUniQueX enabled auto-merge (squash) October 16, 2023 16:54
@zUniQueX zUniQueX merged commit 3647861 into dropwizard:release/4.0.x Oct 16, 2023
11 of 12 checks passed
@zUniQueX zUniQueX deleted the request-log-remote-user branch October 16, 2023 18:37
zUniQueX added a commit to zUniQueX/dropwizard that referenced this pull request Oct 16, 2023
* Set Jetty `Authentication` in Dropwizard `AuthFilter` to support `HttpServletRequest#getRemoteUser()`

* Add test for correct remote user

Refs dropwizard#7537
(cherry picked from commit 3647861)
zUniQueX added a commit that referenced this pull request Oct 16, 2023
* Set Jetty `Authentication` in Dropwizard `AuthFilter` to support `HttpServletRequest#getRemoteUser()`

* Add test for correct remote user

Refs #7537
(cherry picked from commit 3647861)
@GuilhermeCouto
Copy link

Is it working in 4.0.7 ? I am not seeing the user at the log.

@zUniQueX
Copy link
Member Author

@GuilhermeCouto This was released in 4.0.3. Do you have an example/reproducer for a case where it doesn't work?

@GuilhermeCouto
Copy link

I am in version 4.0.7, my request logs are:

0:0:0:0:0:0:0:1] - - [14/mai./2024:20:00:55 +0000] "OPTIONS /estabelecimento/2/business_hours HTTP/1.1" 200 0 "http://localhost:5000/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" 20
[0:0:0:0:0:0:0:1] - - [14/mai./2024:20:00:55 +0000] "OPTIONS /estabelecimento/2 HTTP/1.1" 200 0 "http://localhost:5000/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" 20
[0:0:0:0:0:0:0:1] - - [14/mai./2024:20:00:56 +0000] "GET /estabelecimento/2/business_hours HTTP/1.1" 200 151 "http://localhost:5000/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" 741
[0:0:0:0:0:0:0:1] - - [14/mai./2024:20:00:56 +0000] "GET /estabelecimento/2 HTTP/1.1" 200 2302 "http://localhost:5000/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" 760

I am getting with an authenticated user.

@GuilhermeCouto
Copy link

@zUniQueX Am I doing something wrong?

@zUniQueX
Copy link
Member Author

@GuilhermeCouto I've just set up an example project using dropwizard 4.0.7 and it works fine for me:

@Path("/")
public class HelloWorldResource {
    @GET
    public String helloWorld(@Auth PrincipalImpl principal) {
        return "Hello World!";
    }
}
@Override
public void run(final AuthenticatedUserRequestLogsConfiguration configuration,
                final Environment environment) {
    BasicCredentialAuthFilter<PrincipalImpl> basicCredentialAuthFilter = new BasicCredentialAuthFilter.Builder<PrincipalImpl>()
            .setAuthenticator(credentials -> Optional.of(new PrincipalImpl(credentials.getUsername())))
            .setAuthorizer((principal, role, requestContext) -> true)
            .buildAuthFilter();
    environment.jersey().register(basicCredentialAuthFilter);
    environment.jersey().register(new AuthValueFactoryProvider.Binder<>(PrincipalImpl.class));
    environment.jersey().register(HelloWorldResource.class);
}

When navigating to the endpoint in a browser and entering some basic auth credentials, this produces the following output:

127.0.0.1 - - [17/Mai/2024:14:54:16 +0000] "GET / HTTP/1.1" 401 49 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0" 28
127.0.0.1 - admin [17/Mai/2024:14:54:20 +0000] "GET / HTTP/1.1" 200 12 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0" 22

The first request results in a 401, therefore no user can be logged. The second request correctly logs the username.

@GuilhermeCouto
Copy link

Here is my code, what is wrong?

    ServerAuthenticator simpleAuthenticator = new ServerAuthenticator(daoUser);
            CachingAuthenticator<BasicCredentials, User> cachingAuthenticator = new CachingAuthenticator<>(
                               environment.metrics(), simpleAuthenticator,
                               configuration.getAuthenticationCachePolicy());                
            
    AuthFilter basicCredentialAuthFilter = new BasicCredentialAuthFilter.Builder<User>()
        .setAuthenticator(cachingAuthenticator)
        .setAuthorizer(new ServerAuthorizer())
        .setRealm("XXXXX")
        .setPrefix("Basic")
        .buildAuthFilter();   
    
    
    final byte[] key = configuration.getJwtTokenSecret();

    final JwtConsumer consumer = new JwtConsumerBuilder()
        .setAllowedClockSkewInSeconds(30) // allow some leeway in validating time based claims to account for clock skew
        .setRequireExpirationTime() // the JWT must have an expiration time
        .setRequireSubject() // the JWT must have a subject claim            
        .setVerificationKey(new HmacKey(key)) // verify the signature with the public key
        .setRelaxVerificationKeyValidation() // relaxes key length requirement
        .build(); // create the JwtConsumer instance        
    
    AuthFilter jwtCredentialAuthFilter = 
        new JwtAuthFilter.Builder<User>()
            .setJwtConsumer(consumer)
            .setRealm("XXXXX")
            .setPrefix("Bearer")
            .setAuthenticator(new JWTAuthenticator(daoUser))
            .buildAuthFilter();               

    List<AuthFilter> filters = Lists.newArrayList(basicCredentialAuthFilter, jwtCredentialAuthFilter);
    environment.jersey().register(new AuthDynamicFeature(new ChainedAuthFilter(filters)));
    
    environment.jersey().register(new SecuredResource(configuration.getJwtTokenSecret(),daoUser));
    environment.jersey().register(RolesAllowedDynamicFeature.class);
    //If you want to use @Auth to inject a custom Principal type into your resource
    environment.jersey().register(new AuthValueFactoryProvider.Binder<>(User.class));`

@zUniQueX
Copy link
Member Author

@GuilhermeCouto So far I cannot see something wrong there.

@GuilhermeCouto
Copy link

I discovered that when I use

List<AuthFilter> filters = Lists.newArrayList(basicCredentialAuthFilter, jwtCredentialAuthFilter); environment.jersey().register(new AuthDynamicFeature(new ChainedAuthFilter(filters)));

The user name doesn't appear in log.

But when I just use

environment.jersey().register(new AuthDynamicFeature(basicCredentialAuthFilter));

It works, and the email of the logged user appears in log.

Any suggestions about how to fix it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Access log should contain the name of the authenticated user
3 participants