Spring Security认证相关(一)

会话管理

Spring Security认证成功之后会保存会话信息,将认证信息保存在Session,发送JSESSIONID数据给浏览器保存在Cookie中,浏览器访问的时候携带Cookie,服务器根据JSESSIONID找到Session

Spring Security中会话创建策略有下面几种:

设置超时:

// 会话
http.sessionManagement(session -> {
    session
        // 创建会话策略
        .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
        // 会话超时访问url
        .invalidSessionUrl("/login")
        // 一个账号最大登录设备数量
        .maximumSessions(1)
        // 当一个账号有多个用户登录时提示
        .expiredSessionStrategy(new SessionInformationExpiredStrategyImpl());
});
public class SessionInformationExpiredStrategyImpl implements SessionInformationExpiredStrategy {
    @Override
    public void onExpiredSessionDetected(SessionInformationExpiredEvent event) throws IOException, ServletException {
        Map<String,Object> map = new HashMap<>();
        map.put("code", "-1");
        map.put("message", "登录失败");
        map.put("data", "当前账号已在其它设备登录");
        String json = new ObjectMapper().writeValueAsString(map);
        HttpServletResponse response = event.getResponse();
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().println(json);
    }
}

密码编辑器

密码编辑器接口PasswordEncoder

默认Spring Security提供一些实现类:

在5.0之后的默认密码编辑器是DelegatingPasswordEncoder,可以根据前缀匹配不同的密码编辑器,比如下面这样:

格式:{算法名}加密后密码
{bcrypt}$2a$10$c2jp7iXCNwjEgtA9d2zQde01HpKIUpihEKo4Z.uasrvt.cTxWjFgy

在配置文件中我们可以指定某一种密码编辑器:

/**
  * 密码器
  * @return BCrypt密码器
*/
@Bean
public PasswordEncoder passwordEncoder(){
    return new BCryptPasswordEncoder();
}

Remember-me(记住我)

Remember-me(记住我)或persistent-login认证是指网站能够在两次会话之间记住委托人的身份。这通常是通过向浏览器发送一个cookie来实现的,在未来的会话中可以检测到cookie,并导致自动登录的发生。Spring Security为这些操作提供了必要的钩子,并有两个具体的“记住我”的实现。一个使用散列法来保护基于cookie的令牌的安全性,另一个使用数据库或其他持久性存储机制来存储生成的令牌。

请注意,这两种实现都需要一个 UserDetailsService。如果你使用一个不使用 UserDetailsService 的认证 provider(例如,LDAP provider),除非你在你的应用程序上下文中也有一个 UserDetailsService Bean,否则它不会工作。

Spring Security中开启记住我,只需要在配置文件中开启配置即可。

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    // 认证相关
    http.authorizeRequests(authorize ->
                           authorize
                           // /login.html请求不需要验证
                           .requestMatchers(new AntPathRequestMatcher("/login")
                                            ,new AntPathRequestMatcher("/logout")).permitAll()
                           .anyRequest()
                           .authenticated()
                          );
    http.formLogin(Customizer.withDefaults());
    http.rememberMe();
}

这里我们使用默认的登录表单,效果如下:

使用F12查看登录参数,会发现多了一个remember-me

在登录之后关闭浏览器再次访问:

posted @ 2024-04-23 09:58  无涯子wyz  阅读(78)  评论(0)    收藏  举报