15 changed files with 655 additions and 17 deletions
@ -0,0 +1,73 @@
@@ -0,0 +1,73 @@
|
||||
/* |
||||
* Copyright 2002-2021 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.security.saml2.provider.service.servlet; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import javax.servlet.http.HttpSession; |
||||
|
||||
import org.springframework.security.saml2.provider.service.authentication.AbstractSaml2AuthenticationRequest; |
||||
|
||||
/** |
||||
* A {@link Saml2AuthenticationRequestRepository} implementation that uses |
||||
* {@link HttpSession} to store and retrieve the |
||||
* {@link AbstractSaml2AuthenticationRequest} |
||||
* |
||||
* @author Marcus Da Coregio |
||||
* @since 5.6 |
||||
*/ |
||||
public class HttpSessionSaml2AuthenticationRequestRepository |
||||
implements Saml2AuthenticationRequestRepository<AbstractSaml2AuthenticationRequest> { |
||||
|
||||
private static final String DEFAULT_SAML2_AUTHN_REQUEST_ATTR_NAME = HttpSessionSaml2AuthenticationRequestRepository.class |
||||
.getName().concat(".SAML2_AUTHN_REQUEST"); |
||||
|
||||
private String saml2AuthnRequestAttributeName = DEFAULT_SAML2_AUTHN_REQUEST_ATTR_NAME; |
||||
|
||||
@Override |
||||
public AbstractSaml2AuthenticationRequest loadAuthenticationRequest(HttpServletRequest request) { |
||||
HttpSession httpSession = request.getSession(false); |
||||
if (httpSession == null) { |
||||
return null; |
||||
} |
||||
return (AbstractSaml2AuthenticationRequest) httpSession.getAttribute(this.saml2AuthnRequestAttributeName); |
||||
} |
||||
|
||||
@Override |
||||
public void saveAuthenticationRequest(AbstractSaml2AuthenticationRequest authenticationRequest, |
||||
HttpServletRequest request, HttpServletResponse response) { |
||||
if (authenticationRequest == null) { |
||||
removeAuthenticationRequest(request, response); |
||||
return; |
||||
} |
||||
HttpSession httpSession = request.getSession(); |
||||
httpSession.setAttribute(this.saml2AuthnRequestAttributeName, authenticationRequest); |
||||
} |
||||
|
||||
@Override |
||||
public AbstractSaml2AuthenticationRequest removeAuthenticationRequest(HttpServletRequest request, |
||||
HttpServletResponse response) { |
||||
AbstractSaml2AuthenticationRequest authenticationRequest = loadAuthenticationRequest(request); |
||||
if (authenticationRequest == null) { |
||||
return null; |
||||
} |
||||
HttpSession httpSession = request.getSession(); |
||||
httpSession.removeAttribute(this.saml2AuthnRequestAttributeName); |
||||
return authenticationRequest; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,60 @@
@@ -0,0 +1,60 @@
|
||||
/* |
||||
* Copyright 2002-2021 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.security.saml2.provider.service.servlet; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
|
||||
import org.springframework.security.saml2.provider.service.authentication.AbstractSaml2AuthenticationRequest; |
||||
|
||||
/** |
||||
* A repository for {@link AbstractSaml2AuthenticationRequest} |
||||
* |
||||
* @param <T> the type of SAML 2.0 Authentication Request |
||||
* @author Marcus Da Coregio |
||||
* @since 5.6 |
||||
*/ |
||||
public interface Saml2AuthenticationRequestRepository<T extends AbstractSaml2AuthenticationRequest> { |
||||
|
||||
/** |
||||
* Loads the {@link AbstractSaml2AuthenticationRequest} from the request |
||||
* @param request the current request |
||||
* @return the {@link AbstractSaml2AuthenticationRequest} or {@code null} if it is not |
||||
* present |
||||
*/ |
||||
T loadAuthenticationRequest(HttpServletRequest request); |
||||
|
||||
/** |
||||
* Saves the current authentication request using the {@link HttpServletRequest} and |
||||
* {@link HttpServletResponse} |
||||
* @param authenticationRequest the {@link AbstractSaml2AuthenticationRequest} |
||||
* @param request the current request |
||||
* @param response the current response |
||||
*/ |
||||
void saveAuthenticationRequest(T authenticationRequest, HttpServletRequest request, HttpServletResponse response); |
||||
|
||||
/** |
||||
* Removes the authentication request using the {@link HttpServletRequest} and |
||||
* {@link HttpServletResponse} |
||||
* @param request the current request |
||||
* @param response the current response |
||||
* @return the removed {@link AbstractSaml2AuthenticationRequest} or {@code null} if |
||||
* it is not present |
||||
*/ |
||||
T removeAuthenticationRequest(HttpServletRequest request, HttpServletResponse response); |
||||
|
||||
} |
||||
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
/* |
||||
* Copyright 2002-2021 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.security.saml2.provider.service.authentication; |
||||
|
||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration; |
||||
import org.springframework.security.saml2.provider.service.registration.TestRelyingPartyRegistrations; |
||||
|
||||
/** |
||||
* Tests instances for {@link Saml2AuthenticationToken} |
||||
* |
||||
* @author Marcus Da Coregio |
||||
*/ |
||||
public final class TestSaml2AuthenticationTokens { |
||||
|
||||
private TestSaml2AuthenticationTokens() { |
||||
} |
||||
|
||||
public static Saml2AuthenticationToken token() { |
||||
RelyingPartyRegistration relyingPartyRegistration = TestRelyingPartyRegistrations.relyingPartyRegistration() |
||||
.build(); |
||||
return new Saml2AuthenticationToken(relyingPartyRegistration, "saml2-xml-response-object"); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,143 @@
@@ -0,0 +1,143 @@
|
||||
/* |
||||
* Copyright 2002-2021 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.security.saml2.provider.service.servlet; |
||||
|
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest; |
||||
import org.springframework.mock.web.MockHttpServletResponse; |
||||
import org.springframework.mock.web.MockHttpSession; |
||||
import org.springframework.security.saml2.provider.service.authentication.AbstractSaml2AuthenticationRequest; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.mockito.ArgumentMatchers.anyString; |
||||
import static org.mockito.BDDMockito.given; |
||||
import static org.mockito.Mockito.mock; |
||||
import static org.mockito.Mockito.verify; |
||||
|
||||
/** |
||||
* @author Marcus Da Coregio |
||||
*/ |
||||
public class HttpSessionSaml2AuthenticationRequestRepositoryTests { |
||||
|
||||
private static final String IDP_SSO_URL = "https://sso-url.example.com/IDP/SSO"; |
||||
|
||||
private MockHttpServletRequest request; |
||||
|
||||
private MockHttpServletResponse response; |
||||
|
||||
private HttpSessionSaml2AuthenticationRequestRepository authenticationRequestRepository; |
||||
|
||||
@BeforeEach |
||||
public void setup() { |
||||
this.request = new MockHttpServletRequest(); |
||||
this.response = new MockHttpServletResponse(); |
||||
this.authenticationRequestRepository = new HttpSessionSaml2AuthenticationRequestRepository(); |
||||
} |
||||
|
||||
@Test |
||||
public void loadAuthenticationRequestWhenInvalidSessionThenNull() { |
||||
AbstractSaml2AuthenticationRequest authenticationRequest = this.authenticationRequestRepository |
||||
.loadAuthenticationRequest(this.request); |
||||
assertThat(authenticationRequest).isNull(); |
||||
} |
||||
|
||||
@Test |
||||
public void loadAuthenticationRequestWhenNoAttributeInSessionThenNull() { |
||||
this.request.getSession(); |
||||
AbstractSaml2AuthenticationRequest authenticationRequest = this.authenticationRequestRepository |
||||
.loadAuthenticationRequest(this.request); |
||||
assertThat(authenticationRequest).isNull(); |
||||
} |
||||
|
||||
@Test |
||||
public void loadAuthenticationRequestWhenAttributeInSessionThenReturnsAuthenticationRequest() { |
||||
AbstractSaml2AuthenticationRequest mockAuthenticationRequest = mock(AbstractSaml2AuthenticationRequest.class); |
||||
given(mockAuthenticationRequest.getAuthenticationRequestUri()).willReturn(IDP_SSO_URL); |
||||
this.request.getSession(); |
||||
this.authenticationRequestRepository.saveAuthenticationRequest(mockAuthenticationRequest, this.request, |
||||
this.response); |
||||
AbstractSaml2AuthenticationRequest authenticationRequest = this.authenticationRequestRepository |
||||
.loadAuthenticationRequest(this.request); |
||||
assertThat(authenticationRequest.getAuthenticationRequestUri()).isEqualTo(IDP_SSO_URL); |
||||
} |
||||
|
||||
@Test |
||||
public void saveAuthenticationRequestWhenSessionDontExistsThenCreateAndSave() { |
||||
AbstractSaml2AuthenticationRequest mockAuthenticationRequest = mock(AbstractSaml2AuthenticationRequest.class); |
||||
this.authenticationRequestRepository.saveAuthenticationRequest(mockAuthenticationRequest, this.request, |
||||
this.response); |
||||
AbstractSaml2AuthenticationRequest authenticationRequest = this.authenticationRequestRepository |
||||
.loadAuthenticationRequest(this.request); |
||||
assertThat(authenticationRequest).isNotNull(); |
||||
} |
||||
|
||||
@Test |
||||
public void saveAuthenticationRequestWhenSessionExistsThenSave() { |
||||
AbstractSaml2AuthenticationRequest mockAuthenticationRequest = mock(AbstractSaml2AuthenticationRequest.class); |
||||
this.request.getSession(); |
||||
this.authenticationRequestRepository.saveAuthenticationRequest(mockAuthenticationRequest, this.request, |
||||
this.response); |
||||
AbstractSaml2AuthenticationRequest authenticationRequest = this.authenticationRequestRepository |
||||
.loadAuthenticationRequest(this.request); |
||||
assertThat(authenticationRequest).isNotNull(); |
||||
} |
||||
|
||||
@Test |
||||
public void saveAuthenticationRequestWhenNullAuthenticationRequestThenDontSave() { |
||||
this.request.getSession(); |
||||
this.authenticationRequestRepository.saveAuthenticationRequest(null, this.request, this.response); |
||||
AbstractSaml2AuthenticationRequest authenticationRequest = this.authenticationRequestRepository |
||||
.loadAuthenticationRequest(this.request); |
||||
assertThat(authenticationRequest).isNull(); |
||||
} |
||||
|
||||
@Test |
||||
public void removeAuthenticationRequestWhenInvalidSessionThenReturnNull() { |
||||
AbstractSaml2AuthenticationRequest authenticationRequest = this.authenticationRequestRepository |
||||
.removeAuthenticationRequest(this.request, this.response); |
||||
assertThat(authenticationRequest).isNull(); |
||||
} |
||||
|
||||
@Test |
||||
public void removeAuthenticationRequestWhenAttributeInSessionThenRemoveAuthenticationRequest() { |
||||
AbstractSaml2AuthenticationRequest mockAuthenticationRequest = mock(AbstractSaml2AuthenticationRequest.class); |
||||
given(mockAuthenticationRequest.getAuthenticationRequestUri()).willReturn(IDP_SSO_URL); |
||||
this.request.getSession(); |
||||
this.authenticationRequestRepository.saveAuthenticationRequest(mockAuthenticationRequest, this.request, |
||||
this.response); |
||||
AbstractSaml2AuthenticationRequest authenticationRequest = this.authenticationRequestRepository |
||||
.removeAuthenticationRequest(this.request, this.response); |
||||
AbstractSaml2AuthenticationRequest authenticationRequestAfterRemove = this.authenticationRequestRepository |
||||
.loadAuthenticationRequest(this.request); |
||||
assertThat(authenticationRequest.getAuthenticationRequestUri()).isEqualTo(IDP_SSO_URL); |
||||
assertThat(authenticationRequestAfterRemove).isNull(); |
||||
} |
||||
|
||||
@Test |
||||
public void removeAuthenticationRequestWhenValidSessionNoAttributeThenReturnsNull() { |
||||
MockHttpSession session = mock(MockHttpSession.class); |
||||
MockHttpServletRequest request = new MockHttpServletRequest(); |
||||
request.setSession(session); |
||||
AbstractSaml2AuthenticationRequest authenticationRequest = this.authenticationRequestRepository |
||||
.removeAuthenticationRequest(request, this.response); |
||||
verify(session).getAttribute(anyString()); |
||||
assertThat(authenticationRequest).isNull(); |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue