在 RestEasy 和 Tomcat 中处理 basic/base64 安全 401 异常

Handling a basic/base64 security 401 exception in RestEasy and Tomcat

有很多方法可以为 REST(easy) 服务提供良好的安全性。我已经试过了。在这种情况下,仅 是需要的基本身份验证。所以,不是基于login,RequestFilters等。请关注这个例子。

在为一种 RestEasy 'post' 方法添加安全性时,我不断收到 401 异常。我怎样才能安全地访问 'post'?我使用了 Adam Bien / Atjem König 的验证器代码。

没有 web.xml 中的安全设置,我可以正常访问,所以这部分代码工作正常。 我 need/want 中间没有任何登录屏幕。

Tomcat 用户:conf/tomcat-users。xml:

 <user username="wineuser" password="winepass" roles="winer"/>

Web.xml 文件:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>wine secret</web-resource-name>
        <url-pattern>/rest/wines/secret</url-pattern>
        <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint>
        <role-name>winer</role-name>
    </auth-constraint>
</security-constraint>
<login-config>
    <auth-method>BASIC</auth-method>
</login-config>
<security-role>
    <role-name>winer</role-name>
</security-role>

申请class:

@ApplicationPath("/rest")
public class RestEasyWineServices extends Application {
}

身份验证器实用程序:

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.core.MultivaluedMap;
import javax.xml.bind.DatatypeConverter;

public class Authenticator implements ClientRequestFilter {
    private final String user;
    private final String password;
    public Authenticator(String user, String password) {
        this.user = user;
        this.password = password;
    }
    public void filter(ClientRequestContext requestContext) throws IOException {
        MultivaluedMap<String, Object> headers = requestContext.getHeaders();
        final String basicAuthentication = getBasicAuthentication();
        headers.add("Authorization", basicAuthentication);
    }
    private String getBasicAuthentication() {
        String token = this.user + ":" + this.password;
        try {
            return "Basic " +
                 DatatypeConverter.printBase64Binary(token.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException ex) {
            throw new IllegalStateException("Cannot encode with UTF-8", ex);
        }
    }
}

资源class和方法:

@Path("/wines")
public class WineResource {
    ...
    @POST @Path("secret")
    @Produces({ MediaType.APPLICATION_JSON })
    @Consumes({ MediaType.APPLICATION_JSON})
    public Wine echoPostWineSecret( Wine inputWine2) {
        System.out.println( "Server: **SECRET** post (" + inputWine2 + ")");
        inputWine2 = dao.create(inputWine2);
        return inputWine2;
    }
}

客户class:

Client clientSecret = ClientBuilder.newClient().register(new Authenticator( "wineuser", "winepass"));
WebTarget targetSecret = clientSecret.target("http://localhost:8080").path("/RestRestEasyJquerySqlite2Hibernate/rest/wines");

wine.setId( 1231);
wine.setName( "secret wine name_" + dateKey);
wine.setCountry( "secret wine country_" + dateKey);
wine.setGrapes( "secret wine grapes_" + dateKey);
wine.setRegion( "secret wine region_" + dateKey);
try { 
    wine = targetSecret.path( "secret").request( MediaType.APPLICATION_JSON_TYPE).post( Entity.entity( wine, MediaType.APPLICATION_JSON_TYPE), Wine.class);
    System.out.println( "SECRET created wine: " + wine);
} catch( Exception e) {
    System.out.println( "ERROR: Back on the client: exception");
    e.printStackTrace();
}

引用的软件是正确的。部署错误。

出现401异常的问题是软件部署在Eclipse链接的私有Tomcat服务器上。在该服务器上没有对用户进行配置。

问题的解决方案是将 WAR 文件导出到单独的 Tomcat 服务器。在这个 Tomcat 服务器上,我通过 tomcat-users 配置文件配置了用户。