简体   繁体   English

Spring:使用授权标头重定向

[英]Spring: Redirect with Authorization Header

I'm currently writing an application that issues a JWT token on demand.我目前正在编写一个按需发布 JWT 令牌的应用程序。 When the token is issued, the user should be redirected to a webpage.发出令牌后,应将用户重定向到网页。 This works like a charm - but I need to set an authorization header for that redirect.这就像一个魅力 - 但我需要为该重定向设置一个授权标头。

The user enters his credentials on Webpage A. Webpage A sends a POST Request to Server B. Server B checks the credentials and offers a token.用户在网页 A 上输入其凭据。网页 A 向服务器 B 发送 POST 请求。服务器 B 检查凭据并提供令牌。 Now the user should be redirected to Webpage C.现在用户应该被重定向到网页 C。

I tried the following:我尝试了以下方法:

@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);

}

The redirect works, but only /token gets the Authorization Header as Response Header, right before the redirect happens.重定向有效,但只有/token才能在重定向发生之前将授权标头作为响应标头。

How can I achieve that the header is sent to Webpage C?如何实现将标头发送到网页 C?

Thanks.谢谢。

Update更新

A forward: is not possible, as Webpage C is on another URL and not in the same Controller. forward:是不可能的,因为网页 C 在另一个 URL 上而不是在同一个控制器中。

Anyone has an Idea how to solve?任何人都有一个想法如何解决?

Typically, we let the frontend developers handle the redirections.通常,我们让前端开发人员处理重定向。 If you work on the backend, you could offer a restful API to issue JwtTokens.如果你在后端工作,你可以提供一个宁静的 API 来发布 JwtTokens。 The frontend will worry about how to carry the Authorization header in the following redirected Http requests.前端会担心如何在以下重定向的 Http 请求中携带 Authorization 标头。 Here is a simple login controller using mobile and password in exchange for the JwtToken.这是一个简单的登录控制器,使用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);
    }
}

If you, as the backend, wish to handle the redirection anyway, redirect the request to a webpage with the token as a parameter, in this case:如果您作为后端,无论如何都希望处理重定向,请将请求重定向到以令牌为参数的网页,在这种情况下:

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

The related backend code would be:相关的后端代码将是:

    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();
}

Again, let the frontend put the token into the further request as the authorization header.同样,让前端将令牌作为授权标头放入进一步的请求中。

Keep in mind, you are returning a response so you can set the response header.请记住,您正在返回一个响应,以便您可以设置响应标头。 You don't get to set the request header of the next request for the frontend.您无法为前端设置下一个请求的请求标头。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM