Spring Security和Angular教程(一)安全的单页应用程序

Spring Security和Angular教程(一)

安全的单页应用程序

在本教程中,我们展示了Spring Security,Spring Boot和Angular的一些很好的功能,它们协同工作以提供愉快和安全的用户体验。Spring和Angular的初学者应该可以访问它,但是也有很多细节可供专家使用。这实际上是Spring Security和Angular系列部分中的第一部分,其中每个部分都依次公开了新功能。我们将在第二部分和后续部分中改进应用程序,但此后的主要更改是体系结构而非功能性。

Spring和单页应用程序

HTML5,丰富的基于浏览器的功能和“单页面应用程序”是现代开发人员非常有价值的工具,但任何有意义的交互都将涉及后端服务器,以及静态内容(HTML,CSS和JavaScript),我们将采用需要一个后端服务器。后端服务器可以扮演任何或所有角色:提供静态内容,有时(但现在不常见)渲染动态HTML,验证用户,保护对受保护资源的访问,以及(最后但并非最不重要)与JavaScript交互在浏览器中通过HTTP和JSON(有时称为REST API)。

Spring一直是构建后端功能的流行技术(特别是在企业中),随着Spring Boot的出现,事情变得前所未有的简单。让我们看看如何使用Spring Boot,Angular和Twitter Bootstrap从零开始构建新的单页面应用程序。没有特别的理由选择那个特定的堆栈,但它很受欢迎,特别是在企业Java商店的核心Spring选区,所以这是一个有价值的起点。

创建一个新项目

我们将逐步详细地创建这个应用程序,这样任何不完全使用Spring和Angular的人都可以关注正在发生的事情。如果您希望切换到追逐,您可以跳到应用程序正在运行的末尾,并查看它们如何组合在一起。创建新项目有多种选择:

我们要构建的完整项目的源代码在Github中,所以你可以克隆项目并直接从那里开始工作。然后跳到下一部分

使用卷曲

创建新项目以开始的最简单方法是通过Spring Boot Initializr。例如在类似UN * X的系统上使用curl:

$ mkdir ui && cd ui
$ curl https://start.spring.io/starter.tgz -d style=web \
-d style=security -d name=ui | tar -xzvf -

然后,您可以将该项目(默认情况下是普通的Maven Java项目)导入您喜欢的IDE,或者只使用命令行中的文件和“mvn”。然后跳到下一部分

使用Spring Boot CLI

您可以使用Spring Boot CLI创建相同的项目,如下所示:

$ spring init --dependencies web,security ui/ && cd ui

然后跳到下一部分

使用Initializr网站

如果您愿意,也可以直接从Spring Boot Initializr获取与.zip文件相同的代码。只需在浏览器中打开它并选择依赖项“Web”和“安全性”,然后单击“生成项目”。.zip文件在根目录中包含标准Maven或Gradle项目,因此您可能需要在解压缩之前创建一个空目录。然后跳到下一部分

使用Spring Tool Suite

Spring Tool Suite(一组Eclipse插件)中,您还可以使用向导创建和导入项目File->New->Spring Starter Project。然后跳到下一部分。IntelliJ IDEA和NetBeans具有类似的功能。

添加角度应用程序

如今,Angular(或任何现代前端框架)中的单页面应用程序的核心将是Node.js构建。Angular有一些工具可以快速设置它,所以让我们使用它们,并保留使用Maven构建的选项,就像任何其他Spring Boot应用程序一样。有关如何设置Angular应用程序的详细信息将在其他地方介绍,或者您可以从github查看本教程的代码。

运行应用程序

一旦Angular应用程序启动,您的应用程序将可以在浏览器中加载(即使它还没有做太多)。在命令行上,您可以执行此操作

$ mvn spring-boot:run

并转到http:// localhost:8080的浏览器。当您加载主页时,您应该获得一个浏览器对话框,询问用户名和密码(用户名是“user”,密码在启动时在控制台日志中打印)。实际上还没有任何内容(或者可能是来自ngCLI 的默认“英雄”教程内容),所以你应该基本上得到一个空白页面。

 如果您不喜欢在控制台日志中输入密码,只需将其添加到“application.properties”(在“src / main / resources”中):( security.user.password=password并选择您自己的密码)。我们使用“application.yml”在示例代码中完成了此操作。

在IDE中,只需main()在应用程序类中运行该方法(只有一个类,UiApplication如果使用上面的“curl”命令则调用它)。

要打包并作为独立的JAR运行,您可以这样做:

$ mvn package
$ java -jar target/*.jar

自定义角度应用程序

让我们自定义“app-root”组件(在“src / app / app.component.ts”中)。

最小的Angular应用程序如下所示:

app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'Demo';
  greeting = {'id': 'XXX', 'content': 'Hello World'};
}

此TypeScript中的大多数代码都是锅炉板。有趣的东西都将出现在AppComponent我们定义“selector”(HTML元素的名称)的地方,以及通过@Component注释呈现的HTML片段。我们还需要编辑HTML模板(“app.component.html”):

app.component.html

<div style="text-align:center"class="container">
  <h1>
    Welcome {{title}}!
  </h1>
  <div class="container">
    <p>Id: <span>{{greeting.id}}</span></p>
    <p>Message: <span>{{greeting.content}}!</span></p>
  </div>
</div>

如果您在“src / app”下添加了这些文件并重建了应用程序,它现在应该是安全且实用的,它会说“Hello World!”。在greeting由角在HTML中使用车把呈现占位符,{{greeting.id}}{{greeting.content}}

添加动态内容

到目前为止,我们有一个带有硬编码问候语的应用程序。这对于了解事物是如何组合在一起很有用,但实际上我们希望内容来自后端服务器,所以让我们创建一个HTTP端点,我们可以使用它来获取问候语。在您的应用程序类中(在“src / main / java / demo”中),添加@RestController注释并定义一个新的@RequestMapping

UiApplication.java

@SpringBootApplication
@RestController
public class UiApplication {

  @RequestMapping("/resource")
  public Map<String,Object> home() {
    Map<String,Object> model = new HashMap<String,Object>();
    model.put("id", UUID.randomUUID().toString());
    model.put("content", "Hello World");
    return model;
  }

  public static void main(String[] args) {
    SpringApplication.run(UiApplication.class, args);
  }

}
 根据您创建新项目的方式,可能不会调用它UiApplication

运行该应用程序并尝试卷曲“/ resource”端点,您会发现默认情况下它是安全的:

$ curl localhost:8080/resource
{"timestamp":1420442772928,"status":401,"error":"Unauthorized","message":"Full authentication is required to access this resource","path":"/resource"}

从Angular加载动态资源

所以让我们在浏览器中抓取该消息。修改AppComponent以使用XHR加载受保护资源:

app.component.ts

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'Demo';
  greeting = {};
  constructor(private http: HttpClient) {
    http.get('resource').subscribe(data => this.greeting = data);
  }
}

我们注入了一个由Angular通过模块提供的http服务http并用它来获取我们的资源。Angular将响应传递给我们,我们提取JSON并将其分配给问候语。

为了将http服务依赖注入到我们的自定义组件中,我们需要在AppModule包含组件的组件中声明它(imports与初始草稿相比,它只是一行):

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

再次运行应用程序(或只是在浏览器中重新加载主页),您将看到带有唯一ID的动态消息。因此,即使资源受到保护而您无法直接卷曲,浏览器也能够访问内容。我们有一个安全的单页应用程序,不到一百行代码!

 您可能需要强制浏览器在更改后重新加载静态资源。在Chrome(以及带有插件的Firefox)中,您可以使用“开发人员工具”(F12),这可能就足够了。或者您可能必须使用CTRL + F5。

它是如何工作的?

如果您使用某些开发人员工具,则可以在浏览器中看到浏览器和后端之间的交互(通常F12打开它,默认情况下在Chrome中运行,可能需要Firefox中的插件)。这是一个总结:

动词路径状态响应

得到

/

401

浏览器提示进行身份验证

得到

/

200

的index.html

得到

/*.js

200

角度来自第三资产的负荷

得到

/main.bundle.js

200

应用逻辑

得到

/资源

200

JSON问候语

您可能看不到401,因为浏览器将主页加载视为单个交互,您可能会看到2个“/ resource”请求,因为存在CORS协商。

仔细查看请求,您将看到所有这些请求都有一个“授权”标题,如下所示:

Authorization: Basic dXNlcjpwYXNzd29yZA==

浏览器正在为每个请求发送用户名和密码(因此请记住在生产中使用HTTPS)。没有什么“Angular”,所以它适用于您的JavaScript框架或非框架的选择。

这有什么不对?

从表面上看,似乎我们做得非常好,它简洁,易于实现,我们所有的数据都通过密码保护,如果我们改变了前端或后端技术,它仍然可以工作。但是有一些问题。

  • 基本身份验证仅限于用户名和密码身份验证。

  • 身份验证UI无处不在但很难看(浏览器对话框)。

  • Cross Site Request Forgery(CSRF)不提供任何保护。

CSRF并不是我们的应用程序的问题,因为它只需要获取后端资源(即服务器中没有状态更改)。一旦你在你的应用程序中有POST,PUT或DELETE,任何合理的现代措施都不再安全。

本系列下一部分中,我们将扩展应用程序以使用基于表单的身份验证,这比HTTP Basic更灵活。一旦我们有了表单,我们将需要CSRF保护,Spring Security和Angular都有一些很好的开箱即用功能来帮助解决这个问题。剧透:我们将需要使用HttpSession

谢谢:我要感谢帮助我开发这个系列的所有人,特别是Rob WinchThorsten Spaeth对文本和源代码的仔细审查,以及教我一些技巧,我甚至不知道这些部分我以为我最熟悉。


原文地址:https://spring.io/guides/tutorials/spring-security-and-angular-js

下载代码:https://github.com/daqiang123/Spring-Security-and-Angular/tree/master/basic

依次执行mvn clean,mvn install,mvn spring-boot:run命令,运行程序。

如果执行命令报错,可终止后再次执行。

在浏览器中输入http://localhost:8080/

在登录框中输入用户名:user,密码:password,访问程序。

欢迎加入大华软件学院QQ群交流,群号:665714453。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值