我有一个用Java实现的rest API(来自swagger的MSF4J codegen)和描述它的swagger 2定义。 摇摇欲坠的UI托管在Web服务器上。该API部署在Internet上的VM上。
我的问题是,摇摇欲坠的UI的“试用”功能不起作用。我总是得到“ 401未经授权”。当我从用户界面中获取curl命令并将其粘贴到我的终端中时,它将起作用。
上周,我没有HTTPS或基本身份验证-只有HTTP-并且运行良好。现在我不知道为什么它不起作用。
自从我将招摇定义更改为https以来,UI发出了OPTIONS请求。我实现了它,但得到了401条回复。
该证书来自Lets Encrypt,并由apache网络服务器使用。 apache是同一台机器上其余api的代理。
这是我的身份验证拦截器:
public class BasicAuthSecurityInterceptor extends AbstractBasicAuthSecurityInterceptor {
@Override
protected boolean authenticate(String username, String password) {
if (checkCredentials(username, password))
return true;
return false;
}
private boolean checkCredentials(String username, String password) {
if (username.equals("testuser"))
return BCrypt.checkpw(password, "$2a$10$iXRsLgkJg3ZZGy4utrdNyunHcamiL2RmrKHKyJAoV4kHVGhFv.d6G");
return false;
}
}
这是api的一部分:
public abstract class DeviceApiService {
private static final Logger LOGGER = LogManager.getLogger();
public abstract Response deviceGet() throws NotFoundException;
public abstract Response deviceIdAvailableLoadGet(Integer id, Long from, Long to, String resolution)
throws NotFoundException;
public abstract Response deviceIdGet(Integer id) throws NotFoundException;
protected Response getOptionsResponse() {
String allowedOrigin = "";
try {
allowedOrigin = PropertyFileHandler.getInstance().getPropertyValueFromKey("api.cors.allowed");
} catch (IllegalArgumentException | PropertyException | IOException e) {
LOGGER.error("Could not get allowed origin.", e);
}
Response response = Response.ok().header("Allow", "GET").header("Access-Control-Allow-Origin", allowedOrigin)
.header("Access-Control-Allow-Headers", "authorization, content-type").build();
return response;
}
}
public class DeviceApi {
private final DeviceApiService delegate = DeviceApiServiceFactory.getDeviceApi();
// @formatter:off
@GET
@Produces({ "application/json" })
@io.swagger.annotations.ApiOperation(
value = "Get devices",
notes = "",
response = Device.class,
responseContainer = "List",
authorizations = { @io.swagger.annotations.Authorization(value = "basicAuth") },
tags = { "Device", }
)
@io.swagger.annotations.ApiResponses(
value = { @io.swagger.annotations.ApiResponse(
code = 200,
message = "200 OK",
response = Device.class,
responseContainer = "List")
})
public Response deviceGet() throws NotFoundException {
return delegate.deviceGet();
}
@OPTIONS
@Consumes({ "application/json" })
@Produces({ "application/json" })
@io.swagger.annotations.ApiOperation(value = "CORS support", notes = "", response = Void.class, authorizations = {
@io.swagger.annotations.Authorization(value = "basicAuth") }, tags = { "Device", })
@io.swagger.annotations.ApiResponses(value = {
@io.swagger.annotations.ApiResponse(code = 200, message = "Default response for CORS method", response = Void.class) })
public Response deviceOptions() throws NotFoundException {
return delegate.getOptionsResponse();
}
}
编辑:
这是swagger ui创建的请求的标头:
Accept: text/html,application/xhtml+xm…plication/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: de,en-US;q=0.7,en;q=0.3
Access-Control-Request-Headers: authorization
Access-Control-Request-Method: GET
Connection: keep-alive
DNT: 1
Host: api.myfancyurl.com
Origin: http://apidoc.myfancyurl.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; …) Gecko/20100101 Firefox/61.0
似乎缺少授权标头。当我编辑请求并使用授权标头和编码的凭据重新发送该请求时,它将起作用。 但是我不知道为什么不昂首阔步不添加此标头。一个人应该未经授权接受所有期权要求吗?