0
votes

Using fragment of the code to redirect to the controller (/bootstrap/v1) in IdP-initiated setup:

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

Controller code fragment:

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

Debug level log fragment:

11-29-2018 13:33:53 e7a5edb2-4051-4132-bad0-856d58af1c7d ZDJhMWExYWUtZTAxNy00NDQwLWJmOTctNzcyNTJlOWUyNmQ2 INFO http-nio-8080-exec-6 Spring Security Debugger:


Request received for POST '/saml/SSO':

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

servletPath:/saml/SSO pathInfo:null headers: host: localhost:8080 user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:63.0) Gecko/20100101 Firefox/63.0 accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8 accept-language: en-US,en;q=0.5 accept-encoding: gzip, deflate content-type: application/x-www-form-urlencoded content-length: 11320 dnt: 1 connection: keep-alive cookie: JSESSIONID=ZDJhMWExYWUtZTAxNy00NDQwLWJmOTctNzcyNTJlOWUyNmQ2 upgrade-insecure-requests: 1

Security filter chain: [ MetadataGeneratorFilter
WebAsyncManagerIntegrationFilter SecurityContextPersistenceFilter
CustomLogFilter HeaderWriterFilter LogoutFilter
UsernamePasswordAuthenticationFilter BasicAuthenticationFilter
FilterChainProxy RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter SessionManagementFilter
ExceptionTranslationFilter FilterSecurityInterceptor ]


11-29-2018 13:33:53 e7a5edb2-4051-4132-bad0-856d58af1c7d INFO http-nio-8080-exec-6 o.o.c.b.s.SAMLProtocolMessageXMLSignatureSecurityPolicyRule: Validation of protocol message signature succeeded, message type: {urn:oasis:names:tc:SAML:2.0:protocol}Response 11-29-2018 13:33:53 e7a5edb2-4051-4132-bad0-856d58af1c7d ZDJhMWExYWUtZTAxNy00NDQwLWJmOTctNzcyNTJlOWUyNmQ2 INFO http-nio-8080-exec-7 Spring Security Debugger:


Request received for GET '/bootstrap/v1':

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

servletPath:/bootstrap/v1 pathInfo:null headers: host: localhost:8080 user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:63.0) Gecko/20100101 Firefox/63.0 accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8 accept-language: en-US,en;q=0.5 accept-encoding: gzip, deflate dnt: 1 connection: keep-alive cookie: JSESSIONID=ZDJhMWExYWUtZTAxNy00NDQwLWJmOTctNzcyNTJlOWUyNmQ2 upgrade-insecure-requests: 1

Security filter chain: [ MetadataGeneratorFilter
WebAsyncManagerIntegrationFilter SecurityContextPersistenceFilter
CustomLogFilter HeaderWriterFilter LogoutFilter
UsernamePasswordAuthenticationFilter BasicAuthenticationFilter
FilterChainProxy RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter SessionManagementFilter
ExceptionTranslationFilter FilterSecurityInterceptor ]


11-29-2018 13:33:53 e7a5edb2-4051-4132-bad0-856d58af1c7d WARN http-nio-8080-exec-7 o.s.w.s.PageNotFound: Request method 'GET' not supported

ExpiringUsernameAuthenticationToken set to return:

org.springframework.security.providers.ExpiringUsernameAuthenticationToken@fee70636: Principal: com.<my-company>.security.authentication.@325fcf8b; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: authority_1, authority_2, authority_3, authority_4

So, I'm guessing my SAML validation and user authentication & authorization is good.

Seem like the issue I'm facing is that HTTP GET ins't going to work.

How to configure and submit HTTP POST instead? or Should I refactor my controller to handle behavior (which could break form-based login that also part of the app's authentication)?

HTTP Status 405 - Method Not Allowed Error

1

1 Answers

1
votes

I believe this question is not at all related to SAML, but a generic Spring Security question. Also, you don't specify where the body, BootstrapRequestDto, comes from.

You have a SuccessHandler, that does a redirect:

successRedirectHandler.setDefaultTargetUrl("/bootstrap/v1"); This performs a GET

And you have a controller only accepts POST. And you haven't specified where that body comes from?

You will need to write a custom success handler that issues a post(javascript auto submit form maybe?), or just change your controller to also accept 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);
    }
}