Java Dropwizard Auth-如果未提供标头,如何返回默认用户?

Java Dropwizard Auth-如果未提供标头,如何返回默认用户?,java,authentication,dropwizard,Java,Authentication,Dropwizard,如果没有指定baciauth的头,我希望我的授权机制返回默认用户。我试着这样做: @Override public Optional<User> authenticate(final BasicCredentials basicCredentials) throws AuthenticationException { String email = basicCredentials.getUsername(); String plaintext

如果没有指定baciauth的头,我希望我的授权机制返回默认用户。我试着这样做:

@Override
    public Optional<User> authenticate(final BasicCredentials basicCredentials) throws AuthenticationException {

        String email = basicCredentials.getUsername();
        String plaintextPassword = basicCredentials.getPassword();

        final Optional<User> user = Optional.of(userDao.getUserByEmail(email));

        if (user.isPresent()) {
            return user;
            }
        else {
            return Optional.of(defaultUser);
        }
    }
@覆盖
公共可选身份验证(final BasicCredentials BasicCredentials)引发AuthenticationException{
字符串email=basicCredentials.getUsername();
字符串plaintextPassword=basicCredentials.getPassword();
最终可选用户=Optional.of(userDao.getUserByEmail(email));
if(user.isPresent()){
返回用户;
}
否则{
返回可选的.of(defaultUser);
}
}
但是,不知何故,当我在没有适当标题的情况下提出请求时,我仍然得到了401


如何使其工作?

因此,如果没有基本身份验证标头,则会将null
BasicCredentials
传递给预身份验证进程,从而导致自动的未经授权错误响应。所以我们需要确保有一个标题。为此,您可以注册在Dropwizard auth筛选器之前执行的Jersey筛选器。在那里,我们可以添加一个带有默认用户名和密码的标题

import java.io.IOException;
import javax.annotation.Priority;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.HttpHeaders;
import org.glassfish.jersey.internal.util.Base64;

@Priority(Priorities.AUTHENTICATION - 100)
public class PreAuthenticationFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext request) throws IOException {
        boolean hasValidHeader = false;
        if (request.getHeaders().containsKey(HttpHeaders.AUTHORIZATION)) {
            final String header = request.getHeaderString(HttpHeaders.AUTHORIZATION);
            if (header.toLowerCase().startsWith("basic")) {
                hasValidHeader = true;
            }
        }
        if (!hasValidHeader) {
            final String defaultUser = "defaultUser";
            final String defaultPassword = "defaultPassword";
            final String base64 = Base64.encodeAsString(defaultUser + ":" + defaultPassword);
            request.getHeaders().putSingle(HttpHeaders.AUTHORIZATION, "Basic " + base64);
        }
    } 
}

然后用DW
env.jersey().register(PreAuthenticationFilter.class)注册它

因此,如果没有基本身份验证标头,则会向预身份验证进程传递一个空的
基本身份验证
,这会导致自动的未经授权错误响应。所以我们需要确保有一个标题。为此,您可以注册在Dropwizard auth筛选器之前执行的Jersey筛选器。在那里,我们可以添加一个带有默认用户名和密码的标题

import java.io.IOException;
import javax.annotation.Priority;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.HttpHeaders;
import org.glassfish.jersey.internal.util.Base64;

@Priority(Priorities.AUTHENTICATION - 100)
public class PreAuthenticationFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext request) throws IOException {
        boolean hasValidHeader = false;
        if (request.getHeaders().containsKey(HttpHeaders.AUTHORIZATION)) {
            final String header = request.getHeaderString(HttpHeaders.AUTHORIZATION);
            if (header.toLowerCase().startsWith("basic")) {
                hasValidHeader = true;
            }
        }
        if (!hasValidHeader) {
            final String defaultUser = "defaultUser";
            final String defaultPassword = "defaultPassword";
            final String base64 = Base64.encodeAsString(defaultUser + ":" + defaultPassword);
            request.getHeaders().putSingle(HttpHeaders.AUTHORIZATION, "Basic " + base64);
        }
    } 
}

然后用DW
env.jersey().register(PreAuthenticationFilter.class)注册它

问题是,如果您使用该筛选器,为什么不立即在该筛选器中进行身份验证?在我看来,DW auth有点缺陷,因为它剥夺了我认为重要的一点控制。我更喜欢在过滤器中进行身份验证,而不是使用DW的方法。我想很多人都遇到过同样的问题。authN/authZ链中有几个过滤器。首先是身份验证过滤器。Dropwizard在此筛选器中使用您的验证器。Jersey授权(RoleAllowed)过滤器,它调用您的授权人。所以不同的过滤器处理不同的事情。也许您看到的有缺陷的不是过程,而是身份验证过滤器的实现。对于您特定的用例,是的,我同意必须使用此工作环境是一种负担。但这就是它的实现方式。您可以看到它在哪里检查头。如果不存在,则抛出异常。问题是,如果您使用筛选器,为什么不立即在该筛选器中进行身份验证?在我看来,DW auth有点缺陷,因为它剥夺了我认为重要的一点控制。我更喜欢在过滤器中进行身份验证,而不是使用DW的方法。我想很多人都遇到过同样的问题。authN/authZ链中有几个过滤器。首先是身份验证过滤器。Dropwizard在此筛选器中使用您的验证器。Jersey授权(RoleAllowed)过滤器,它调用您的授权人。所以不同的过滤器处理不同的事情。也许您看到的有缺陷的不是过程,而是身份验证过滤器的实现。对于您特定的用例,是的,我同意必须使用此工作环境是一种负担。但这就是它的实现方式。您可以看到它在哪里检查头。如果不存在,则抛出异常。