【问题标题】:Spring Security SAML SSO redirect to controllerSpring Security SAML SSO 重定向到控制器
【发布时间】:2019-05-01 21:57:56
【问题描述】:

在 IdP 启动的设置中使用代码片段重定向到控制器 (/bootstrap/v1):

public SavedRequestAwareAuthenticationSuccessHandler successRedirectHandler() {
    SavedRequestAwareAuthenticationSuccessHandler successRedirectHandler = new SavedRequestAwareAuthenticationSuccessHandler();
    successRedirectHandler.setDefaultTargetUrl("/bootstrap/v1");
    return successRedirectHandler;
}

控制器代码片段:

public class BootstrapController extends ParentController {

    @RequestMapping(value = "/v1", method = RequestMethod.POST)
    public ResponseEntity<BootstrapResponseDto> bootstrap(@RequestBody BootstrapRequestDto bootstrapRequestDto, @RequestHeader(value = "MAC-ADDRESS", required = false) String macAddress) {

        myAppUserDetails userDetails = SecurityContextUtils.getUserDetails();

        BootstrapResponseDto bootstrapResponseDto = new BootstrapResponseDto();

        // some app specific logic goes here...

        return new ResponseEntity<>(bootstrapResponseDto, HttpStatus.OK);
    }
}

调试级日志片段:

11-29-2018 13:33:53 e7a5edb2-4051-4132-bad0-856d58af1c7d ZDJhMWExYWUtZTAxNy00NDQwLWJmOTctNzcyNTJlOWUyNmQ2 信息 http-nio-8080-exec-6 Spring 安全调试器:


收到 POST '/saml/SSO' 的请求:

org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper@28cc5b21

servletPath:/saml/SSO pathInfo:null headers: host: localhost:8080 用户代理:Mozilla/5.0(Macintosh;Intel Mac OS X 10.13;rv:63.0) Gecko/20100101 Firefox/63.0 接受: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8 接受语言:en-US,en;q=0.5 接受编码:gzip,放气 内容类型:应用程序/x-www-form-urlencoded 内容长度:11320 dnt:1 个连接:保持活动状态 cookie: JSESSIONID=ZDJhMWExYWUtZTAxNy00NDQwLWJmOTctNzcyNTJlOWUyNmQ2 升级不安全请求:1

安全过滤器链:[ MetadataGeneratorFilter
WebAsyncManagerIntegrationFilter SecurityContextPersistenceFilter
CustomLogFilter HeaderWriterFilter LogoutFilter
用户名密码验证过滤器基本验证过滤器
FilterChainProxy RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter SessionManagementFilter
ExceptionTranslationFilter FilterSecurityInterceptor ]


11-29-2018 13:33:53 e7a5edb2-4051-4132-bad0-856d58af1c7d 信息 http-nio-8080-exec-6 o.o.c.b.s.SAMLProtocolMessageXMLSignatureSecurityPolicyRule: 协议消息签名验证成功,消息类型: {urn:oasis:names:tc:SAML:2.0:protocol}响应 11-29-2018 13:33:53 e7a5edb2-4051-4132-bad0-856d58af1c7d ZDJhMWExYWUtZTAxNy00NDQwLWJmOTctNzcyNTJlOWUyNmQ2 信息 http-nio-8080-exec-7 Spring 安全调试器:


收到 GET '/bootstrap/v1' 的请求:

org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper@5f9e2aff

servletPath:/bootstrap/v1 pathInfo:null headers: host: localhost:8080 用户代理:Mozilla/5.0(Macintosh;Intel Mac OS X 10.13;rv:63.0) Gecko/20100101 Firefox/63.0 接受: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8 接受语言:en-US,en;q=0.5 接受编码:gzip,放气 dnt:1 连接:保持活动 cookie: JSESSIONID=ZDJhMWExYWUtZTAxNy00NDQwLWJmOTctNzcyNTJlOWUyNmQ2 升级不安全请求:1

安全过滤器链:[ MetadataGeneratorFilter
WebAsyncManagerIntegrationFilter SecurityContextPersistenceFilter
CustomLogFilter HeaderWriterFilter LogoutFilter
用户名密码验证过滤器基本验证过滤器
FilterChainProxy RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter SessionManagementFilter
ExceptionTranslationFilter FilterSecurityInterceptor ]


11-29-2018 13:33:53 e7a5edb2-4051-4132-bad0-856d58af1c7d 警告 http-nio-8080-exec-7 o.s.w.s.PageNotFound:请求方法 'GET' 不 支持

ExpiringUsernameAuthenticationToken 设置为返回:

org.springframework.security.providers.ExpiringUsernameAuthenticationToken@fee70636:主体:com..security.authentication.@325fcf8b;凭证:[受保护];已认证:真实;详细信息:空;授予权限:authority_1、authority_2、authority_3、authority_4

所以,我猜我的 SAML 验证和用户身份验证和授权很好。

似乎我面临的问题是 HTTP GET 无法正常工作。

如何配置和提交 HTTP POST?要么 我应该重构我的控制器来处理行为(这可能会破坏基于表单的登录,这也是应用程序身份验证的一部分)?

HTTP Status 405 - Method Not Allowed Error

【问题讨论】:

    标签: spring spring-security saml saml-2.0 spring-saml


    【解决方案1】:

    我相信这个问题与 SAML 完全无关,而是一个通用的 Spring Security 问题。此外,您没有指定正文 BootstrapRequestDto 的来源。

    你有一个 SuccessHandler,它执行重定向:

    successRedirectHandler.setDefaultTargetUrl("/bootstrap/v1"); 这执行GET

    你有一个控制器只接受POST。而且你还没有说明那具尸体是从哪里来的?

    您需要编写一个自定义的成功处理程序来发布一个帖子(可能是 JavaScript 自动提交表单?),或者只是将您的控制器更改为也接受 GET。

    public class BootstrapController extends ParentController {
    
        @RequestMapping(value = "/v1", method = RequestMethod.GET)
        public ResponseEntity<BootstrapResponseDto> bootstrap() {
    
            myAppUserDetails userDetails = SecurityContextUtils.getUserDetails();
            BootstrapResponseDto bootstrapResponseDto = new bootstrapResponseDto();
    
            // some app specific logic goes here...
            return new ResponseEntity<>(bootstrapResponseDto, HttpStatus.OK);
        }
    
        @RequestMapping(value = "/v1", method = RequestMethod.POST)
        public ResponseEntity<BootstrapResponseDto> bootstrap(@RequestBody BootstrapRequestDto bootstrapRequestDto, @RequestHeader(value = "MAC-ADDRESS", required = false) String macAddress) {
    
            myAppUserDetails userDetails = SecurityContextUtils.getUserDetails();
    
            BootstrapResponseDto bootstrapResponseDto = new BootstrapResponseDto();
    
            // some app specific logic goes here...
    
            return new ResponseEntity<>(bootstrapResponseDto, HttpStatus.OK);
        }
    }
    

    【讨论】:

    • 感谢您的回复...我正在考虑这些思路(在控制器上实现 GET 方法)并且您已经确认这是解决此问题的方法。
    • 嘿,很有魅力。似乎我仍然需要重定向回前端的 JavaScript 控制器来为 UI 渲染做更多的处理;此时响应以裸 json 的形式发回浏览器。想一想如何去做?
    • @RequestMapping(value = "/v1", method = RequestMethod.GET,produces = "text/html; charset=utf-8")
    • @SBatCCOC 如果您觉得我的回答有用,请点赞。
    猜你喜欢
    • 1970-01-01
    • 2015-07-11
    • 1970-01-01
    • 2015-10-09
    • 2021-01-16
    • 2020-04-28
    • 2021-02-03
    • 2013-11-20
    • 2019-10-22
    相关资源
    最近更新 更多