gpt4 book ai didi

Spring - 使用 cookie 的 RESTful 身份验证

转载 作者:行者123 更新时间:2023-12-04 07:26:06 26 4
gpt4 key购买 nike

我尝试根据这篇文章 - http://automateddeveloper.blogspot.co.uk/2014/03/securing-your-mobile-api-spring-security.html 使用 cookie 实现身份验证(对于我的 android 客户端应用程序)

安全配置:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

private final static String TOKEN_STRING = "my_token";
private final static String COOKIE_STRING = "my_cookie";

@Autowired
private UserDetailsService userSvc;
@Autowired
private MyTokenBasedRememberMeService tokenSvc;
@Autowired
private RememberMeAuthenticationProvider rememberMeProvider;
@Autowired
private MyAuthSuccessHandler authSuccess;
@Autowired
private MyAuthFailureHandler authFailure;
@Autowired
private MyLogoutSuccessHandler logoutSuccess;


@Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userSvc)
.passwordEncoder(passwordEncoder());

auth.authenticationProvider(rememberMeProvider);
}

@Override
protected void configure(HttpSecurity http) throws Exception {

http
.authorizeRequests()
.antMatchers("/register").permitAll()
.anyRequest().authenticated().and()
.formLogin()
.loginPage("/")
.loginProcessingUrl("/loginendpoint")
.successHandler(authSuccess)
.failureHandler(authFailure).and()
.logout()
.logoutUrl("/logout")
.logoutSuccess(logoutSuccess)
.deleteCookies(COOKIE_STRING).and()
.rememberMe()
.rememberMeServices(tokenSvc).and()
.csrf()
.disable()
.addFilterBefore(rememberMeAuthenticationFilter(), BasicAuthenticationFilter.class)
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}

@Bean
public RememberMeAuthenticationFilter rememberMeAuthenticationFilter() throws Exception {
return new RememberMeAuthenticationFilter(authenticationManager(), tokenBasedRememberMeService());
}

@Bean
public RememberMeAuthenticationProvider rememberMeAuthenticationProvider() {
return new RememberMeAuthenticationProvider(TOKEN_STRING);
}

@Bean
public MyTokenBasedRememberMeService tokenBasedRememberMeService() {
MyTokenBasedRememberMeService service = new MyTokenBasedRememberMeService(TOKEN_STRING,
userSvc);
service.setAlwaysRemember(true);
service.setCookieName(COOKIE_STRING);
return service;
}

@Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}

}

MyTokenBasedRememberMeService:
public class MyTokenBasedRememberMeService extends TokenBasedRememberMeServices {

private final static String TOKEN_STRING = "my_token";

public MyTokenBasedRememberMeService(String key, UserDetailsService userDetailsService) {
super(key, userDetailsService);
}

@Override
protected String extractRememberMeCookie(HttpServletRequest request) {
String token = request.getHeader(TOKEN_STRING);
if ((token == null) || (token.length() == 0)) {
return "";
}
return token;
}
}

不幸的是,在成功登录后,我的 cookie 在客户端是空的:
Set-Cookie: my_cookie=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/

怎么了?

-------编辑 1-------

If you login directly in the browser you get no cookie (in dev tools for example)?



我使用 postman 对其进行了测试,但我只收到了 JSESSIONID cookie(没有 my_cookie)。

Also, are you using a custom login controller method? (e.g. Is your usercontroller explicitly authenticating users?)



是的,我正在使用自定义登录 Controller 方法,但我是 spring security 的新手,如果可以在没有自定义 Controller 的情况下完成,我将不胜感激任何解释。我的 Controller 负责用户的身份验证。

If you are not using spring-security to handle authentication then I suspect you may have to explicitly set cookies etc yourself



不,我只使用 Spring 安全。至少我是这么认为的...... :)

What is UserController login method doing?



我更新了我的代码。

-------编辑 2-------

根据@rhinds 的建议和 spring 文档,我纠正了一些事情(上面的代码已更新)。现在我可以登录 loginendpoint登录后我得到 my_cookie .但我有相关的问题:
  • 成功登录后,我收到一个 cookie 作为响应。如果它是在服务器端自动添加的,我必须手动添加 token (客户端)以进一步请求?
  • 注销呢? “Spring”如何知道必须注销哪个用户?
  • token 到期日期如何?默认是2周,然后呢?我可以设置 token 永不过期吗?

  • 对于将做类似事情的人,我建议也看看这篇很棒的文章 - https://dzone.com/articles/secure-rest-services-using :)

    最佳答案

    好的,所以最好的起点是放弃用于登录的自定义 spring Controller ,并将其委托(delegate)给 spring 安全性 - 文档将为您提供如何开始的很好的概述 - see here to get started

    从链接的文章中,如果您查看配置代码:

    @Override protected void configure(HttpSecurity http) throws Exception {
    http
    .csrf()
    .disable()
    .authorizeRequests()
    .antMatchers("/resources/**").permitAll()
    .antMatchers("/sign-up").permitAll()
    .antMatchers("/sign-in").permitAll()
    .anyRequest().authenticated()
    .and()
    .formLogin()
    .loginPage("/")
    .loginProcessingUrl("/loginprocess")
    .failureUrl("/mobile/app/sign-in?loginFailure=true")
    .permitAll().and()
    .rememberMe().rememberMeServices(tokenBasedRememberMeService);
    }
    .formLogin() 下的部分call 告诉 spring-security 哪个端点监听登录尝试 - 例如如果我有这个配置和 POST到端点 /loginprocess然后 Spring-security 将拦截它并使用身份验证管理器来处理提交的表单(期望用户名和密码字段等)。

    下一个重要的部分是您的 userDetailsService 的接线。和身份验证管理器:
     @Override protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception {
    auth
    .userDetailsService(userDetailsServiceImpl)
    .passwordEncoder(bCryptPasswordEncoder());
    auth.authenticationProvider(rememberMeAuthenticationProvider);
    }

    这为 spring-security 提供了在给定登录尝试的情况下尝试加载用户对象的方法 - 只要您的类实现 UserDetailsService那么spring security应该有它所需要的一切。

    假设一切都正确,那么您应该可以删除自定义登录 Controller 方法,定义一个 loginProcessingUrl然后 POST对此,spring-security 应该启动并(尝试)处理它。

    花一些时间让 spring-security 配置工作并处理简单的登录案例可能是值得的,一旦这一切都被委托(delegate)给 spring-security 机器,更新配置以连接到 RememberMe 方面应该会更容易。

    回复编辑 2

    我假设您正在根据此处的一般方法遵循链接文章中的实现细节: http://automateddeveloper.blogspot.co.uk/2014/03/securing-your-api-for-mobile-access.html (您在操作中链接到的实现细节的解释)

    1. After a successful login I receive a cookie in response. To further requests I have to manually add the token (client side) if it's automatically added on the server side?


    因此,假设您正在登录,然后从您的移动应用程序发出 API 请求 - 根据文章,您的应用程序中需要一个 webview 以允许用户登录,一旦他们完成,WebView 将收到来自登录的响应,这将包括 cookie。此时,您所关心的只是从 cookie 中提取 token ——之后,就不再需要 cookie。在您的应用程序中,您可以随心所欲地保留 token ,并且只需添加它以确保在您从应用程序发出的每个 API 请求中提供该 token - 文章中的 RememberMe 实现从 API 请求 header 中提取 token 并验证用户。

    1. What about logout? How "Spring" will know which user has to be logged out?


    它不会 - 配置已将 spring 设置为无状态,例如它不跟踪登录的用户,这是由有效 cookie 的存在(或者在 API 请求的情况下,我们提取的 token 的存在)记录的 - 例如。在无状态模式下,对应用程序发出的每个请求都会检查以查看它是否经过身份验证

    1. What about the token expiration date? The default is 2 weeks, then what? Can I set so that the token never expires?


    同样,假设您遵循上面链接中描述的模式,这并不重要,因为我们只是在第一次登录时使用该 cookie,之后您的应用程序有一个将用于身份验证的记住我 token ,因此 cookie 本质上是从那时起被丢弃。

    关于Spring - 使用 cookie 的 RESTful 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32101153/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com