【问题标题】:Spring Boot and Angular authentication - how to secure the app?Spring Boot 和 Angular 身份验证 - 如何保护应用程序?
【发布时间】:2021-04-17 18:52:04
【问题描述】:

所以我有这个使用 Spring MVC 和 JSP 运行的遗留应用程序,从 mongo DB 读取
,我正在考虑将其替换为使用 Spring Boot 和 Angular JS 的现代应用程序

我不是在寻找一个框架,我的问题是关于身份验证的更多概念,以及它如何在 Angular 和 Spring Boot 之间工作。

我不想使用第三方进行身份验证,我想继续使用我的内部数据库用户和密码。
我还有一个客户端需要先注册的 REST API,然后在绕过角度和身份验证的每个请求上发送一个令牌。

所以在过去(古老的 j2ee)我有 Servlet 过滤器,这个过滤器对任何请求都运行,它检查会话是否经过身份验证,如果没有 - 它会转发到身份验证页面,然后将结果存储在会话中.

类似这样的东西:

@WebFilter("/*")
public class LoginFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {    
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        HttpSession session = request.getSession(false);
        String loginURI = request.getContextPath() + "/login";

        boolean loggedIn = session != null && session.getAttribute("user") != null;
        boolean loginRequest = request.getRequestURI().equals(loginURI);

        if (loggedIn || loginRequest) {
            chain.doFilter(request, response);
        } else {
            response.sendRedirect(loginURI);
        }
    }

    // ...
}

如何用 Angular JS 做同样的认证机制?
servlet 中的过滤器等价于什么?
Angular 是客户端渲染,如何保障呢?

感谢您的任何意见!

【问题讨论】:

  • 从 spring security 提供的 formLigin 开始,它将为您提供基于会话的身份验证。在 Angular 中实现自定义表单。

标签: java angular spring


【解决方案1】:

我不是在寻找框架,我的问题更具概念性 关于身份验证,以及它如何在 Angular 和 Spring 之间工作 开机。

我发现这个回答特别棘手,因为您要求的是超出特定框架的概念性答案,但您指的是 Angular 和 Spring 这两个框架,所以让我们退后一步。

正确的身份验证始终必须在服务器端执行,因为客户端上的身份验证很容易绕过。您可以设置一些看门狗来禁止客户端的某些路由,但这只是为了改善用户体验。

基本上有两种风格可供选择:有状态或无状态

状态身份验证是在成功身份验证后,服务器将创建一些会话,存储它的一些标识符,并在连续请求时对其进行验证。这是使用 cookie 的传统会话方法,在 spring 中命名为 JSESSION。这种方法的缺点是必须在某个地方维护状态,除非您有粘性会话(您可以通过将这些信息保存在内存中来逃脱),否则您将需要一些分布式系统来存储/检索它(一个 SQL 数据库, cassandra,你的宠物项目等)。但正如我们所知,高流量的分布式状态会成为瓶颈,最好尽可能避免它。

无状态身份验证:由于 JWT 包含在任何服务器上重新创建会话所需的所有信息,因此没有分布式状态,或者更好地说,状态在客户端(浏览器)中,并且是加密的签名,以便用户可以访问/篡改它们。缺点是令牌的加密/解密可能需要一点 CPU,但对用户来说没有什么明显的。

因此,一旦您决定了上述一项,其余的就没有什么不同了。在这两种情况下,您都必须在角度上实现一些 interceptor,根据具体情况在每个请求上发送 cookie 或 Auth 标头,并且在服务器端,您必须通过相应的过滤器。除了第一个示例中的 cookie,您可以只发送会话值并作为标头,以更 RESTful 的方式。

我还有一个客户端需要先注册然后再注册的 REST API 绕过角度和身份验证,在每个请求上发送一个令牌。

这看起来像是您的 API 的一个新用例,但上述说法成立,您仍然可以在登录完成后使用这些身份验证标头进行授权 并且令牌/会话已返回给身份验证用户。对于这种类型的客户端,您还可以使用不同的身份验证令牌,在这种情况下,只需链接一个新的过滤器来检查此标头,而无需对您的 API 进行任何更改。

我相信您会在网上找到合适的资源来实施您想要的身份验证/授权解决方案

【讨论】:

    【解决方案2】:

    显而易见的想法:https://spring.io/guides/tutorials/spring-security-and-angular-js/

    如果您尝试使用静态资源在同一端口上提供 angular,您将很难使用 spring boot 设置它,因为在谁应该解决特定资源(angular 或 spring boot)方面存在冲突。例如:/home 可以通过 Angular 解决,但 spring 不知道存在 /home 的事实,如果您直接点击 /home,除非加载了 index.html,否则它将无法通过 Angular 解决你会看到一个 404 Whitelabel 页面。

    如果您在不同的端口上使用 angular 和 spring boot,那么您必须阅读上述弹簧指南中的这句话:

    您不能拥有安全、无状态的应用程序。

    补充Hopey One 已经指出的内容:使用JHipster 并没有你想象的那么糟糕。构建 80% 的项目几乎不需要一天的时间,然后您可以相应地调整剩余的 20%。它将解决大部分知识空白,让您编写实际需要的代码。而且由于您已经有一个正在运行的应用程序,因此其中大部分将是复制粘贴工作。您可以阅读this guide 来设置环境。

    【讨论】:

      【解决方案3】:

      使用 Spring Boot,您希望使用 Spring Security 并尽可能多地构建在框架之上。我看到了三种方法:

      【讨论】:

        【解决方案4】:

        我建议探索这两个主题:

        Filterservlet-api的一部分,这意味着过滤器可以在任何库中实现,Web服务器将注册并映射到特定的url。在我们的例子中,您的LoginFilterJWTAuthenticationFilter 非常相似,但具有Spring Framework 的附加功能,这两个类都实现了Filter 接口。

        【讨论】:

          【解决方案5】:

          看看JHipster 项目。无需太多努力,您就可以生成一个基于 angular 和 spring boot 的简单项目。它使用您选择的数据库实现 JWT 进行身份验证。可以作为一个很好的引导程序或作为实施项目的参考实现。

          【讨论】:

          • 谢谢,这意味着学习另一个框架......我想避免这种情况。
          猜你喜欢
          • 2016-07-30
          • 1970-01-01
          • 2021-12-16
          • 2018-01-10
          • 2018-04-15
          • 1970-01-01
          • 1970-01-01
          • 2020-09-18
          • 2019-04-25
          相关资源
          最近更新 更多