我正在尝试使用Spring(spring-boot)设置一个基本的auth页面。
当我禁用CSRF保护时,登录工作正常,但在身份验证完成后我获得了HTTP 405 for POST / login。从我的研究看起来这是因为没有启用CSRF。我从配置htto.csrf().disable()
中删除了,根据我读过的所有文档和评论,我希望看到额外的隐藏字段。
<input
type="hidden"
th:name="${_csrf.parameterName}"
th:value="${_csrf.token}" />
那没发生。然后我手动添加了,但是当Thymeleaf解析模板时我得到了一个例外。
org.springframework.expression.spel.SpelEvaluationException:EL1007E:在null上找不到属性或字段'parameterName'
看起来_csrf是空的。
以下是我在gradle build.gradle中的内容:
compile(group:'org.springframework.boot',name: “弹簧引导起动thymeleaf”) 编译(组:'org.springframework.boot',名称:'spring-boot-starter-security') 编译( “org.springframework.boot:弹簧引导起动的web”)
这是我的配置:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
UserRoleDetailService userDetailService;
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/registration", "/error/access-denied", "/login**", "/logout").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").successForwardUrl("/admin/home").permitAll()
.and()
.httpBasic()
.and()
.logout().logoutSuccessUrl("/");
http.userDetailsService(userDetailService);
}
@SuppressWarnings("deprecation")
@Bean
public static PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
Thymeleaf 3.0.9 Spring 5.0.4
我在这里做错了什么? 任何输入赞赏!谢谢!
使用HTML表单进行更新
<form th:action="@{/login}" method="post" class="form-signin">
<h3 class="form-signin-heading" th:text="Welcome"></h3>
<br/>
<input type="text" id="username" name="username" th:placeholder="Email"
class="form-control"/> <br/>
<input type="password" th:placeholder="Password"
id="password" name="password" class="form-control"/> <br/>
<input
type="hidden"
th:name="${_csrf.parameterName}"
th:value="${_csrf.token}" />
<div align="center" th:if="${param.error}">
<p style="font-size: 20; color: #FF1C19;">Email or Password invalid, please verify</p>
</div>
<button class="btn btn-lg btn-primary btn-block" name="Submit" value="Login" type="Submit"
th:text="Login"></button>
</form>
更新#2
在修改我的代码后,我发现当我禁用资源服务器配置时,CSRF令牌开始按照文档显示。现在的问题是为什么让OAuth2资源服务器因正确插入csrf而混乱?
这是我的资源服务器配置
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends
ResourceServerConfigurerAdapter {
@Autowired
private TokenStore tokenStore;
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.tokenStore(tokenStore);
resources.resourceId(AuthorizationServerConfig.API_RESOURCE_ID).stateless(false);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.requestMatchers()
.and().authorizeRequests()
.antMatchers("/users/**")
.access("#oauth2.hasScope('read')")
.and().exceptionHandling().
accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}