当前位置: 首页 > 面试题库 >

如何对服务器正确验证AngularJS客户端

卜盛
2023-03-14
问题内容

我正在建立一个使用RESTful API(Jersey)的AngularJS网络应用程序。

在服务器端,我正在使用Java应用程序服务器(详细来说是Glassfish 4)。

我的设置如下:

  • AngularJS Webapp作为单个war文件部署到Java EE应用程序服务器。
  • RESTfulAPI(和后端逻辑)也作为war文件部署到同一Java EE应用程序服务器。
  • AngularJS Web应用程序调用REST API来获取所需的数据。
  • RESTful API:
    • /api/public/*用于公众不受限制的访问(例如/ api / public / users / signup以注册为新用户)。允许任何用户访问该区域。无需登录
    • /api/private/* 用于受限访问(例如/ api / private / account / {id}以检索某些帐户特定的数据)
  • 专用资源受到Java EE内部安全性概念的保护(有关Web.xml的详细信息,请参见下文)。

Web.xml

<security-constraint>
    <web-resource-collection>
        <web-resource-name>PRIVATE REST API</web-resource-name>
        <url-pattern>/private/*</url-pattern>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
        <http-method>HEAD</http-method>
        <http-method>PUT</http-method>
        <http-method>OPTIONS</http-method>
        <http-method>TRACE</http-method>
        <http-method>DELETE</http-method>
    </web-resource-collection>
    <auth-constraint>
        <description>Have to be a USER</description>
        <role-name>USERS</role-name>
    </auth-constraint>
</security-constraint>
<login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>userauth</realm-name>
</login-config>
<security-role>
    <description/>
    <role-name>USERS</role-name>
</security-role>

此设置对我有用,但前提是我必须在浏览器中手动调用URL。如果我没有通过身份验证并访问安全区域,浏览器会要求输入用户名和密码。如果提供的凭据有效,那么我将可以访问限制区域:很好。

但是如何在AngularJS中使用它呢?要登录,需要进行POST
API调用:/api/public/users/login您必须从表单(用户名和密码)中提供凭据。

客户端代码是:

ctrls.controller('LoginController', function($scope, $http, $log, $location, UserService, RemoteServerHelperService) {
    $scope.loginDataWrong = undefined;
    $scope.login = function(credentials) {
    $http.post(RemoteServerHelperService.buildURL('/public/users/login'), credentials)
        .success(function (data, status) {
            UserService.setLoggedIn(credentials.email);
            $scope.loginDataWrong = undefined;
            $location.path('/app');
            $log.info("login attempt: successfull. User.loggedIn:" + UserService.isLoggedIn());
        }).error(function (data, status, headers, config) {
            UserService.invalidate();
            $scope.loginDataWrong = true;
            $log.info("login attempt: failed. User.loggedIn:" + UserService.isLoggedIn());
        });
    };
});

客户端代码似乎起作用。我也有一些路由可以确保客户端内容的安全,等等。有几篇文章详细描述了客户端代码。因此,此“摘要”应该足够了。

服务器端代码为:

@POST
@Path("/login")
@Consumes(MediaType.APPLICATION_JSON)
public Response login(Credentials credentials, @Context HttpServletRequest request) {
    if (isAlreadyAuthenticated(request)) {
        try {
            request.logout();
        } catch (ServletException ex) {
            return Response.status(Status.CONFLICT).build();
        }
    }

    // not authenticated
    try {
        request.login(credentials.getEmail(), credentials.getPassword());
        return Response.ok().build();
    } catch (ServletException ex) {
        return Response.status(Status.CONFLICT).build();
    }
}

但是,这不会“验证”客户端的进一步请求。成功登录后在受限区域内进行API调用时,我会403 FORBIDDEN从服务器端收到响应。所以我认为我做错了。您有任何想法如何验证客户端到服务器的进一步请求吗?

可能的解决方案是切换到基于FORM的身份验证,并简单地使用j_username和j_password调用j_security_check,但是现在我想坚持使用BASIC-
Authentication并通过RESTful API手动执行身份验证。

该设置$httpProvider.defaults.withCredentials = true;似乎没有任何效果。

更新:

多亏了leaderleader,我才解决了这个问题。我删除了该login()方法,因为我希望Java EE-Server负责身份验证。

要访问安全区域,AngularJS网络应用必须正确设置HTTP标头。在我的情况下$http.defaults.headers.common['Authorization'] = 'Basic <username:pw>';username:password必须使用Base64编码。

正确设置标题后,将不会显示密码提示,并且AngularJS Web应用程序可以访问REST API。


问题答案:

多亏了leaderleader,我才解决了这个问题。我删除了login()方法,因为我希望Java EE-Server负责身份验证。

要访问安全区域,AngularJS网络应用必须正确设置HTTP标头。就我而言,$ http.defaults.headers.common
[‘Authorization’] =’Basic’; 其中username:password必须为Base64编码。

正确设置标题后,将不会显示密码提示,并且AngularJS Web应用程序可以访问REST API。



 类似资料:
  • 问题内容: 我试图了解如何执行以下操作: 声明表单的可接受方式是什么。我的理解是,您只需用HTML声明表单,并添加ng-model指令,如下所示: 要发送到服务器的内容。我可以将item对象作为JSON发送到服务器,然后对其进行解释。然后,我可以对对象执行验证。如果失败,则抛出JSON错误,然后发回确切的信息?有接受的方式吗?如何以一种很好的方式将验证错误从服务器推送到客户端? 我确实需要一个示例

  • 我试图了解如何做以下事情: 声明表单的公认方式是什么。我的理解是您只需用超文本标记语言声明表单,然后添加ng-model指令,如下所示: 发送到服务器的内容。我可以将item对象作为JSON发送到服务器,并对其进行解释。然后我可以对对象执行验证。如果失败,我抛出一个JSON错误,并返回具体内容?有没有公认的方法?如何以一种好的方式将验证错误从服务器推送到客户端? 我真的需要一个例子,但是Angul

  • 验证 SSH 服务器证书(客户端) 和 SSH 用户证书 类似,使用客户端机构认证来验证主机。需要一个 SSH 服务器数字证书认证机构签发服务器证书,客户端只需要保存 CA 的公钥。 使用一台处于气隙系统下的计算机来生成服务器数字证书认证机构的根证书: ❯ ssh-keygen -C "SSH Server Certificate Authority" -f sshserver.root.ca 使

  • 问题内容: 进行客户端或服务器端验证哪个更好? 在我们的情况下,我们正在使用 jQuery和MVC。 在我们的视图和控制器之间传递的JSON数据。 我所做的许多验证工作都是在用户输入数据时对其进行验证。例如,我使用该事件来防止文本框中的字母,设置最大字符数,并且该数字在一定范围内。 我想更好的问题是,与客户端相比,进行服务器端验证是否有任何好处? 真棒的答案大家。我们拥有的网站受到密码保护,并且用

  • 附加内容 How I’ve set up SSH keys on my Yubikey 4 (so far) How to Harden SSH with Identities and Certificates Scalable and secure access with SSH

  • 问题内容: 我有一个角度应用程序,其中包含一个从示例中获取的保存按钮: 这对于客户端验证非常有用,因为当用户解决问题时它会变为false,但是我有一个电子邮件字段,如果另一个用户使用相同的电子邮件注册,则该字段设置为无效。 一旦我将电子邮件字段设置为无效,就无法提交表单,并且用户无法修复该验证错误。所以现在我不能再使用来禁用我的提交按钮。 肯定有更好的办法 问题答案: 我在几个项目中都需要这样做,