AngularJS$http、CORS和Jersey的基本身份验证
我正在学习AngularJS。我已经用带有基本身份验证的AngularJS$http、CORS和Jersey的基本身份验证,angularjs,cors,jersey,basic-authentication,Angularjs,Cors,Jersey,Basic Authentication,我正在学习AngularJS。我已经用带有基本身份验证的CORS创建了示例项目。我的服务器端代码是Jersey Rest。但我还是得到了403个禁止的错误。我不明白。我错过了什么吗。我的代码如下。请帮我解决它 服务器代码-- /* * This is the controller level Code to get all UserlogInHistoryAngular * information */ @GET @Path("/getall") @Produces({ MediaT
CORS
创建了示例项目。我的服务器端代码是Jersey Rest。但我还是得到了403个禁止的错误。我不明白。我错过了什么吗。我的代码如下。请帮我解决它
服务器代码--
/*
* This is the controller level Code to get all UserlogInHistoryAngular
* information
*/
@GET
@Path("/getall")
@Produces({
MediaType.APPLICATION_XML,
MediaType.APPLICATION_JSON
})
public Response getAllUserLogInHistoryAngular() {
log.info("Controller layer for Get All UserlogInHistory");
UserLoginHistoryService userLogInHistoryService = new UserLoginHistoryService();
GenericEntity < List < UserLogInHistory >> userLoginHistory = new GenericEntity < List < UserLogInHistory >> (
userLogInHistoryService.getAllUserlogInHisotry()) {};
return Response
.status(200)
.entity(userLoginHistory)
.header("Access-Control-Allow-Credentials", true)
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods",
"GET, POST, DELETE, PUT, OPTIONS")
.header("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization, X-CSRF-Token, Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name")
.allow("OPTIONS").build();
}
}
var myapp = angular
.module('myapp', ['angularUtils.directives.dirPagination']);
myapp.config(function($httpProvider) {
//Enable cross domain calls
$httpProvider.defaults.withCredentials = true;
$httpProvider.defaults.useXDomain = true;
});
myapp.controller('customerController', function($scope, $http) {
var encodingstring = window.btoa("numery" + ":" + "password");
console.log(encodingstring);
$http({
withCredentials: true,
headers: {
'Authorization': 'Basic ' + encodingstring,
'Content-Type': 'application/json; charset=utf-8'
},
method: "GET",
url: "http://localhost:8080/userloginhistoryapi/rest/secured/userloginhistory/getall"
}).then(function(response) {
$scope.lstUser = response.data;
//$log.info(response);
console.log(response.data);
console.log($scope.lstUser);
})
$scope.sortColumn = "name";
$scope.reverseSort = false;
$scope.sortData = function(column) {
$scope.reverseSort = ($scope.sortColumn == column) ? !$scope.reverseSort : false;
$scope.sortColumn = column;
};
$scope.getSortColumn = function(column) {
if ($scope.sortColumn == column) {
return $scope.reverseSort ? 'arrow-down' : 'arrow-up';
}
return '';
};
function getSelectedIndex(id) {
for (var i = 0; i < $scope.listCustomers.length; i++)
if ($scope.listCustomers[i].id == id)
return i
return -1;
};
angular.js:13018 OPTIONS http://localhost:8080/userloginhistoryapi/rest/secured/userloginhistory/getall 403 (Forbidden)
(anonymous) @ angular.js:13018
sendReq @ angular.js:12744
serverRequest @ angular.js:12485
processQueue @ angular.js:17396
(anonymous) @ angular.js:17444
$digest @ angular.js:18557
$apply @ angular.js:18945
bootstrapApply @ angular.js:1939
invoke @ angular.js:5108
doBootstrap @ angular.js:1937
bootstrap @ angular.js:1957
angularInit @ angular.js:1842
(anonymous) @ angular.js:35431
trigger @ angular.js:3491
(index):1 Failed to load http://localhost:8080/userloginhistoryapi/rest/secured/userloginhistory/getall: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8081' is therefore not allowed access. The response had HTTP status code 403.
angular.js:15018 Possibly unhandled rejection: {"data":null,"status":-1,"config":{"method":"GET","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"callback","withCredentials":true,"headers":{"Authorization":"Basic bnVtZXJ5OnBhc3N3b3Jk","Accept":"application/json, text/plain, */*"},"url":"http://localhost:8080/userloginhistoryapi/rest/secured/userloginhistory/getall"},"statusText":"","xhrStatus":"error"}
(anonymous) @ angular.js:15018
(anonymous) @ angular.js:11302
processChecks @ angular.js:17428
$digest @ angular.js:18557
$apply @ angular.js:18945
done @ angular.js:12799
completeRequest @ angular.js:13056
requestError @ angular.js:12972
error (async)
(anonymous) @ angular.js:12985
sendReq @ angular.js:12744
serverRequest @ angular.js:12485
processQueue @ angular.js:17396
(anonymous) @ angular.js:17444
$digest @ angular.js:18557
$apply @ angular.js:18945
bootstrapApply @ angular.js:1939
invoke @ angular.js:5108
doBootstrap @ angular.js:1937
bootstrap @ angular.js:1957
angularInit @ angular.js:1842
(anonymous) @ angular.js:35431
trigger @ angular.js:3491
VM2032:185 [CodeLive] HTTP detected: Connecting using WS
VM2032:109 [CodeLive] Connected to CodeLive at ws://127.0.0.1:42529
bundle.js:10 license url https://www.genuitec.com/go/webclipse-buy-now
这就是发生的事情。这是一个
选项
请求。此请求发生在实际请求之前。它与服务器进行检查,以查看请求是否被允许。作为对飞行前请求的响应,服务器应该发回Access-Control-X-X
头,就像您在getAllUserLogInHistoryAngular
方法中一样
因此,在飞行前的情况下,它会点击基本的身份验证过滤器并自动被拒绝,而不添加CORS响应头。将CORS响应头放在resource方法中没有任何作用,也没有任何用处。通常,COR应该在一个过滤器中处理,以便它在命中资源方法之前处理所有请求
这是你应该做的。与基本身份验证一样,使用ContainerRequestFilter
处理CORS。您希望在身份验证筛选器之前调用此筛选器,因为CORS预飞行不关心身份验证,并且它不会随请求发送身份验证凭据。在这个过滤器中,您应该检查它是否是CORS飞行前请求。通常,这可以通过检查选项
方法以及是否存在原点
标题来完成。如果是飞行前,则中止请求并在ContainerResponseFilter
中添加CORS标头。可能看起来像
@Provider
@PreMatching
public class CorsFilter implements ContainerRequestFilter, ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext request) throws IOException {
if (isPreflightRequest(request)) {
request.abortWith(Response.ok().build());
return;
}
}
private static boolean isPreflightRequest(ContainerRequestContext request) {
return request.getHeaderString("Origin") != null
&& request.getMethod().equalsIgnoreCase("OPTIONS");
}
@Override
public void filter(ContainerRequestContext request, ContainerResponseContext response)
throws IOException {
if (request.getHeaderString("Origin") == null) {
return;
}
if (isPreflightRequest(request)) {
response.getHeaders().add("Access-Control-Allow-Credentials", "true");
response.getHeaders().add("Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS, HEAD");
response.getHeaders().add("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization, X-CSRF-Token, " +
"Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name");
}
response.getHeaders().add("Access-Control-Allow-Origin", "*");
}
}
请注意,它是一个@PreMatching
过滤器,这将导致在您的身份验证过滤器之前调用它(假设过滤器不是一个预匹配过滤器,在这种情况下,您还应该使用@Priority
注释)
此筛选器所做的是检查请求是否为飞行前请求,如果是,则以200中止整个请求,这会导致请求跳过资源方法,跳过它之后的所有其他请求筛选器,并跳转到响应筛选器。在响应过滤器中,我们通过检查前面设置的属性来检查它是否为飞行前。如果是,则设置CORS响应头。如果您想了解有关CORS的更多信息以及有关此特定筛选器实现的更多信息,请访问
所以不,这是将要发生的事情的流程
客户端浏览器服务器
------ ------- ------
请求端点------->记住请求------->发回CORS
但首先发送响应头
来自CorsFilter的CORS预飞
|
抓住原始Skips CorsFilter,
转到身份验证筛选器,
转到资源
发送资源响应
|
Handle response您是否检查过任何REST客户端(如Postman)中的服务是否与凭据一起工作正常?您的基本身份验证发生在哪里?服务在Postman和SoapUI中工作正常。我两个都查过了。我使用ContainerRequestFilter进行基本身份验证