Spring:使用授权标头重定向

Posted

技术标签:

【中文标题】Spring:使用授权标头重定向【英文标题】:Spring: Redirect with Authorization Header 【发布时间】:2017-06-24 10:35:09 【问题描述】:

我目前正在编写一个按需发布 JWT 令牌的应用程序。 颁发令牌时,应将用户重定向到网页。这就像一个魅力 - 但我需要为该重定向设置一个授权标头。

用户在网页 A 上输入他的凭据。网页 A 向服务器 B 发送 POST 请求。服务器 B 检查凭据并提供令牌。现在用户应该被重定向到网页 C。

我尝试了以下方法:

@RequestMapping(value = "/token", method = RequestMethod.POST, produces = "application/json", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public ResponseEntity<Object> token(
        @RequestParam("user") String _username, 
        @RequestParam("secret") String _secret
        ) throws Exception
       
    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

    MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
    map.add("user", _username);
    map.add("secret", _secret);

    HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<MultiValueMap<String, String>>(map, headers);

    HttpStatus statusCode = HttpStatus.FOUND;
    HttpHeaders httpHeaders = new HttpHeaders();

    try 
        ResponseEntity<String> request = restTemplate.exchange(_url, HttpMethod.POST, entity, String.class);
     catch (Exception ex) 
        ex.printStackTrance();
    

    String response = request.getBody();

    JSONObject _tokenObject = new JSONObject(response);
    String _token = _tokenObject.getString("access_token");

    httpHeaders.add("Authorization", "Bearer: " + _token);

    URI _redirectUri = new URI("http://foo.example.com/webpageC");
    httpHeaders.setLocation(_redirectUri);

    return new ResponseEntity<>(httpHeaders, HttpStatus.FOUND);


重定向有效,但只有/token 在重定向发生之前将授权标头作为响应标头。

如何实现标头发送到网页C?

谢谢。

更新

forward: 是不可能的,因为网页 C 在另一个 URL 上而不是在同一个控制器中。

任何人有一个想法如何解决?

【问题讨论】:

我不认为将标头传递给重定向是可能的重定向将在客户端发生。您可以做的是转发或使用 RestTemplate 使您的令牌方法充当webpageC的代理。 你能解释一下吗?或者提示一下如何实现? 发布了将近一年的帖子,但您找到解决方案了吗? 遗憾的是,我们不得不以另一种方式解决它.. @webmonkey 如果您能与社区分享您的方法,那就太好了。 【参考方案1】:

通常,我们让前端开发人员处理重定向。如果你在后端工作,你可以提供一个 RESTful API 来发布 JwtTokens。前端会担心如何在以下重定向的 Http 请求中携带 Authorization 标头。这是一个简单的登录控制器,使用mobilepassword 来换取JwtToken。

@RequestMapping(value = "/login", method = RequestMethod.POST)
public Result login(@RequestBody Map<String, String> loginMap) 
    User user = userService.findByMobile(mobile);

    if(user == null || !user.getPassword().equals(password)) 
        return new Result(ResultCode.MOBILEORPASSWORDERROR);
    else 
        String token = jwtUtils.createJwt(user.getId(), user.getUsername(), map);
        return new Result(ResultCode.SUCCESS,token);
    

如果您作为后端仍然希望处理重定向,请将请求重定向到带有令牌作为参数的网页,在这种情况下:

GET http://www.example.com/login/success?token=xxx&redirectUrl=%2Fxxx

相关的后端代码是:

    protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response, Authentication authentication) 
    Optional<String> redirectUri = CookieUtils.getCookie(request, REDIRECT_URI_PARAM_COOKIE_NAME)
            .map(Cookie::getValue);

    if(redirectUri.isPresent() && !isAuthorizedRedirectUri(redirectUri.get())) 
        throw new BadRequestException();
    

    String targetUrl = redirectUri.orElse(getDefaultTargetUrl());

    String token = tokenProvider.createToken(authentication);

    return UriComponentsBuilder.fromUriString(targetUrl)
            .queryParam("token", token)
            .build().toUriString();

再次,让前端将令牌作为授权标头放入进一步的请求中。

请记住,您正在返回一个响应,因此您可以设置响应标头。您无法为前端设置下一个请求的请求标头。

参考: https://www.callicoder.com/spring-boot-security-oauth2-social-login-part-2/

【讨论】:

顺便说一下,不要在您的服务器上存储未加密的密码。

以上是关于Spring:使用授权标头重定向的主要内容,如果未能解决你的问题,请参考以下文章

使用授权标头重定向到操作

Spring Security OAuth2 始终重定向到具有有效 Bearer 标头的 /login 页面

重定向的瓶子设置授权标头

OkHttp是否在重定向上发送授权和其他可能敏感的标头?

使用 Spring Security 在 Grails App 中避免登录重定向

Apache NiFi的InvokeHTTP和其他HTTP处理器是否会向重定向的URL发送授权标头?