SpringBoot整合SpringSecurity遇到的SESSION验证问题

前言

项目是之前的老项目springmvc+jsp项目改的,因为需要对框架做改动,功能没有大改动,所以没有采用前后端分离的方式,后端采用springboot+spring security前端还是jsp,所以还是session验证的方式登录。但是整合好后测试发现问题,每次登录跳转到首页之后刷新页面又重定向到了login页面

问题解决

1、问题出现的原因

因为人比较懒,框架直接用之前前后端分离的项目,配置里面SecuityConfig也是延用前后端分离的配置,这样创建完就发现一个问题:每次请求后端接口的session都不一致,这时候刷新页面重新请求后台得到是新的session,系统判断没有登录就会重新跳转到login页面

在排查的时候发现Security的配置SecuityConfig里面有这一行:

http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)

这个是配置是session的生成策略,这个枚举类型,有几个类型,点击去查看

其中:

ALWAYS

总是创建HttpSession

IF_REQUIRED

Spring Security只会在需要时创建一个HttpSession

NEVER

Spring Security不会创建HttpSession,但如果它已经存在,将可以使用HttpSession

STATELESS

Spring Security永远不会创建HttpSession,它不会使用HttpSession来获取SecurityContext

问题就出在这里,我们的前端是jsp验证需要用session验证的方式,这样的配置session生成策略是STATELESS,就是不生成session,这样的配置还是之前前后端分离的配置,用在这里就不对了。

2、问题解决

咱们需要把生成session的策略改成ALWAYS,用session的方式验证。

将这个配置改成如下:

.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS);

测试问题解决!

3、其他问题记录:

接口请求POST返回403,通过查阅资料,Security采用的CSRF(Cross-site request forgery跨站请求伪造)默认支持的方法: GET|HEAD|TRACE|OPTIONS,不支持POST。

需要在security在配置中禁用掉它。加如下配置:

.and().csrf().disable()

 3、总结

其实是因为自己懒直接用之前的前后端分离的配置导致的,还有SpringSecurity有些配置还是需要了解他是做什么的,不然后面遇到其他问题也不知为什么。

这里就记录一下:

.cors()是开启跨域;
.csrf().disable() 是禁用使用跨站请求,可解决POST请求403问题;
.sessionManagement().sessionCreationPolicy(X)是session的生成策略,前后端分离的时候配置成STATELESS,非前后端分离的需要配置成ALWAYS

原创不易,转载请注明出处!

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Spring Boot可以很方便地整合Spring Security和JWT(JSON Web Token)。 首先,需要在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> ``` 然后,需要创建一个Security配置类,用于配置Spring Security和JWT: ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; @Autowired private JwtRequestFilter jwtRequestFilter; @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { // 配置用户认证方式 } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Override protected void configure(HttpSecurity httpSecurity) throws Exception { httpSecurity.csrf().disable() .authorizeRequests().antMatchers("/authenticate").permitAll(). anyRequest().authenticated().and(). exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and().sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS); httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class); } } ``` 在上面的配置类中,需要注入JwtAuthenticationEntryPoint和JwtRequestFilter两个类。其中,JwtAuthenticationEntryPoint用于处理未经授权的请求,JwtRequestFilter用于验证JWT并将用户信息添加到Spring Security上下文中。 接下来,需要创建一个JwtTokenUtil类,用于生成和验证JWT: ```java @Component public class JwtTokenUtil { private static final String SECRET_KEY = "secret"; public String generateToken(UserDetails userDetails) { Map<String, Object> claims = new HashMap<>(); return Jwts.builder().setClaims(claims).setSubject(userDetails.getUsername()) .setIssuedAt(new Date(System.currentTimeMillis())) .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10)) .signWith(SignatureAlgorithm.HS512, SECRET_KEY).compact(); } public boolean validateToken(String token, UserDetails userDetails) { final String username = getUsernameFromToken(token); return (username.equals(userDetails.getUsername()) && !isTokenExpired(token)); } private boolean isTokenExpired(String token) { final Date expiration = getExpirationDateFromToken(token); return expiration.before(new Date()); } private Date getExpirationDateFromToken(String token) { return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getExpiration(); } private String getUsernameFromToken(String token) { return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getSubject(); } } ``` 在上面的类中,需要设置一个密钥,用于生成和验证JWT。generateToken方法用于生成JWT,validateToken方法用于验证JWT是否有效。 最后,需要创建一个JwtAuthenticationEntryPoint类和一个JwtRequestFilter类。JwtAuthenticationEntryPoint类用于处理未经授权的请求,JwtRequestFilter类用于验证JWT并将用户信息添加到Spring Security上下文中。 以上就是整合Spring Security和JWT的基本步骤。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值