6

我正在编写一个带有基于弹簧靴休息的后端和基于聚合物飞镖的前端的小应用程序。

目前我正在努力从登录机制接收会话ID......

最初我计划使用HeaderHttpSessionStrategy并使用它来对 spring-session/redis 会话存储进行身份验证以启用水平扩展。

问题是spring security总是在登录后和dartHttpRequest类(来自html包)中执行重定向,并且在重定向后,来自初始响应的标头字段当然不再存在/可访问。我试图为客户端禁用 followRedirect,但看起来这仅适用于 IO 包HttpRequest

然后我尝试切换到,CookieHttpSessionStrategy但看起来 dart httprequest 没有将收到的 cookie 存储在浏览器 cookie 后端:-/

这应该是一个简单的问题,但我在这里有点迷失了。这不可能那么难...

例如,当我使用 intellij 休息客户端时,一切正常,我可以从 cookie 或标头字段中提取会话 ID...

有任何想法吗?:-/

4

2 回答 2

2

看起来 dart 总是在浏览器中遵循这些重定向,我没有机会在第一个请求的标头中检索 cookie 或令牌。

因此,作为替代解决方案,我接下来尝试执行此操作:

在 Spring Security 中激活基本身份验证:

@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/", "/logout").permitAll()
                .anyRequest().authenticated()
                .and()
                .httpBasic()
                .and()
                .sessionManagement().sessionFixation().changeSessionId()
                .and()
                .csrf().disable();
    }
...
}

在一个控制器中,我有这样的东西作为受保护的资源:

@RequestMapping(value = "login", method = RequestMethod.POST)
public String login() {
    return RequestContextHolder.currentRequestAttributes().getSessionId();
}

通过这种方式,您可以获得会话 ID 作为常规结果。因此,我可以简单地从响应正文中获取 ID,并在我提供一次正确的基本身份验证凭据后使用它。

这只应在受信任的环境中或通过 https 使用,以使坏人更难嗅探凭据或会话。

所以基本上这就是我登录时所做的:

void login() {
  Map<String, String> headers = {};
  authorize(headers);
  HttpRequest.request(LOGIN_URL, method: "POST", requestHeaders: headers)
  .then((request) => processLogin(request))
  .catchError((e) => processLoginError(e));

}

void processLogin(HttpRequest request) {
  sessionController.sessionId=request.responseText;
  mainApp.showHome();
}

void processLoginError(var e) {
  print("total failure to login because of $e");
}
String authorization() {
  String auth = window.btoa("$username:$password");
  return "Basic $auth";
}

void authorize(Map<String, String> headers) {
  headers.putIfAbsent("Authorization", () => authorization());
}

要发送请求,HeaderHttpSessionStrategy我可以这样做:

void updateUserData(){
  _logger.info("Updating user data");
  Map<String, String> headers = {"Accept": "application/json", 'x-auth-token':sessionId};
  HttpRequest.request(USER_URL, method: "GET", requestHeaders: headers)
    .then((request) => processUserData(request))
    .catchError(ErrorHandler.handleHttpErrorGeneric);
}

你也可以让它与 cookie 一起工作,但我喜欢这样,HttpRequest.request()所以使用标题字段更容易。

于 2015-02-01T20:20:09.480 回答
0

教程教您如何在身份验证成功或失败后阻止 Spring Security 重定向。

身份验证应该返回 200 而不是 301
失败的身份验证应该返回 401 而不是 302

实际上,我认为教程中的代码过于复杂。对于MySavedRequestAwareAuthenticationSuccessHandler类,您只需要函数中的一行onAuthenticationSuccess

clearAuthenticationAttributes(request);
于 2017-09-27T20:33:12.947 回答