在 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 配置文件配置了用户。
有很多方法可以为 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 配置文件配置了用户。