WebSocket和SpringSecurity的学习记录

这篇具有很好参考价值的文章主要介绍了WebSocket和SpringSecurity的学习记录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. WebSocket 基础概念

什么是 WebSocket?
  • WebSocket 是一种网络通信协议,提供了在单个 TCP 连接上进行全双工通信的方式。"全双工"意味着客户端和服务器可以同时发送和接收信息,这与传统的 HTTP 请求不同,后者是一种半双工通信方式(即一次只能进行一个请求或响应)。
WebSocket 与 HTTP 的区别
  • 连接持续性:HTTP 协议是基于请求-响应模式的,通常在请求被服务端响应后连接就会关闭。而 WebSocket 在握手后就建立了一个持久的连接,直到客户端或服务器决定关闭这个连接。
  • 实时性:WebSocket 支持实时数据传输,这对于需要快速响应的应用(如在线游戏、实时聊天等)来说非常重要。
  • 头信息大小:WebSocket 的头信息比 HTTP 小,这意味着在数据传输时,WebSocket 的开销更小。
建立连接的过程
  1. 客户端请求:WebSocket 连接是通过 HTTP 请求“升级”来初始化的。客户端发送一个特殊的 HTTP 请求,包含 Upgrade: websocketConnection: Upgrade 头信息。
  2. 服务器响应:如果服务器支持 WebSocket,则会以一个状态码 101 Switching Protocols 响应,表示服务器同意改变协议。
  3. 数据传输:一旦握手完成,数据就可以通过这个连接双向传输。
使用场景
  • 实时聊天应用
  • 在线游戏
  • 实时数据更新(如股票报价)
  • 协作应用(如实时文档编辑)
WebSocket URL
  • WebSocket URL 以 ws:// (非加密) 或 wss:// (加密) 开头,类似于 HTTP 的 http:// 和 HTTPS 的 https://

2. 在 Spring Boot 中使用 WebSocket

步骤 1: 添加依赖项

首先,在你的 pom.xml 文件中添加 Spring Boot 对 WebSocket 的支持。这通常意味着添加 spring-boot-starter-websocket 依赖。

xmlCopy code<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
    <!-- 其他依赖 -->
</dependencies>
步骤 2: 配置 WebSocket

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


@Configuration
@EnableWebSocketMessageBroker  // 启用 WebSocket 消息代理
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        // 注册一个 WebSocket 端点,客户端将使用它连接到 WebSocket 服务器。
        registry.addEndpoint("/ws").withSockJS();
        // SockJS 用于兼容不支持 WebSocket 的浏览器
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        // 定义消息代理,用于将消息从一个客户端路由到另一个客户端
        registry.setApplicationDestinationPrefixes("/app");
        // 客户端将使用此前缀发送消息
        registry.enableSimpleBroker("/topic");
        // 定义了一个简单的消息代理,客户端可以订阅的前缀
    }
}

这里使用了 STOMP(Simple Text Oriented Messaging Protocol)作为 WebSocket 的子协议。STOMP 提供了一个可互操作的线路格式,允许 STOMP 客户端与任何支持 STOMP 的消息代理进行交互。

步骤 3: 创建 WebSocket 控制器

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

@Controller
public class WebSocketController {

    @MessageMapping("/hello")  // 定义消息的地址
    @SendTo("/topic/greetings")  // 定义客户端订阅的地址
    public String greeting(String message) throws Exception {
        // 当服务器接收到 "/app/hello" 的消息时,它会调用此方法
        return "Hello, " + message + "!";
    }
}

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

步骤 4: 客户端连接

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

<!DOCTYPE html>
<html>
<head>
    <title>WebSocket Test</title>
    <script src="https://cdn.jsdelivr.net/npm/sockjs-client/dist/sockjs.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/stomp-websocket/lib/stomp.min.js"></script>
</head>
<body>
    <script type="text/javascript">
        var socket = new SockJS('/ws'); // 连接到服务器上的 WebSocket 端点
        var stompClient = Stomp.over(socket); // 使用 STOMP 子协议

        stompClient.connect({}, function (frame) {
            // 成功连接后的回调函数
            console.log('Connected: ' + frame);
            stompClient.subscribe('/topic/greetings', function (greeting) {
                // 订阅 '/topic/greetings' 以接收消息
                alert(JSON.parse(greeting.body).content);
            });
        });

        function sendMessage() {
            stompClient.send("/app/hello", {}, JSON.stringify({'name': "yourName"}));
            // 向 '/app/hello' 发送消息
        }
    </script>
    <button onclick="sendMessage()">Send Message</button>
</body>
</html>

2.Spring Security安全框架

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

security提供了一个默认的登录页面,在没有登录的情况下所有的请求都会被拦截到该页面,默认的登录名和密码是可以改的在yml配置文件中

spring:
  security:
    user:
      name: boss
      password: 123

使用顺序

  • 创建数据库
  • 使用Mybatis管理dao层
  • 创建密码解析器——PasswordEncoder
public class MyPasswordEncode implements PasswordEncoder {
    /*
    * 密码加密方法
    * */
    @Override
    public String encode(CharSequence rawPassword) {
        System.out.println("自定义密码解析器,encode方法执行");
        return rawPassword.toString();
    }

    /**
     * 校验密码明文和密文是否相同的方法
     * @param rawPassword 明文密码,客户端传递的
     * @param encodedPassword 密文密码,服务器中存储的
     * @return
     */
    @Override
    public boolean matches(CharSequence rawPassword, String encodedPassword) {

//        先使用encode方法,用相同的加密策略,加密明文,在对比密文
        return encode(rawPassword).equals(encodedPassword);
    }
    /*
     * 是否需要升级密码解析策略,强化密码解析策略
     * */
    @Override
    public boolean upgradeEncoding(String encodedPassword) {
        return PasswordEncoder.super.upgradeEncoding(encodedPassword);
    }
}

创建配置类管理该解析器——解析器唯一

WebSocket和SpringSecurity的学习记录,spring boot,后端,java

  • 定义登录服务类型——方法的实现内容是:根据用户名查询用户对象,和用户权限列表。(MyUserDetailsServiceImpl)

WebSocket和SpringSecurity的学习记录,spring boot,后端,java

/**
 * 登录服务实现类型
 */
@Component
public class MyUserDetailsServiceImpl implements UserDetailsService {
    @Autowired
    userMapper userMapper;
    /**
     * 方法的实现内容是:根据用户名查询用户对象,和用户权限列表。
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//      根据用户名查询用户
        User user =userMapper.SelectByUserName(username);
//        判断用户是否存在
        if (user==null)
        {
            throw new UsernameNotFoundException("用户名或者密码错误");
        }
//        返回UserDetails接口类型对象
        org.springframework.security.core.userdetails.User result=
                new org.springframework.security.core.userdetails.User(
                        username,//登录用户的用户名
                        user.getPassword(),//登录用户的密码,是服务器保存的密文
                        AuthorityUtils.NO_AUTHORITIES//工具提供的无权限空集合,
                        );
        return result;
    }
}


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

  1. 在默认的页面登录的时候,sercurity会自动调用实现PosswordEndcoder接口的类中的encode方法,进行密码的解析
  2. 然后sercurity接着调用实现UserDetailsService接口的实现类中的loadUserByUsername方法,进行例如用户的查询
  3. 然后sercurity会接着调用实现PosswordEndcoder接口的类中的encode方法,和matches进行库密码和表单密码的校验

WebSocket和SpringSecurity的学习记录,spring boot,后端,java文章来源地址https://www.toymoban.com/news/detail-811285.html

MySecurityConfiguration配置类的编写

@Configuration
@EnableWebSecurity
public class MySecurityConfiguration {
    /**
     * 创建Security过滤器链对象
     * @return
     */
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity security) throws Exception {
//        登录配置类
        Customizer<FormLoginConfigurer<HttpSecurity>> customizer = new Customizer<FormLoginConfigurer<HttpSecurity>>(){
            @Override
            public void customize(FormLoginConfigurer<HttpSecurity> configurer) {
                //具体的认证配置
                configurer
                        .loginPage("/login")
//                        .defaultSuccessUrl("/test")//默认跳转地址
//                        .successForwardUrl("/test") //认证成功后跳转地址
                        .successHandler(new MyAuthenticationsuccessHandler("/test",true))//设置认证成功后的处理代码逻辑。
                        .failureUrl("/loginfail")//登录失败跳转地址
                ;//设置登录页面访问地址。默认是/login。必须是get请求。自定义后提供控制器+视图
            }
        };
//        设置认证配置
    security
            .formLogin(customizer);

//    退出登录配置
        Customizer<LogoutConfigurer<HttpSecurity>> logoutCustomizer = new Customizer<LogoutConfigurer<HttpSecurity>>() {
            @Override
            public void customize(LogoutConfigurer<HttpSecurity> configLoginout) {
                configLoginout
                        .logoutUrl("/logout")//退出登录请求地址
                        .logoutSuccessUrl("/login")//退出登录成功以后跳转地址,默认是登录页面地址?logou
                        .logoutSuccessHandler(new MyLogOutsuccessHandler())//设置退出登录成功后的处理代码
                        .addLogoutHandler(new MyLogOutHandler())
                ;
            }
        };
//        设置登出配置
        security.logout(logoutCustomizer);

    security
            .authorizeRequests()
            .antMatchers("/login","/css/**","/image/**","/loginfail").permitAll() // 允许所有用户访问 /login 路径
            .anyRequest().authenticated(); // 所有其他请求都需要认证
//        关闭CSRF功能
        security.csrf().disable();
        return security.build();
    }
    /**
     * 创建一个passwordencoder类型bean对象
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        //强散列密码解析器,构造方法可以传递整型参数,范围在4~31之间,数字越大强度越高,性能越低
        return new BCryptPasswordEncoder();
    }

}

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

//认证成功后的处理逻辑
public class MyAuthenticationsuccessHandler implements AuthenticationSuccessHandler {
//  登录成功后访问的地址
    private String url;
    // 是否是重定向
    private boolean isRedirect;
    public MyAuthenticationsuccessHandler( String url,boolean isRedirect){
            this.url=url;
            this.isRedirect=isRedirect;
    }
    /**
     * 认证成功后具体的执行代码
     * @param request
     * @param response
     * @param authentication  认证成功后的用户主体对象,包含个人登录的信息和权限列表
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        if(isRedirect){
            //重定向
            response.sendRedirect(url);
        }else
            //请求转发
            request.getRequestDispatcher(url).forward(request,response);
    }
}

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

public class MyLogOutHandler implements LogoutHandler {
    /**
     * 处理时逻辑
     * @param request
     * @param response
     * @param authentication
     */
    @Override
    public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
        //一般做额外处理,比如保存会话中某些attribute到数据库
        //比如记录日志
    }
}

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

public class MyLogOutsuccessHandler implements 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和SpringSecurity的学习记录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • spring-websocket在SpringBoot(包含SpringSecurity)项目中的导入

    ✅作者简介:大家好,我是 Meteors., 向往着更加简洁高效的代码写法与编程方式,持续分享Java技术内容。 🍎个人主页:Meteors.的博客 🥭本文内容:spring-websocket在SpringBoot(包含SpringSecurity)项目中的导入 -----------------------------------------------------       目录       --------------

    2024年02月15日
    浏览(30)
  • 初级 - 若依框架 - Java Spring/Spring Boot 项目理解记录

    一般情况下,我们创建对象都是 类名 + 类引用名 = new 类名() 但是如果是不想要 等于号后面的对象实例化操作,那么可以使用 @Autowired 注解,当然这是在使用 Spring 时,才能这样,不然一般情况下,也没法用这个注解。用了这个 @Autowired 注解,会让 Spring 自动帮你托管这个对象

    2024年02月16日
    浏览(36)
  • Java实战:Spring Boot实现AOP记录操作日志

    本文将详细介绍如何在Spring Boot应用程序中使用Aspect Oriented Programming(AOP)来实现记录操作日志的功能。我们将探讨Spring Boot集成AOP的基本概念,以及如何使用Spring Boot实现AOP记录操作日志。最后,我们将通过一个具体示例来演示整个实现过程。本文适合已经具备Spring Boot基础

    2024年02月22日
    浏览(41)
  • java web(后端+前端) 学习路线记录---1.Java(更新中)

    资源:狂神说 1.注释、标识符、 (1) 建立空项目来建立java项目: (2) 单行注释://注释 (3) 多行注释:/* Djandjan / (4) 文档注释: / * */ 2标识符(类名,变量名,方法名) (5) (6) 标识符注意点: 2.数据类型 (1) 要求变量严格符合规范,所有变量先

    2024年02月20日
    浏览(32)
  • 【Spring Boot 源码学习】ConditionEvaluationReport 日志记录上下文初始化器

    《Spring Boot 源码学习系列》 上篇博文《共享 MetadataReaderFactory 上下文初始化器》, Huazie 带大家详细分析了 SharedMetadataReaderFactoryContextInitializer 。而在 spring-boot-autoconfigure 子模块中预置的上下文初始化器中,除了共享 MetadataReaderFactory 上下文初始化器,还有一个尚未分析。 那么

    2024年04月13日
    浏览(34)
  • Spring Boot 整合SpringSecurity和JWT和Redis实现统一鉴权认证

    本文主要讲了Spring Security文章,如果有什么需要改进的地方还请大佬指出⛺️ 🎬作者简介:大家好,我是青衿🥇 ☁️博客首页:CSDN主页放风讲故事 🌄每日一句:努力一点,优秀一点 Spring Security Spring Security是一个强大且高度可定制的身份验证和访问控制框架。它是保护基

    2024年02月05日
    浏览(39)
  • Spring Boot + Vue的网上商城之springsecurity+jwt+redis实现用户权限认证实现

    在网上商城项目中,用户的安全性是非常重要的。为了实现用户权限认证和安全校验,我们可以使用Spring Security、JWT和Redis来实现。本篇博客将详细介绍后端和前台的实现过程,并提供相应的代码案例。 当用户点击登录按钮时,前端发送一个POST请求到后端的登录接口,传递用

    2024年02月07日
    浏览(41)
  • Spring Boot学习随笔- 后端实现全局异常处理(HandlerExceptionResolver),前后端解决跨域问题(@CrossOrigin(局部解决)自定义跨域配置类(全局))

    学习视频:【编程不良人】2021年SpringBoot最新最全教程 异常处理作用:用来解决整合系统中任意一个控制器抛出异常时的统一处理入口 传统单体架构下的处理方式 配置全局异常处理类 resolveException :当控制器方法出现异常时,如果该方法没有try...catch,则会进入当前方法 针

    2024年02月04日
    浏览(40)
  • 2023 最新版IntelliJ IDEA 2023.1创建Java Web前(vue3)后端(spring-boot3)分离 项目详细步骤(图文详解)

    2023 最新版IntelliJ IDEA 2023.1创建Java Web 项目详细步骤(图文详解) 本篇使用当前Java Web开发主流的spring-boot3框架来创建一个Java前后端分离的项目,前端使用的也是目前前端主流的vue3进行一个简单的项目搭建,让你距离Java全栈开发更近一步 🏴‍☠️。 使用版本: “17.0.1”

    2024年02月12日
    浏览(76)
  • Spring Boot整合WebSocket

    在HTTP协议中,所有的请求都是由客户端发起的,由服务端进行响应,服务端无法向客户端推送消息,但是在一些需要即时通信的应用中,又不可避免地需要服务端向客户端推送消息,传统的解决方案主要有如下几种。 轮询 轮询是最简单的一种解决方案,所谓轮询,就是客户

    2024年02月05日
    浏览(74)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包