当SessionCreationPolicy.STATELESS处于无状态时显示spring安全身份验证对象
我将spring安全会话策略设置为无状态 因为我正在使用JWT,所以STATLESS会更好 但无国籍会导致一个问题 在thymeleaf中无法显示身份验证对象当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
@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");
}
}