在上一个教程中,我们实现了 — Angular 7 + Spring Boot 登录示例。 我们还创建了一个带有指向页面的链接的菜单。在之前的示例中,我们使用 Angular 代码实现了硬编码的用户名和密码进行登录。在本教程中,我们将使用 Spring Boot 实现基本身份验证。从 Angular 到 Spring Boot 发出的所有 REST 调用都将使用基本身份验证进行身份验证。基本身份验证是使用 HTTP 协议构建的简单身份验证方案。在使用此协议时,HTTP 请求具有 Authorization 标头,该标头包含单词 Basic,后跟一个空格和 base64 编码的字符串 username:password。
.
在之前的教程中,我们已经实现了 Spring Boot + 基本身份验证示例。 此外,在本教程中,Angular 代码虽然是可行的,但不是最优的。添加标头的基本身份验证代码存在大量重复。在下一个教程中,我们将使用 HTTP 拦截器优化此代码。
Angular 7+ Spring Boot - Table of ContentsAngular 7 + Spring Boot Application Hello World Example
Angular 7 + Spring Boot Application CRUD Example
Angular 7 + Spring Boot Application Login Example
Angular 7 + Spring Boot Application Basic Authentication Example
Angular 7 + Spring Boot Basic Auth Using HTTPInterceptor Example
视频
此教程在以下 Youtube 视频中解释。
使用 Spring Boot 进行基本身份验证
在之前的教程中,我们已经为执行 CRUD 操作实现了 Spring Boot REST API。在本教程中,我们将为此应用程序添加基本身份验证。我们将修改我们在之前的教程中开发的代码。Maven 项目如下所示 -
pom.xml 定义如下
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.javainuse</groupId>
<artifactId>angular-spring</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency> </dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
接下来,我们配置 Spring Security,以利用内存身份验证。此外,我们允许允许 OPTIONS 调用。这些 OPTIONS 调用是由 Angular 应用程序发出的,用于 Spring Boot 应用程序。此外,在此处我们禁用了 csrf。之前的 Spring Boot Security — Enabling CSRF Protection Tutorial 中我们已经看到了什么是 csrf。
package com.javainuse;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable(). authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll().anyRequest().authenticated()
.and().httpBasic();
} @Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("javainuse").password("{noop}password").roles("USER");
}
}
定义一个用户模型类。当其用户使用用户名和密码尝试登录时,将返回此用户对象。仅当基本身份验证凭据正确时,控制器才会返回此对象。
package com.javainuse.model;public class User {
private String status; public User(String status) {
this.status = status;
} public String getStatus() {
return status;
} public void setStatus(String status) {
this.status = status;
}}
在控制器中,我们定义另一个 REST API 以返回用户对象。
package com.javainuse.controller;import java.util.ArrayList;
import java.util.List;import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import com.javainuse.model.User;
import com.javainuse.model.Employee;@CrossOrigin()
@RestController
@RequestMapping({ "/employees" })
public class TestController { private List<Employee> employees = createList(); @GetMapping(produces = "application/json")
public List<Employee> firstPage() {
return employees;
}
@GetMapping(produces = "application/json")
@RequestMapping({ "/validateLogin" })
public User validateLogin() {
return new User("User successfully authenticated");
} @DeleteMapping(path = { "/{id}" })
public Employee delete(@PathVariable("id") int id) {
Employee deletedEmp = null;
for (Employee emp : employees) {
if (emp.getEmpId().equals(id)) {
employees.remove(emp);
deletedEmp = emp;
break;
}
}
return deletedEmp;
} @PostMapping
public Employee create(@RequestBody Employee user) {
employees.add(user);
return user;
} private static List<Employee> createList() {
List<Employee> tempEmployees = new ArrayList<>();
Employee emp1 = new Employee();
emp1.setName("emp1");
emp1.setDesignation("manager");
emp1.setEmpId("1");
emp1.setSalary(3000); Employee emp2 = new Employee();
emp2.setName("emp2");
emp2.setDesignation("developer");
emp2.setEmpId("2");
emp2.setSalary(3000);
tempEmployees.add(emp1);
tempEmployees.add(emp2);
return tempEmployees;
}
}
在 Angular 方面实现基本身份验证的更改
我们将修改我们在之前的教程中开发的代码。我们将开发的 Angular 项目如下所示 -
在 http-client.service.ts 中,我们将在进行 REST 调用之前添加基本身份验证标头。
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';export class Employee{
constructor(
public empId:string,
public name:string,
public designation:string,
public salary:string,
) {}
}@Injectable({
providedIn: 'root'
})
export class HttpClientService { constructor(
private httpClient:HttpClient
) {
} getEmployees()
{
let username='javainuse'
let password='password'
const headers = new HttpHeaders({ Authorization: 'Basic ' + btoa(username + ':' + password) });
return this.httpClient.get<Employee[]>('http://localhost:8080/employees',{headers});
}
public deleteEmployee(employee) {
let username='javainuse'
let password='password'
const headers = new HttpHeaders({ Authorization: 'Basic ' + btoa(username + ':' + password) });
return this.httpClient.delete<Employee>("http://localhost:8080/employees" + "/"+ employee.empId,{headers});
} public createEmployee(employee) {
let username='javainuse'
let password='password'
const headers = new HttpHeaders({ Authorization: 'Basic ' + btoa(username + ':' + password) });
return this.httpClient.post<Employee>("http://localhost:8080/employees", employee,{headers});
}
}
以前的 authentication.service.ts 用于检查凭据是否与硬编码值匹配。现在,我们将使用基本身份验证标头进行 REST 调用。只有返回 User 对象,登录才会成功。
import { Injectable } from '@angular/core';
import { HttpClientService } from './http-client.service';
import { HttpClient,HttpHeaders } from '@angular/common/http';
import { map } from 'rxjs/operators';export class User{
constructor(
public status:string,
) {}
}@Injectable({
providedIn: 'root'
})
export class AuthenticationService {
constructor(
private httpClient:HttpClient
) {
} authenticate(username, password) {
const headers = new HttpHeaders({ Authorization: 'Basic ' + btoa(username + ':' + password) });
return this.httpClient.get<User>('http://localhost:8080/employees/validateLogin',{headers}).pipe(
map(
userData => {
sessionStorage.setItem('username',username);
return userData;
}
) );
} isUserLoggedIn() {
let user = sessionStorage.getItem('username')
console.log(!(user === null))
return !(user === null)
} logOut() {
sessionStorage.removeItem('username')
}
}
在 login.service.ts 中,我们检查身份验证服务是否返回有效用户。如果是,则登录成功,并将用户转发到员工页面。
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { AuthenticationService } from '../service/authentication.service';@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit { username = ''
password = ''
invalidLogin = false constructor(private router: Router,
private loginservice: AuthenticationService) { } ngOnInit() {
} checkLogin() {
(this.loginservice.authenticate(this.username, this.password).subscribe(
data => {
this.router.navigate([''])
this.invalidLogin = false
},
error => {
this.invalidLogin = true }
)
); }}
现在,如果我们转到 localhost:4200/login。使用凭据登录 - 用户名='javainuse',密码='password'。将使用基本身份验证对用户进行身份验证,并将其转发到员工页面。
译自:https://medium.com/@rameez.s.shaikh/angular-7-spring-boot-basic-authentication-example-98455b73d033
评论(0)