首页
Preview

Angular 7 + Spring Boot 基本身份验证示例

在上一个教程中,我们实现了 — 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

版权声明:本文内容由TeHub注册用户自发贡献,版权归原作者所有,TeHub社区不拥有其著作权,亦不承担相应法律责任。 如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

点赞(0)
收藏(0)
阿波
The minute I see you, I want your clothes gone!

评论(0)

添加评论