Spring Security通过帖子对用户进行身份验证

时间:2019-08-21 08:12:57

标签: java spring spring-security

我有一个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);
    }
} 

1 个答案:

答案 0 :(得分:0)

您可以创建一个端点,该端点在请求正文中获取用户的凭据,执行身份验证,然后在HttpOnly cookie中设置令牌以及其他必需的参数。

设置cookie后,后续请求可以从cookie中读取访问/刷新令牌并将其添加到请求中,然后可以使用自定义CheckTokenEndpoint来验证令牌。

在下面的示例中,TokenParametersDto是具有usernamepassword属性的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。