Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 419
webmonkey Avatar asked Apr 11 '26 21:04

webmonkey


1 Answers

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/

like image 178
justthink Avatar answered Apr 13 '26 10:04

justthink



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!