【问题标题】:Spring Security authenticate user via postSpring Security 通过 post 对用户进行身份验证
【发布时间】:2019-12-26 11:19:54
【问题描述】:

我有一个在单独的端口 (localhost:3000) 上运行的 react 应用程序,我想用它来验证用户身份,目前我有一个代理设置到我的 Spring 后端 (localhost:8080)。

我是否可以通过向我的后端发送 POST 请求并取回会话 cookie 然后在每个请求中包含该 cookie 以某种方式手动验证而不是 http.httpBasic()?它还将简化 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);
    }
} 

【问题讨论】:

标签: java spring spring-security


【解决方案1】:

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

设置cookies后,后续请求可以从cookies中读取access/refresh token并将其添加到请求中,然后可以使用自定义CheckTokenEndpoint来验证tokens。

在以下示例中,TokenParametersDto 是一个 POJO,具有 usernamepassword 属性。

对于颁发令牌(通过验证凭据),您可以将调用委托给 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。

【讨论】:

    猜你喜欢
    • 2012-03-06
    • 2013-02-23
    • 2020-04-16
    • 2013-06-12
    • 2011-08-12
    • 2016-11-13
    • 1970-01-01
    • 1970-01-01
    • 2020-02-16
    相关资源
    最近更新 更多