如何集成基于 angularjs 和 java jaas 的身份验证?

Posted

技术标签:

【中文标题】如何集成基于 angularjs 和 java jaas 的身份验证?【英文标题】:how to integrate angularjs and java jaas based authentication? 【发布时间】:2014-07-30 13:23:53 【问题描述】:

我有一个 web 应用程序,前端有 angularJS,后端有 Java。 Angular 通过使用和通过 HTTP 发送 JSON 的 Restful Web 服务与 Java 后端通信。我需要为这个应用程序构建身份验证机制,并且想知道最好的方法是什么,目前我正在使用基于 JAAS 的身份验证(JDBC 用户表)。这是我的应用程序的配置方式:

我的 web.xml 配置有:

    <login-config>
        <auth-method>FORM</auth-method>
        <realm-name>userauth</realm-name>
        <form-login-config>
            <form-login-page>/login.html</form-login-page>
            <form-error-page>/loginError.html</form-error-page>
        </form-login-config>                
    </login-config>

    <security-constraint>   
        <display-name>ConstraintSSL</display-name>
        <web-resource-collection>
            <web-resource-name>protected</web-resource-name>
            <description/>
            <url-pattern>/checkout/*</url-pattern>
            <url-pattern>/login/*</url-pattern>
            <url-pattern>/login.*</url-pattern>
            <url-pattern>/account/*</url-pattern>
            <url-pattern>/ad/create</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>

        <user-data-constraint>        
          <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>        
    </security-constraint>

    <security-constraint>   
        <display-name>ConstraintUser</display-name>
        <web-resource-collection>
            <web-resource-name>user</web-resource-name>
            <description/>
            <url-pattern>/account/*</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/>
            <role-name>ADMINISTRATORS</role-name>
            <role-name>USERS</role-name>
        </auth-constraint>

        <user-data-constraint>        
          <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>        
    </security-constraint>

    <security-role>
        <description/>
        <role-name>USERS</role-name>
    </security-role>
    <security-role>
        <description/>
        <role-name>ADMINISTRATORS</role-name>
    </security-role>

  <session-config>
    <session-timeout>30</session-timeout>
    <tracking-mode>COOKIE</tracking-mode>
  </session-config>

   <welcome-file-list>
    <welcome-file>init.html</welcome-file>
   </welcome-file-list>

init.html 仅重定向到加载 angular 并启动实际应用程序的 index.html 页面。

现在这是我的 UserController,它处理客户端(浏览器)上的用户相关活动:

myControllers.controller('UserController', ['$scope', '$routeParams', 'UserService',
  function($scope, $routeParams, UserService) 
    $scope.logged = false;

    // if User is not detected by cookie
    $scope.user = fetchUserFromCookie();

    if (! $scope.user) 

        // set default guest user
        $scope.user =          
            firstName : 'guest',
            lastName : 'user',
            preferredCurrency : "USD$",
            sessionHash: "XXXXXX",
            shoppingCart : 
                totalItems : 0,
                total : 0
                       
        ;      

    

    $scope.login = function(userName, pass) 
          $scope.user = UserService.login(userName, pass);            
          $scope.logged = true;      
    ;

    $scope.logout = function(userName) 
          $scope.user = UserService.logout(userName); // warn server side you're logging out
          $scope.logged = false;
          $scope.user = null;
    ;

  ]);

我的目标是提供一个基于 JAAS 的 JDBC 身份验证的登录页面,并且只允许那些具有特定 ADMIN 角色或 USER 角色的用户查看某个页面,如何在基于 angularJS + Java 的应用程序中实现这一点?

我主要关心的是会话跟踪,

如何跟踪特定用户已授予访问权限并有权更改特定记录?

如何防止手动更改 JS 代码或更改 Cookie 以劫持用户会话?

【问题讨论】:

总是做服务器端权限检查,你不会有问题#3! 是的,但是如何实现呢?我如何知道调用 REST 端点的实际客户端是特定的授权用户?我应该在会话期间在客户端和服务器周围传递令牌吗?你能指出一个示例实现吗?谢谢 我有一个类似的问题并找到了aschua.de/blog/pairing-angularjs-and-javaee-for-authentication 的帖子。也许这对你也有帮助,即使有点晚了。 谢谢!这绝对有帮助 @guilhebl 您从哪里获取用户的角色详细信息?来自数据库还是来自 Web.xml 文件?能否请你帮忙。我在同一阶段使用 angular+java 实现身份验证 【参考方案1】: index.html 页面应在 html 中包含令牌以避免 CSRF 令牌不应存储在 cookie 存储中 每个请求都应使用标头参数进行签名 服务器应通过传递的标头验证每个请求 如果必须使用 cookie,您应该验证引用者以防止 CSRF

【讨论】:

你的意思是把 cookie 作为隐藏字段放在 HTML 中?此外,即使用户关闭浏览器,我也需要记住用户,然后我将令牌保存在 cookie 和服务器端,所以稍后我可以恢复用户的会话而无需让他再次登录,是否存在这样做有什么风险吗? 我的意思是像带有 token 属性的 div。如果您需要存储令牌,则应尽可能使用本地存储而不是 cookie (ie9+)。如果您仍然需要使用 cookie,请尝试阅读有关 csrf 的更多信息。 en.wikipedia.org/wiki/Cross-site_request_forgery我记得在服务器端检查referer和token的最简单方法 我明白了,但我想启用“记住我”功能,就像堆栈交换或其他网站一样,当用户关闭浏览器并再次打开时,我想恢复他的会话,使用 LocalStorage 的唯一问题是因为它是一个 HTML5 功能,旧浏览器不支持它,所以我在这种情况下使用 Cookie,所以我必须确保我验证引用者。

以上是关于如何集成基于 angularjs 和 java jaas 的身份验证?的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS 和 Webpack 集成

如何集成 bootstrap-3.0.1 和 AngularJS?

基于 Jenkins 快速搭建持续集成环境

如何将 Flot 与 AngularJS 集成?

如何集成 AngularJS 和 Spring-OAuth2?

如何将 Apache Shiro 与 AngularJS 集成