国嵌视频第二季之ARMl裸机开发

国嵌视频第二季之ARM裸机开发

 开发板的介绍

s3c2440

处理器 2440

norflash 2M

nandflash 256M

RAM64M

lcd3.5寸

 

烧写linux系统顺序先使用J-LINK在windows上烧写boot-loader,再通过linux中的usb和windows的串口配合(v-k-y)依次烧写boot-loader,kernel和镜像。

 

 交叉编译

       

一、常见交叉工具

1、交叉编译器

arm-linux-gcc -o output-filename filename

arm-linux-gcc -g -o led.o -c led.c

arm-linux-gcc 是专门用来调试在arm平台下可运行文件交叉编译工具。

2、交叉链接器

arm-linux-ld -Tled.lds -o led.elf led.o

        扩展 连接器脚本

每一个链接过程都是由链接脚本(一般以lds作为文件的后缀名)控制。链接器脚本主要用于规定如何把输入文件内的section放入输出文件内,并控制输出文件内各部分在程序地址空间内的布局。但你也可以用连接的命令做一些其他的事。

脚本格式

一下脚本将输出文件的textsection 定位在0x10000,data section 定位在0x80000000;

SECTIONS

{

.=0X10000

.text ALIGN(4):

{

*(.text)

}

.=0x8000000

.dataALIGN(4):

{

*(.data)

}

.bssALIGN(4):

{

*(.bss)

}

}

3、交叉转换器

arm-linux-objcopy被用来复制一个目标文件的内容到另一个文件中,可用于不用源文件之间的格式转换

例:arm-linux-objcopy-o binary elf_file bin_file

4、交叉文件工具

arm-linux-readelf 用来显示elf格式可执行文件的信息

5、交叉反汇编器

arm-linux-objdump 用来显示二进制文件信息,查看反汇编代码

例:arm-linux-objdump-D elf_file >dis_file 或

arm-linux-objdump -D -b binary -m arm bin_file >dis_file

 

 

二、Makefile 工程管理

一般来说,无论是C、C++、还是pas,首先要把源文件编译成中间代码文件,在Windows下也就是.obj文件,UNIX下是.o文件,即Object file,这个动作叫做编译(compile)。然后再把大量的Object File合成执行文件,这个动作叫做链接(link)。

编译时,编译器需要的是语法的正确,函数与变量的声明的正确。

链接时,主要是链接函数和全局变量。

1、介绍

make命令执行时,需要一个Makefile文件,以告诉make命令需要怎样的去编译和连接程序。

2、规则

目标(target):依赖(prerequires)

命令(command)

注意:每个命令行前面必须是一个Tab字符进行缩减。

3、使用变量简化

edit:main.ocommand.o display.o insert.o editmain.o 或

object=main.ocommand.o display.o insert.o editmain.o

edit:$(object)

4、在目录中删除文件的规则

.PHONY :clean

clean:-rmedit$(objects)

5、makefile 注释

 Makefile只有行注释,和UINX的shell脚本一样,其注释使用‘#’,可以用反斜杠进行转义。

 

  ARM工作模式

http://www.cnblogs.com/zzx1045917067/archive/2012/11/26/2789736.html

 ARM7<ARM9<ARM11<Cortex-A5<Cortex-A8<Cortex-A9

 ARM与Cortex-A5都是一个指令架构。

 一、存储格式

大端格式:高字节在低地址,低字节在高地址

小端格式:高字节在高地址,低字节在低地址

指令长度:

ARM微处理器的指令长度是32位,也可以为16位(thumb状态下)。Arm位处理器中支持字节(8位),半字(16位),字(32位)三种数据类型,其中,字需要4字节对齐,半字节需要2字节对齐。

ARM体系的CPU有两种工作状态

1 ARM状态:处理器执行32位的字对齐的ARM指令

2 Thumb状态:处理器执行16位的、半字对齐的Thumb指令

thumb指令集是arm指令集的一个子集,是针对代码密度问题而提出的,它具有16位的代码宽度。thumb不是一个完整的体系结构,不能指望处理器只执行thumb指令集而不支持arm集。

 二、 ARM处理器的7种工作模式

用户模式(usr),快速中断模式(fiq),外部中断模式(irq),管理模式(svc),中止模式(abt),未定义模式(und),系统模式(sys)。

处理器模式的切换方式:

  软件控制进行切换(被动切换)

  通过外部中断和异常进行切换(主动切换)

三、ARM寄存器概述

ARM处理器v4及以上版本有37个32位的寄存器,其中31个为通用寄存器,6个为状态寄存器。

R13----栈指针寄存器,用于保存堆栈指针

栈区(Stack)--由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式方式类似于数据结构中的栈。

堆区(heap)--一般有程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式类似于链表。

R14---程序连接寄存器,当执行BL子程序调用指令时,R14中得到R15的备份,而当发生中断或异常时,R14保存R15的返回值。

R15---程序计数器

快速中断模式有七个备份寄存器R8-R14,这使得进入快速中断模式执行很大部分程序时,甚至不需要保存任何寄存器;其他特权模式都含有两个独立的寄存器副本R13、R14,这样可以令每个模式都拥有自己的堆栈指针和连接寄存器。

当前程序状态寄存器(CPSR)

CPSR中各位意义如下:

T位:1---CPU处于Thumb状态,0---CPU处于ARM状态

I、F(中断禁止位):1---禁止中断,0---中断使能

四、模式切换

当异常发生,CPU进入相应的异常模式时,以下工作是由CPU自动完成的

1、在异常模式的R14中保存前一工作模式的下一条即将执行的指令地址

2、将CPSR的值复制到异常模式的SPSR中;

3、将CPSR的工作模式设为该异常模式对应的工作模式;

4、令PC值等于这个异常模式在异常向量表中的地址,即跳转去执行异常向量表中的相应指令;

从异常工作模式退回到之前的工作模式时,需要软件来完成以下工作:

1、将异常模式的R14减去一个适当的值(4或8)后赋给PC寄存器;

2、将异常模式SPSR的值赋给CPSR。

 

 ARM汇编

一、汇编程序框架

一般框架

.section    .data

<初始化的数据>

.section    .bss

<为初始化的数据>

.section    .text

.global _start

_start:

<汇编代码>

 

简化之后

.text

.global _start

start:

<汇编代码>

 

ARM指令

一、算术和逻辑指令

mov  目的操作数,源操作数

将源操作数(立即数或者地址上的数据)传送给目的操作数(地址)

 

mvn 目的操作数,源操作数

将源操作数(立即数或者地址上的数据)取反传送给目的操作数(取反)

 

sub ax,bx

就是ax中的值减bx中的值 ,把结果放在ax中

 

add ax,bx

将ax与bx相加,然后把结果放在ax中

 

and ax,bx

将ax与bx相与,然后把结果放在ax中

 

bic Rd,Rn,operand2

将Rn的值与操作数opreand2的反码按位逻辑“与”,结果存放在目的寄存器Rd中

 

二、比较指令

cmp 操作对象1,操作对象2

计算操作对象1-操作对象2,但不保存结果,只是根据结果修改相应的标志位

 

tst  操作数1,操作数2

数据处理指令,用于把一个寄存器的内容和另一个寄存器的内容或立即数进行按位的与运算,并根据运算的结果更新CPSR中条件标志位的值

 

三、跳转指令

bl是arm汇编中用来调用子程序的指令,它把BL后面的一条指令的地址放在R14寄存器里,R15寄存器(PC当前指针地址)就设置成要跳往的地址。这样在这个子程序返回时,再mov PC,R14 就可以返回到BL后面的地址了。B是直接mov PC,目标地址;而不保存其后的地址到R14。

                

四、移位指令

lsl

mov r0,r1,lsl#2 ;将R1中的内容左移两位后传送到R0中

 

ror

mov r0,r1,ror#2;将r1中的内容循环右移两位后传送到r0中

 

五、程序状态字访问指令

mrs 与msr配合使用,作为更新psr的读-修改-写序列的一部分

mrs r0,cpsr   ;将cpsr中的内容传送至r0

mrs cpsr, r0  ;将cpsr中的内容传送至r0

 

六、存储器访问指令

ldr r0,0x12344563 ;就是把0x12344563这个地址中的值存放在r0中

 

str  源寄存器,<存储器地址>

str指令用于从源寄存器中将一个32位的字数据传送到存储器中。

例: str r0,[r1],#8  ;将r0中的字数据写入以r1为地址的存储器中,并将新地址r1+8写入r1

str r0,[r1,#8]   ;将r0中的字数据写入以r1+8为地址的存储器中

ARM伪指令

      ARM机器码

汇编语言-(汇编器)>机器码-(运行在)>芯片

 

一、定义类伪指令

global   定义全局变量,该伪指令的含义是让global过的符号对链接器可见,也就是说,一个函数或者变量,通常情况下只在本文件内有效,当需要在外部引用该文件里的某一个函数或变量时,必须首先将该函数或变量使用global伪指令进行声明。

ascii          该伪指令用于在内存中定义字符串,我们要输出到串口中的字符串“helloworld\n”就是由它定义的。

byte        定义一个字节的变量

word         定义一个字的变量

data          将一个内部RAM的地址赋给指定的符号名

equ            相当于C中的宏定义

align          更新位置计数器的值,使代码对齐到某一边界。

 

指令与伪指令的区别

      指令是在执行阶段发挥作用的,由cpu(Intel、AMD等)来执行。

      伪指令是在编译阶段发挥作用的,由汇编器(MASM、TASM等)来解释

     

协处理器访问指令

      协处理器用于执行特定的处理任务。ARM可支持多达16个协处理器,其中CP15是最重要的一个。

 

 

 

Bootloader设计蓝图

 

一、bootloader作用

 

U-Boot是用于多种嵌入式CPU(MIPS X86ARM等)的bootloader程序,U-boot不仅支持嵌入式linux系统的引导,还支持VxWorks,QNX等多种嵌入式操作。

 

二、U-boot的设计框架

                            ----   以2440为例

    第一阶程序设计包括核心初始化(设置中断向量表、设置处理器为svc模式、关闭看门狗、关闭所有中断、关闭mmu和cache)C语言编程环境设置(设置堆栈和清除bss段)、led初始化、初始化系统时钟、进行内存初始化、复制nand flash 中的bl到内存中(简单初始化nand flash、复制代码到内存、跳转到第二阶段入口)

    第二阶程序设计包括mmu初始化、中断初始化(中断初始化、按键初始化)、初始化串口(串口初始化、移植printf函数)、网卡初始化、LCD初始化(触摸屏初始化、LCD初始化)、解析执行用户命令(移植tftp命令、移植bootm命令)

核心初始化

一、    异常向量表

1、    概念解析

异常定义:因为内部或者外部的一些事件导致处理器停下正在处理的工作,转而去处理这些发生的事件。

 

2、    ARM处理器支持7种类型的异常

用户模式、快速中断模式、外部中断模式、特权模式、数据访问中止模式、未定义指令终止模式、系统模式。

3、    异常向量

当一种异常发生的时候,ARM处理器会跳转到相应异常的固定地址去执行异常处理程序,而这个固定的地址,就称为异常向量。

 

           二、看门狗

watchdog一般是一个硬件模块,其作用就是在系统死机时,帮助系统实现自动重启。watchdog在硬件上实现了计时功能,启动计时后,用户(软件)必须在计时结束后重新开始计时,俗称“喂狗”,如果超时的时候还没有重新开始计时,那么它认为系统是死机了,就自动重启系统。

           三、mmu与cache

                 

cache是一种容量小但存取速度非常快的存储器,它保存在近用到的存储器中的数据的拷贝。

对于程序员来说,Cache是透明的。它自动决定保存那些数据,覆盖那些数据。按照功能划分:

I-Cache:指令cache,用于存放指令

D-Cace:数据cache,用于存放数据

   mmu是Memory Management Unit的缩写,中文名是内存管理单元,他是中央处理器中用来管理虚拟存储器、物理存储器的控制线路,同时也负责虚拟地址映射为物理地址,以及提供硬件机制的内存访问授权,多用户多进程系统。

 

时钟初始化

1、时钟脉冲信号定义

按一定的电压幅度 ,一定的时间间隔连续发出的脉冲信号 。时钟脉冲信号是时序逻辑的基础 ,它用于决定逻辑单元中的状态何时更新 。数字芯片中众多的晶体管都工作在开关状态 ,它们的导通和关断动作无 不是按照时钟信号的节奏进行的。

2、时钟脉冲信号频率

在单位时间(如一秒)内产生的时钟脉冲个数。

3、信号的产生

1.     晶振

2.     锁相环PLL,PLL合成器是一种更为复杂的系统时钟源。通常PLL合成器需要一个外部晶体并包含一个能够对晶体的特定频率加倍或者分频的集成锁相环(PLL)电路。

4、2440时钟体系

       S3C 2440可以使用外部晶振(XTIpll)(默认为12MHZ)和外部时钟(EXTCLK)两种方式输入时钟信号。它由跳线OM[3:2]决定。S3C2440默认主频为12MHZ。

 

S3C2440使用的内存为SDRAM。

 

C语言环境初始化

         C语言所需关键点就是堆与栈。

         栈是一种具有先进后出的数据组织方式。栈低是第一个进站栈的数据所处的位置,栈顶是最后一个进栈的数据所处的位置。如下图所示。

       根据SP指针所指向的位置,栈可以分为满栈和空栈。

1、满栈:当堆栈指针SP总是指向最后压入堆栈的数据。

2、空栈:当堆栈指针SP总是指向下一个将要放入数据的空位置。

3、ARM采用满栈。

 

栈作用:保存局部变量、参数传递、保存寄存器值。

内存分配中的堆与栈

一般情况下程序放在Rom或Flash中,运行时需要拷贝到内存中执行。内存中的栈区处于相对较高的地址并以地址的增长方向为上的话,栈地址是向下增长的。栈中分配局部变量空间,堆区是向上增长的用于分配程序员申请的内存空间。另外还有静态区分配静态变量,全局变量空间的;只读区是分配常量和程序代码空间的;以及其他的一些分区。

 

来看一个网上很流行的经典例子

main.cpp

int a=0;//全局初始化区

char *p1;//全局未初始化区

main()

{

int b;//栈

char s[]=”abc”;//栈

char*p2;//栈

char *p3=“1234567”;//1234567\0在常量区,p3在栈上

static int c=0;//全局(静态)初始化区

p1 = (char*)malloc(10);//堆

p2 = (char*)malloc(20);//堆

}

 

堆与栈有以下几点不用

1、申请方式与回收方式不同

栈区(Stack)--由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式方式类似于数据结构中的栈。

堆区(heap)--一般有程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式类似于链表。

2、申请后系统的响应

栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。

堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统受到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆。

3、申请大小的限制

在windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶地址和栈的最大容量是系统预先规定好的,在windows下,栈的大小是2M(也有人说是1M)。由于栈的大小有限,所以子函数还是有物理意义的,而不仅仅是逻辑意义。

 

C与汇编混合编程

         为什么需要混合编程

1、  执行效率

2、  能够更直接的控制处理器

 

C与汇编混合编程有三种方式

1、  汇编调用C函数

2、  C调用汇编函数

3、  C内嵌汇编

 

C内嵌汇编—格式

 

__asm__(

汇编语句部分

:输出部分

:输入部分

:破坏描述部分

);

例:

voidwrite_p15_c1 (unsigned long value)

{

__asm__volatile(

“mcr p15, 0, %0, c1,c0, 0\n”

:

:

: “r” (value)

:"memory");

}

使用volatile来告诉编译器不要对接下来这部分代码进行优化。

 

2012年10月15日星期一亲测可以下载 公开视频光盘目录结构 国嵌视频1.iso -学习方法与课程体系介绍(学前必看) -学习方法介绍.avi -国嵌嵌入式课程体系.pdf -嵌入式Linux学习方法.pdf -国嵌课程1-嵌入式入门体验班(上) -第1天(嵌入式系统概述) -国嵌体验入门班-1-1(嵌入式系统概述).avi -国嵌体验入门班-1-2(ARM概述).avi -国嵌体验入门班-1-3(嵌入式Linux概述).avi -国嵌体验入门班-1-4(2440开发板介绍).avi -国嵌体验入门班-1-5(软硬件环境搭建).avi -第2天(开发板快乐体验) -国嵌体验入门班-2-1(开发板系统安装).avi -国嵌体验入门班-2-1(开发板系统安装-Jlink方式).avi -国嵌体验入门班-2-1(开发板系统安装-并口方式).avi -国嵌体验入门班-2-2(裸机程序体验).avi -国嵌体验入门班-2-3(QT系统体验).avi -国嵌体验入门班-2-4(Android系统体验).avi 国嵌视频2.iso -国嵌课程1-嵌入式入门体验班(下) -第3天(Linux系统体验) -国嵌体验入门班-3-1(Linux定制安装).avi -国嵌体验入门班-3-2(Linux命令).avi -国嵌体验入门班-3-3(VI使用).avi -国嵌体验入门班-3-4(Linux系统管理).avi -国嵌体验入门班-3-5(Shell编程).avi -国嵌体验入门班-3-6(Qcd功能演示).avi -国嵌体验入门班-3-7(必修实验).avi -国嵌课程2-嵌入式Linux应用开发班 -第1天(编程基础) -国嵌应用班-1-1(GCC程序编译).avi -国嵌应用班-1-2(GDB程序调试).avi -国嵌应用班-1-3(makefile工程管理).avi -国嵌应用班-1-4(必修实验).avi -第2天(文件时间编程) -国嵌应用班-2-1(系统调用方式访问文件).avi -国嵌应用班-2-2(库函数访问文件).avi -国嵌应用班-2-3(时间编程).avi -国嵌应用班-2-4(必修实验).avi -第3天(多进程程序设计) -国嵌应用班-3-1(进程控制原理).avi -国嵌应用班-3-2(进程控制程序设计).avi -国嵌应用班-3-3(必修实验).avi -第4天(进程间通讯) -国嵌应用班-4-1(进程间通讯概述).avi -国嵌应用班-4-2(管道通讯).avi -国嵌应用班-4-3(信号通讯).avi -国嵌应用班-4-4(共享内存通讯).avi -国嵌应用班-4-5(必修实验).avi -第5天(进程间通讯) -国嵌应用班-5-1(消息队列).avi -国嵌应用班-5-2(信号量).avi -国嵌应用班-5-3(必修实验).avi -第6天(进程间通讯) -国嵌应用班-6-1(线程基础).avi -国嵌应用班-6-2(多线程程序设计).avi -国嵌应用班-6-3(必修实验).avi -第7天(网络编程) -国嵌应用班-7-1(Linux网络概述).avi -国嵌应用班-7-2(Linux网络编程基础).avi -国嵌应用班-7-3(TCP程序设计).avi -国嵌应用班-7-4(UDP网络程序设计).avi -国嵌应用班-7-5(并发服务器).avi -国嵌应用班-7-6(必修实验).avi 国嵌视频3.iso -国嵌课程3-ARM系统进阶班 -第1天(ARM系统开发基础) -ARM系统精讲班-1-1(ADS集成开发环境).avi -ARM系统精讲班-1-2(ARM工作模式).avi -ARM系统精讲班-1-3(ARM寄存器).avi -ARM系统精讲班-1-4(ARM寻址方式).avi -ARM系统精讲班-1-5(ARM汇编指令详解).avi -第2天(ARM系统开发基础) -ARM系统精讲班-2-1(ARM汇编指令详解).avi -ARM系统精讲班-2-2(ARM伪指令).avi -ARM系统精讲班-2-3((混合编程).avi -ARM系统精讲班-1-8(必修实验).avi -第3天(LED驱动程序设计) -ARM系统精讲班-2-1(GPIO).avi -ARM系统精讲班-2-2(LED控制程序设计).avi -ARM系统精讲班-2-3((LED闪烁).avi -第4天(LED与按键驱动程序设计) -ARM系统精讲班-4-1(ARM中断控制系统).avi -ARM系统精讲班-4-2(按键控制程序设计).avi -ARM系统精讲班-2-6(必修实验).avi -第5天(定时器与时钟驱动程序设计) -ARM系统精讲班-5-1(ARM时钟体系).avi -ARM系统精讲班-5-2(定时器驱动程序设计).avi -国嵌课程4(嵌入式LINUX内核驱动进阶班-上) -第1天(内核开发基础) -国嵌内核驱动进阶班-1-1(Linux内核简介).avi -国嵌内核驱动进阶班-1-2(Linux内核源代码).avi -国嵌内核驱动进阶班-1-3(Linux内核配置与编译).avi -国嵌内核驱动进阶班-1-4(Linux内核模块开发).avi -国嵌内核驱动进阶班-1-5(必修实验).avi -第2天(U-Boot移植) -国嵌内核驱动进阶班-2-1(嵌入式linux系统架构).avi -国嵌内核驱动进阶班-2-2(交叉工具链).avi -国嵌内核驱动进阶班-2-3(Bootloader介绍).avi -国嵌内核驱动进阶班-2-4(U-Boot介绍).avi -国嵌内核驱动进阶班-2-5(U-Boot命令).avi -国嵌内核驱动进阶班-2-6(U-Boot启动流程).avi -国嵌内核驱动进阶班-2-7(Uboot移植).avi -国嵌内核驱动进阶班-2-8(必修实验).avi 国嵌视频4.iso -国嵌课程4(嵌入式LINUX内核驱动进阶班-下) -第3天(内核开发基础) -国嵌内核驱动进阶班-3-1(嵌入式linux内核制作).avi -国嵌内核驱动进阶班-3-2(根文件系统制作).avi -国嵌内核驱动进阶班-3-3(内核启动流程).avi -国嵌内核驱动进阶班-3-4(嵌入式文件系统).avi -国嵌内核驱动进阶班-3-5(必修实验).avi -第4天(内存管理子系统) -国嵌内核驱动进阶班-4-1(Linux内存管理).avi -国嵌内核驱动进阶班-4-2(进程地址空间).avi -国嵌内核驱动进阶班-4-3(内核地址空间).avi -国嵌内核驱动进阶班-4-4(Linux内核链表).avi -国嵌内核驱动进阶班-4-5(Linux内核定时器).avi -国嵌内核驱动进阶班-2-7(Uboot移植).avi -国嵌内核驱动进阶班-2-8(必修实验).avi -第5天(进程管理子系统) -国嵌内核驱动进阶班-5-1(LINUX进程控制).avi -国嵌内核驱动进阶班-5-2(LINUX进程调度).avi -国嵌内核驱动进阶班-5-3(Linux系统调用).avi -国嵌内核驱动进阶班-5-4(Proc文件系统).avi -国嵌内核驱动进阶班-5-5(内核异常分析).avi -国嵌内核驱动进阶班-5-6(必修实验).avi -第6天(简单字符设备驱动程序设计) -国嵌内核驱动进阶班-6-1(LINUX驱动程序介绍).avi -国嵌内核驱动进阶班-6-2(字符设备驱动程序设计).avi -国嵌内核驱动进阶班-6-3(字符设备驱动程序实例分析).avi -国嵌内核驱动进阶班-6-4(竞争与互斥).avi -国嵌内核驱动进阶班-6-5(必修实验).avi -第7天(高级字符设备驱动程序设计) -国嵌内核驱动进阶班-7-1(Ioctl设备控制).avi -国嵌内核驱动进阶班-7-2(内核等待队列).avi -国嵌内核驱动进阶班-7-3(阻塞型字符设备驱动).avi -国嵌内核驱动进阶班-7-4(Poll设备方法).avi -国嵌内核驱动进阶班-7-5(自动创建设备文件).avi -国嵌内核驱动进阶班-7-6(必修实验).avi
SpringCloud Gateway可以通过Spring Security来实现SAML2认证,下面是一个简单的案例: 1. 添加依赖 在pom.xml中添加以下依赖: ``` <dependency> <groupId>org.springframework.security.extensions</groupId> <artifactId>spring-security-saml2-core</artifactId> <version>1.0.10.RELEASE</version> </dependency> ``` 2. 配置SAML2认证 在Spring Security配置中添加以下内容: ``` @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private SAMLUserDetailsService samlUserDetailsService; @Autowired private SAMLAuthenticationProvider samlAuthenticationProvider; @Autowired private SAMLConfigurer samlConfigurer; @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers("/saml/**").permitAll() .anyRequest().authenticated() .and() .apply(samlConfigurer); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(samlAuthenticationProvider); } @Bean public SAMLConfigurer samlConfigurer() { return new SAMLConfigurer(); } @Bean public SAMLUserDetailsService samlUserDetailsService() { return new SAMLUserDetailsServiceImpl(); } @Bean public SAMLAuthenticationProvider samlAuthenticationProvider() { SAMLAuthenticationProvider provider = new SAMLAuthenticationProvider(); provider.setUserDetails(samlUserDetailsService()); provider.setForcePrincipalAsString(false); return provider; } } ``` 在上面的配置中,我们定义了一个SAMLUserDetailsService,用于获取SAML认证信息中的用户信息,同时也定义了一个SAMLAuthenticationProvider,用于对SAML认证信息进行认证。 3. 配置SAML2元数据 在application.yml中添加以下内容: ``` spring: security: saml2: metadata-url: http://idp.example.com/metadata entity-id: https://gateway.example.com/saml/metadata signing-key: | -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAyeFw4C4LJ8aRmL2QGnSvSfWb9XICdxpIzqD3tY5uVg5iZPfN ... -----END RSA PRIVATE KEY----- encryption-key: | -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAyeFw4C4LJ8aRmL2QGnSvSfWb9XICdxpIzqD3tY5uVg5iZPfN ... -----END RSA PRIVATE KEY----- verification-key: | -----BEGIN CERTIFICATE----- MIIDrjCCApagAwIBAgIGAVxQyBANBgkqhkiG9w0BAQsFADCBjTELMAkGA1UEBhMC ... -----END CERTIFICATE----- ``` 其中,metadata-url是SAML2元数据的URL,entity-id是网关的实体ID,signing-key是网关的签名密钥,encryption-key是网关的加密密钥,verification-key是SAML2提供商的验证证书。 4. 配置路由 在application.yml中添加以下内容: ``` spring: cloud: gateway: routes: - id: saml_route uri: http://backend.example.com predicates: - Path=/backend/** filters: - SAML2LoginRedirect - SAML2Login ``` 在上面的配置中,我们将请求路径为/backend/**的请求路由到后端服务,同时使用SAML2LoginRedirect和SAML2Login过滤器进行SAML2认证。 5. 配置SAML2过滤器 在SAMLConfigurer中添加以下内容: ``` public class SAMLConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> { @Autowired private SAMLUserDetailsService samlUserDetailsService; @Autowired private SAMLAuthenticationProvider samlAuthenticationProvider; @Value("${spring.security.saml2.metadata-url}") private String metadataUrl; @Value("${spring.security.saml2.entity-id}") private String entityId; @Value("${spring.security.saml2.signing-key}") private String signingKey; @Value("${spring.security.saml2.encryption-key}") private String encryptionKey; @Value("${spring.security.saml2.verification-key}") private String verificationKey; @Override public void configure(HttpSecurity http) throws Exception { SAMLConfigurerBean samlConfigurerBean = new SAMLConfigurerBean(); samlConfigurerBean.setMetadataURL(metadataUrl); samlConfigurerBean.setEntityId(entityId); samlConfigurerBean.setTlsKey(signingKey); samlConfigurerBean.setTlsKeyPassword(""); samlConfigurerBean.setTlsCert(encryptionKey); samlConfigurerBean.setVerificationCertificate(verificationKey); samlConfigurerBean.setSsoLoginURL("http://idp.example.com/login"); samlConfigurerBean.setSsoLogoutURL("http://idp.example.com/logout"); SAMLConfigurerFilter samlFilter = new SAMLConfigurerFilter(samlConfigurerBean); http.addFilterBefore(samlFilter, BasicAuthenticationFilter.class); } @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(samlAuthenticationProvider); } @Bean public SAMLConfigurer samlConfigurer() { return new SAMLConfigurer(); } @Bean public SAMLUserDetailsService samlUserDetailsService() { return new SAMLUserDetailsServiceImpl(); } @Bean public SAMLAuthenticationProvider samlAuthenticationProvider() { SAMLAuthenticationProvider provider = new SAMLAuthenticationProvider(); provider.setUserDetails(samlUserDetailsService()); provider.setForcePrincipalAsString(false); return provider; } } ``` 在上面的配置中,我们定义了一个SAMLConfigurerBean,用于配置SAML2提供商的信息,同时也定义了一个SAMLConfigurerFilter,用于对SAML2认证信息进行过滤。 6. 测试 启动应用程序并访问http://gateway.example.com/backend/test,应该会跳转到SAML2提供商的登录页面进行登录,登录成功后应该会被重定向到http://gateway.example.com/backend/test。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值