Websocket And Security

Websocket And Security1. WebSocket 基础概念
什么是 WebSocket?
WebSocket 是一种网络通信协议,提供了在单个 TCP 连接上进行全双工通信的方式。\”全双工\”意味着客户端

1. WebSocket 基础概念

什么是 WebSocket?

WebSocket 是一种网络通信协议,可通过单个TCP 连接提供全双工通信。 “全双工”是指客户端和服务器可以同时发送和接收信息,而不像传统的HTTP 请求是半双工的(即一次只能执行一个请求或响应)。

WebSocket 与 HTTP 的区别

连接持久性:HTTP 协议基于请求/响应模型,连接通常在服务器响应请求后关闭。 WebSocket 在握手后建立持久连接,直到客户端或服务器决定终止连接。实时:WebSockets支持实时数据传输。这对于需要快速响应的应用(在线游戏、实时聊天等)来说非常重要。标头大小:WebSocket 标头信息比HTTP 小,因此WebSocket 发送数据时需要的开销较小。

建立连接的过程

客户端请求:WebSocket 连接由“升级”HTTP 请求初始化。客户端发送一个特殊的HTTP 请求,其中包含Upgrade: Websocket 和Connection: Upgrade 标头。服务器响应:如果服务器支持WebSockets,则返回状态码101 Switching Protocol,表示服务器已同意协议更改。数据传输:握手完成后,可以通过此连接双向传输数据。

使用场景

实时聊天应用程序在线游戏实时数据更新(例如股票价格) 协作应用程序(例如实时文档编辑)

WebSocket URL

WebSocket URL 以ws://(未加密)或wss://(加密)开头,HTTP 以http://开头,HTTPS 以https://开头。

2. 在 Spring Boot 中使用 WebSocket

步骤 1: 添加依赖项

首先,将Spring Boot 对WebSockets 的支持添加到您的pom.xml 文件中。这通常意味着添加spring-boot-starter-websocket 依赖项。

复制xml 代码中的依赖项

依赖

groupIdorg.springframework.boot/groupId

artifactIdspring-boot-starter-websocket/artifactId

/依赖

!– 其他依赖项–

/依赖项

步骤 2: 配置 WebSocket

在Spring Boot 应用程序中创建一个配置类来启用和配置WebSocket。

@作品

@EnableWebSocketMessageBroker //启用WebSocket消息代理

公共类WebSocketConfig 实现WebSocketMessageBrokerConfigurer {

@覆盖

公共无效registerStompEndpoints(StompEndpointRegistry注册表){

//注册客户端将用于连接到WebSocket 服务器的WebSocket 端点。

registry.addEndpoint(\’/ws\’).withSockJS();

//SockJS用于兼容不支持WebSockets的浏览器

}

@覆盖

公共无效configureMessageBroker(MessageBrokerRegistry注册表){

//定义一个消息代理将消息从一个客户端路由到另一个客户端

registry.setApplicationDestinationPrefixes(\’/app\’);

//客户端将使用此前缀发送消息

registry.enableSimpleBroker(\’/topic\’);

//简单的消息代理,定义客户端可以订阅的前缀

}

}

这里,STOMP(简单文本导向消息协议)用作WebSocket的子协议。 STOMP 提供可互操作的有线格式,允许STOMP 客户端与启用STOMP 的消息代理进行交互。

步骤 3: 创建 WebSocket 控制器

接下来,创建一个控制器来处理发送到WebSocket 的消息。

@控制器

公共类WebSocketController {

@MessageMapping(\’/hello\’) //定义消息的地址

@SendTo(\’/topic/greetings\’) //定义客户端订阅的地址

公共Stringgreeting(字符串消息)抛出异常{

//当服务器收到来自“/app/hello”的消息时调用此方法

返回\’你好,\’+消息+\’!\’;

}

}

该控制器接收发送到/app/hello 的消息并将响应发送到/topic/greetings。

步骤 4: 客户端连接

在客户端,您需要使用适当的库来建立WebSocket 连接。如果您的客户端是网页,则可以使用SockJS 和STOMP 客户端库。

!DOCTYPE html

html

titleWebSocket 测试/标题

脚本src=\’https://cdn.jsdelivr.net/npm/sockjs-client/dist/sockjs.min.js\’/script

脚本src=\’https://cdn.jsdelivr.net/npm/stomp-websocket/lib/stomp.min.js\’/script

/头

身体

脚本类型=\’文本/javascript\’

var socket=new SockJS(\’/ws\’); //连接到服务器上的WebSocket 端点。

var stompClient=Stomp.over(socket) //使用STOMP 子协议。

stompClient.connect({}, 函数(框架) {

//连接成功后的回调函数

console.log(\’Connected:\’ + 框架);

stompClient.subscribe(\’/topic/greetings\’, 函数(问候语) {

//在“/topic/greetings”中注册以接收消息

警报(JSON.parse(greeting.body).content);

});

});

函数发送消息() {

stompClient.send(\’/app/hello\’, {}, JSON.stringify({\’name\’: \’yourName\’}));

//发送消息到“/app/hello”

}

/剧本

Button onclick=\’sendMessage()\’发送消息/按钮

/身体

/html

2.Spring Security安全框架

Spring Security是专门针对Java应用程序的安全框架。为基于Spring的应用程序提供全面的安全解决方案。

安全性提供了一个默认的登录页面,并在未登录的情况下拦截对此页面的所有请求。默认的登录名和密码可以在yml配置文件中更改。

弹簧:

安全:

用户:

name: 老板

密码: 123

使用顺序

创建数据库并使用Mybatis管理的dao层创建密码解析器——PasswordEncoder。

公共类MyPasswordEncode 实现PasswordEncoder {

/*

*密码加密方式

* */

@覆盖

公共字符串编码(CharSequence rawPassword){

System.out.println(\’自定义密码解析器,encode方法执行\’);

返回rawPassword.toString()。

}

/**

*如何验证密码的明文和密文是否相同

* @param rawPassword 客户端传递的纯文本密码。

* @param encodedPassword 服务器上存储的密文密码。

* @返回

*/

@覆盖

公共布尔匹配(CharSequence rawPassword,字符串编码密码){

//首先使用编码方式使用相同的加密策略对明文进行加密,然后比较密文。

返回编码(rawPassword).equals(encodedPassword);

}

/*

* 是否需要升级你的密码破解策略,强化你的密码破解策略

* */

@覆盖

公共布尔upgradeEncoding(字符串编码密码){

返回PasswordEncoder.super.upgradeEncoding(encodedPassword)。

}

}

创建一个配置类只管理这个解析器——解析器

定义登录服务类型——的方法的实现是根据用户名查询用户对象和用户权限列表。 (我的用户详细信息服务Impl)

/**

*登录服务实现类型

*/

@成分

公共类MyUserDetailsServiceImpl 实现UserDetailsService {;

@Autowired

userMapper 用户映射器;

/**

*该方法的实现根据用户名查询用户对象和用户权限列表。

* @param 用户名

* @返回

* @抛出用户名未找到异常

*/

@覆盖

公共UserDetails loadUserByUsername(字符串用户名)抛出UsernameNotFoundException {

//根据用户名查询用户

用户user=userMapper.SelectByUserName(用户名);

//判断用户是否存在

如果(用户==空)

{

throw new UsernameNotFoundException(\’用户名或密码不正确\’);

}

//返回UserDetails 接口类型的对象

org.springframework.security.core.userdetails.user 结果=

新的org.springframework.security.core.userdetails.User(

username,//登录用户的用户名

user.getPassword(),//登录用户的密码是服务器存储的密文

AuthorityUtils.NO_AUTHORITIES//工具没有提供任何权限的空集合,

);

返回结果。

}

}

安全性** 登录自动自定义验证的默认设置** 执行顺序

当登录默认页面时,sercurity会自动调用实现PosswordEndcoder接口的类的encode方法来解析密码,然后sercurity调用实现UserDetailsService接口的实现类的loadUserByUsername方法来检索用户。查询然后安全将继续。调用实现PosswordEndcoder接口的类的encode方法,确保库密码和表单密码匹配。

MySecurityConfiguration配置类的编写

@作品

@EnableWebSecurity

公共类MySecurityConfiguration {

/**

* 创建安全过滤器链对象

* @返回

*/

@豆子

public SecurityFilterChain securityFilterChain(HttpSecurity security) 抛出异常{

//登录设置类

定制器FormLoginConfigurerHttpSecurity 定制器=新定制器FormLoginConfigurerHttpSecurity(){

@覆盖

公共无效定制(FormLoginConfigurerHttpSecurity配置器){

//具体认证设置

作曲家

.loginPage(\’/登录\’)

//.defaultSuccessUrl(\’/test\’)//默认跳转地址

//.successForwardUrl(\’/test\’) //认证成功后跳转到地址

.successHandler(new MyAuthenticationsuccessHandler(\’/test\’,true))//设置认证成功后的处理代码逻辑。

.failureUrl(\’/loginfail\’)//登录失败跳转地址

;//设置登录页面访问地址。默认为/登录。必须是检索请求。定制后提供控制器+视图

}

};

//设置认证配置

安全

.formLogin(定制器);

//完成登录设置

定制器LogoutConfigurerHttpSecurity logoutCustomizer=新定制器LogoutConfigurerHttpSecurity() {

@覆盖

公共无效自定义(LogoutConfigurerHttpSecurity configLoginout){

配置退出登录

.logoutUrl(\’/logout\’)//注销请求地址

.logoutSuccessUrl(\’/login\’)//注销成功后的跳转地址是否为默认登录页面地址?

.logoutSuccessHandler(new MyLogOutsuccessHandler()) //设置注销登录成功后的处理代码

.addLogoutHandler(new MyLogOutHandler())

;

}

};

//设置注销设置

security.logout(logoutCustomizer);

安全

.authorizeRequests()

.antMatchers(\’/login\’,\’/css/**\’,\’/image/**\’,\’/loginfail\’).permitAll() //允许所有用户访问/login 路径

.anyRequest().authenticated(); //所有其他请求都需要身份验证

//关闭CSRF功能

security.csrf().disable();

返回security.build()。

}

/**

* 创建密码编码器类型的bean对象

*/

@豆子

公共密码编码器密码编码器(){

//strong哈希密码解析器。该构造方法可以传递一个范围为4到31的整数参数。数字越高,实力越高,但性能越低。

返回一个新的BCryptPasswordEncoder()。

}

}

MyAuthenticationsuccessHandler类用于处理认证成功的处理逻辑

//认证成功后的处理逻辑

公共类MyAuthenticationssuccessHandler 实现AuthenticationSuccessHandler {

//登录成功后访问的地址

私有字符串URL;

//是重定向吗?

私有布尔值是一个重定向。

公共MyAuthenticationssuccessHandler(字符串url,布尔isRedirect){

这个.url=url;

this.isRedirect=isRedirect;

}

/**

* 认证成功后具体执行代码

* @参数请求

* @参数响应

* @paramauthentication 认证成功后的用户主体对象(包含个人的登录信息和权限列表)

* @抛出IOException

* @抛出ServletException

*/

@覆盖

public void onAuthenticationSuccess(HttpServletRequest请求,HttpServletResponse响应,身份验证authentication)抛出IOException,ServletException {

if(是重定向){

//重定向

响应.sendRedirect(url);

}除此之外

//转移要求

request.getRequestDispatcher(url).forward(请求,响应);

}

}

MyLogOutHandler(登出的一般做额外处理,比如保存会话中某些attribute到数据库)

公共类MyLogOutHandler 实现LogoutHandler {

/**

* 处理逻辑

* @参数请求

* @参数响应

* @参数验证

*/

@覆盖

公共无效注销(HttpServletRequest请求,HttpServletResponse响应,身份验证){

//通常会执行额外的处理,例如将会话中的某些属性保存到数据库中。

//日志记录等

}

}

MyLogOutsuccessHandler(登出成功的处理逻辑)

公共类MyLogOutsuccessHandler 实现LogoutSuccessHandler {

/**

*注销成功后的操作

*/
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
System.out.println(\”退出登录成功后的处理\”);
//销毁会话,清空缓存
request.getSession().invalidate();//销毁会话
authentication.setAuthenticated(false);//设置未登录状态
response.sendRedirect(\”/login\”);//进行重定向
}
}

#以上关于Websocket And Security的相关内容来源网络仅供参考,相关信息请以官方公告为准!

原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/93809.html

(0)
CSDN的头像CSDN
上一篇 2024年7月26日
下一篇 2024年7月26日

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注