简体   繁体   中英

Spring: Redirect with Authorization Header

I'm currently writing an application that issues a JWT token on demand. 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. Now the user should be redirected to Webpage 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.

How can I achieve that the header is sent to Webpage C?

Thanks.

Update

A forward: is not possible, as Webpage C is on another URL and not in the same Controller.

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. The frontend will worry about how to carry the Authorization header in the following redirected Http requests. Here is a simple login controller using mobile and password in exchange for the 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/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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