我有一个React应用程序运行在一个单独的端口(本地主机:3000)上,我想使用该应用程序来对用户进行身份验证,目前,我已经为Spring后端(本地主机:8080)设置了代理。
我可以通过向后端发送http.httpBasic()
请求并获取会话cookie,然后在每个请求中包含cookie的方式,以某种方式手动验证而不是POST
?它将同时简化iOS端的身份验证过程(使用该过程,我只能将会话cookie值存储在钥匙串中,并将其与对我的api的每个请求一起传递给它)
如何为非浏览器请求禁用csrf?
是否有更好的方法?浏览器和移动身份验证的不同路径?
{
"username": "user",
"password": "12345678"
}
在spring控制器中处理请求
@PostMapping(path = "/web")
public String authenticateUser() {
//Receive the auth data here... and perform auth
//Send back session cookie
return "Success?";
}
我的 WebSecurityConfigurerAdapter.java
@Configuration
@EnableWebSecurity
public class WebsecurityConfig extends WebSecurityConfigurerAdapter {
private final DetailService detailService;
public WebsecurityConfig(DetailService detailService) {
this.detailService = detailService;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(detailService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.authorizeRequests()
.antMatchers(HttpMethod.POST,"/api/v1/authenticate/new").permitAll()
.antMatchers(HttpMethod.POST,"/api/v1/authenticate/web").permitAll()
.anyRequest().authenticated();
}
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedMethods("GET", "POST").allowedOrigins("http://localhost:8080");
}
};
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(14);
}
}
答案 0 :(得分:0)
您可以创建一个端点,该端点在请求正文中获取用户的凭据,执行身份验证,然后在HttpOnly cookie中设置令牌以及其他必需的参数。
设置cookie后,后续请求可以从cookie中读取访问/刷新令牌并将其添加到请求中,然后可以使用自定义CheckTokenEndpoint来验证令牌。
在下面的示例中,TokenParametersDto
是具有username
和password
属性的POJO。
对于颁发令牌(通过验证凭据),您可以将调用委派给TokenEndpoint#postAccessToken(....)或将其逻辑用于自己的方法。
@PostMapping(path = "/oauth/http/token", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Void> issueToken(@RequestBody final @Valid @NotNull TokenParametersDto tokenParametersDto,
final HttpServletResponse response) {
final OAuth2AccessToken token = tokenService.issueToken(tokenParametersDto);
storeTokenInCookie(token, response);
return new ResponseEntity<>(HttpStatus.OK);
}
private void storeTokenInCookie(final OAuth2AccessToken token, final HttpServletResponse response) {
final Cookie accessToken = new Cookie("access_token", token.getValue());
accessToken.setHttpOnly(true);
accessToken.setSecure(sslEnabled);
accessToken.setPath("/");
accessToken.setMaxAge(cookieExpiration);
final Cookie tokenType = new Cookie("token_type", token.getTokenType());
tokenType.setHttpOnly(true);
tokenType.setSecure(sslEnabled);
tokenType.setPath("/");
tokenType.setMaxAge(cookieExpiration);
// Set Refresh Token and other required cookies.
response.addCookie(accessToken);
response.addCookie(tokenType);
}
Check this answer用于为特定的URL部分禁用CSRF。