如何在Spring Boot Controller中获取SAML RelayState?

问题描述 投票:0回答:1

我可以在 Spring

RelayState
通过
SAML 1
访问
SAMLCredential
来获得
SecurityContext

SAMLCredential saml = (SAMLCredential) SecurityContextHolder.getContext()
                                 .getAuthentication().getCredentials();
String relay = saml.getRelayState();

如何使用

RelayState
在控制器方法中访问
SAML2

java spring-boot saml-2.0 spring-saml
1个回答
0
投票

所以经过大量的搜索和反复试验,我想出了一种方法(尽管我真的相信它应该更简单)。

@Bean
Saml2AuthenticationRequestResolver authenticationRequestResolver(
        RelyingPartyRegistrationResolver registrations) {
    OpenSaml4AuthenticationRequestResolver authenticationRequests = new OpenSaml4AuthenticationRequestResolver(registrations);

    return new Saml2AuthenticationRequestResolver() {
        public <T extends AbstractSaml2AuthenticationRequest> T resolve(HttpServletRequest request) {
            T post = authenticationRequests.resolve(request);
            
            String relayState = request.getParameter("RelayState");
            
            log.info("@Config - RelayState is {}", relayState);
            
            if (relayState != null)
            {
              HttpSession session = request.getSession();
              
              session.setAttribute("RelayState", relayState);
              
              log.info("@Config - RelayState saved to session");
            }
            
            return post;
        }
    };
}

然后在控制器方法中,您将按如下方式检索它:

public String index(Model model, @AuthenticationPrincipal Saml2AuthenticatedPrincipal principal, HttpServletRequest request) {
    String username = principal.getName();

    log.info("@Controller - Current Authenticated user: {}", username);
    
    model.addAttribute("username", username);
    
    HttpSession session = request.getSession();
    
    String relayState = (String) session.getAttribute("RelayState");
    
    log.info("@Controller - RelayState: {}", relayState);
    
    if(relayState != null) {
        session.removeAttribute("RelayState"); // prevent replay
        
        return "redirect:"+relayState;
    }
    
    return "index";
}

基本上,您无法直接从控制器中的 HttpServletRequest 直接获取 RelayState 参数,因为初始 SAML 请求是经过处理和验证的 POST,然后生成 GET 并重定向到控制器。第二个请求不包含第一个请求的请求参数。

© www.soinside.com 2019 - 2024. All rights reserved.