使用AngularJS和Spring Boot的Post基本认证语义
Post Basic Authentication semantics with AngularJS and Spring Boot?
我正在通读下面的教程。AngularJS的导航控制器在页面加载时触发,其中包括执行一个验证函数,如下所示:
var authenticate = function(credentials, callback) {
var headers = credentials ? {
authorization: "Basic " +
btoa(credentials.username + ":" + credentials.password)
} : {};
$http.get('user', {
headers: headers
}).then(function(response) {
if (response.data.name) {
$rootScope.authenticated = true;
} else {
$rootScope.authenticated = false;
}
callback && callback();
}, function() {
$rootScope.authenticated = false;
callback && callback();
});
}
函数被这样调用:authenticate()
因此没有传递凭据或回调,因此在页面加载时身份验证显然没有成功。这样调用它的原因是在登录后浏览器刷新的情况下。所以我的问题是这个函数如何成功地将$rootScope.authenticated
设置为真正的登录后,因为IIUC的基本身份验证headers
值与ajax请求发送(行$http.get('user', {headers : headers}
)将是{}
。Spring是否会简单地让请求通过,因为用户已经经过身份验证,这是因为Authentication Basic
标头是在表单身份验证后设置的吗?
这里的重点是Spring Boot(实际上是Spring Security)在成功认证后在后端创建一个HttpSession
。
实际上,后端是有状态的,因为它在服务器端保留会话数据(身份验证的用户)。客户端(这里是浏览器)由提供的会话id标识。
从协议的角度来看,身份验证流是这样的。
用例:浏览器向后端发起HTTP调用:后端响应Unauthorized
,因为客户端试图访问受保护的资源而没有Authorization
头
$ curl -I -H "X-Requested-With:XMLHttpRequest" http://localhost:8080/user
HTTP/1.1 401
Set-Cookie: XSRF-TOKEN=b1137571-5e15-491c-8df5-9db5d34f29a8;path=/
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Transfer-Encoding: chunked
用例:抢占式基本身份验证。后端授予对资源的访问权限,并通知客户端会话id
$ curl -I -H "X-Requested-With:XMLHttpRequest" -H "Authorization:Basic dXNlcjpwYXNzd29yZA==" http://localhost:8080/user
HTTP/1.1 200
Set-Cookie: XSRF-TOKEN=ef72f0b8-4262-4ea2-8a46-5f7e19558079;path=/
Set-Cookie: JSESSIONID=52B61923DE639EE339A653845FBFC5F2;path=/;HttpOnly
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type : application/json;charset=UTF-8
Content-Length: 343
由于浏览器通过HTTP头Authorization
发送有效的用户凭据,后端创建一个新的HttpSession
并向浏览器发送一个标识符(会话id)
Set-Cookie: JSESSIONID=52B61923DE639EE339A653845FBFC5F2;path=/;HttpOnly
现在,浏览器自动将Cookie
标头附加到每个后续的HTTP调用中
Cookie: JSESSIONID=52B61923DE639EE339A653845FBFC5F2
防止新的身份验证周期。只要会话在服务器端没有超时,服务器就会将会话数据"分配"给这个特定的HTTP请求。
基本认证并不局限于Spring Boot (Spring Security)和Angular。它是多年来Internet的标准化认证方案。
请记住,基本身份验证是一种老式的身份验证方案,在现代web应用程序中非常不受欢迎。
Spring是否会让请求通过,因为用户已经通过了身份验证,这是因为身份验证基本头是在表单身份验证后设置的吗?
关于上面的例子,你现在可以理解为什么一个空的headers
对象不会导致拒绝。
- 浏览器(Angular应用)用有效的用户凭证设置了
Authorization
头抢占,并向受限资源发起HTTP请求 - 服务器验证用户凭据,创建由会话id标识的
HttpSession
并将其发送回浏览器 - 浏览器自动将会话id作为cookie附加到后续的每个HTTP请求中
- 服务器通过会话id识别HTTP请求并接受传入请求
如果你指示Spring Security不在服务器上创建会话会发生什么?为此,在
后面添加.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
to SecurityConfiguration::configure
.
现在,您可以看到示例中对/resource
的每次调用都会导致HTTP 401,因为服务器上不再有会话。现在,Angular应用必须自己在每个HTTP请求上设置Authorization
标头。
浏览器也可以自动附加Authorization
标头。为简洁起见,我将跳过这部分。请记住,基本身份验证在现代web应用程序中是非常不鼓励的。
这个例子的目的不是向你展示如何用Spring Boot和Angular实现登录。其主要目的是在微服务架构中,将原始登录进化为基于OAuth2和Spring的单点登录。
不要认为代码示例是理所当然的。
- 语义ui如何使用javascript启用或禁用下拉列表
- 语义ui表单验证:图像url
- Dropbox oauth认证的IF语句的第二部分是't已触发
- 语义UI中格式化的工具提示
- Meteor.js可以'找不到语义:ui包
- Template.subscriptionReady和语义UI Accordion模块
- Getstream.io"未认证”;带有只读令牌
- JavaScript引用html5语义标记
- 语义UI下拉选项数据属性
- 关于验证和语义标记的一些基本HTML5问题
- 语义UI动态下拉菜单重新初始化问题
- "缺少认证令牌”;当使用AWS apigclient(带凭据)时
- 基于语义UI的页面在Tide SDK中无法正常工作
- 语义 UI 手风琴获取打开事件中打开的项目的索引
- 语义错误为Angular 2编写NgMatchers打字脚本
- jquery html()编写函数以包含语义html元素
- javascript+语义ui:垂直菜单与项目之间的对话框,如何
- 如何使用语义ui模态
- 具有输入类型文件字段的语义UI重置表单
- 使用AngularJS和Spring Boot的Post基本认证语义