当SessionCreationPolicy.STATELESS处于无状态时显示spring安全身份验证对象

当SessionCreationPolicy.STATELESS处于无状态时显示spring安全身份验证对象,spring,spring-boot,spring-security,jwt,thymeleaf,Spring,Spring Boot,Spring Security,Jwt,Thymeleaf,我将spring安全会话策略设置为无状态 因为我正在使用JWT,所以STATLESS会更好 但无国籍会导致一个问题 在thymeleaf中无法显示身份验证对象 @Configuration @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired MyUserDetailsService myUserDetailsService; @Over

我将spring安全会话策略设置为无状态

因为我正在使用JWT,所以STATLESS会更好 但无国籍会导致一个问题

在thymeleaf中无法显示身份验证对象

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

@Autowired
MyUserDetailsService myUserDetailsService;


@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().antMatchers("/index").permitAll();
    http.authorizeRequests().antMatchers("/main").permitAll();
    http.formLogin().loginPage("/login").permitAll().successHandler(successHandler());
    http
    .csrf().disable()
    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); // Session is STATELESS
}
[${#身份验证}]]
如果我更改了会话策略,我可以显示身份验证对象

但那不是我想要的

总之


当spring的会话策略为无状态时,我可以将身份验证对象与thymeleaf一起使用吗?

基于表单的登录需要会话,因此标记为无状态将意味着用户不可用。您可能可以看到该页面,因为它被标记为permitAll,这意味着无需用户查看它

要解决这个问题,您可以切换到一种无状态的身份验证形式(即,它包含在每个请求中)。例如:

<h1>[[${#authentication }]]</h1>
我也不确定themleaf模板使用的语法。对我来说,我用的是这样的东西:

// @formatter:off
http
    .authorizeRequests()
        .mvcMatchers("/index", "/main").permitAll()
        .and()
    .httpBasic()
        .and()
    .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS); 
// @formatter:on
我有一个测试来验证它的有效性

@Controller
public class IndexController {
    @GetMapping("/")
    String index() {
        return "index";
    }

    @ModelAttribute
    Authentication authentication(Authentication authentication) {
        return authentication;
    }
}
@SpringBootTest(webEnvironment=SpringBootTest.webEnvironment.RANDOM\u端口)
类DemoApplicationTests{
@自动连线
testrest模板rest;
@试验
void indexWhenOnymous()引发异常{
ResponseEntity result=rest.exchange(RequestEntity.get(URI.create(“/”).build(),String.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
断言(result.getBody()).doesNotContain(“用户”);
}
@试验
void indexWhenAuthenticated()引发异常{
ResponseEntity result=rest.exchange(RequestEntity.get(URI.create(“/”)).headers(h->h.setBasicAuth(“用户”、“密码”))).build(),String.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(result.getBody())。包含(“用户”);
}
}

您可以找到完整的示例,在该示例中,您可以使用用户名
user
和密码
password

登录。谢谢您的回答。但是我该如何登录呢?我应该添加登录url和html吗?如果你想使用无状态方法,你需要一个身份验证机制来支持每次提供凭证。基于表单的身份验证旨在使用状态,因此它实际上不适用于无状态身份验证。在我的示例中,凭据是通过基本身份验证提供的,这将适用于无状态身份验证。在我提供的
测试中,您可以在
索引中看到如何进行身份验证。
@Controller
public class IndexController {
    @GetMapping("/")
    String index() {
        return "index";
    }

    @ModelAttribute
    Authentication authentication(Authentication authentication) {
        return authentication;
    }
}
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class DemoApplicationTests {
    @Autowired
    TestRestTemplate rest;

    @Test
    void indexWhenAnonymous() throws Exception{
        ResponseEntity<String> result = rest.exchange(RequestEntity.get(URI.create("/")).build(), String.class);
        assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(result.getBody()).doesNotContain("user");
    }

    @Test
    void indexWhenAuthenticated() throws Exception{
        ResponseEntity<String> result = rest.exchange(RequestEntity.get(URI.create("/")).headers(h -> h.setBasicAuth("user", "password")).build(), String.class);
        assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(result.getBody()).contains("user");
    }
}