Skip to content

Commit dc7c9c9

Browse files
committed
SAML: Show error when user doesn't have access to app
1 parent 8e1b3e8 commit dc7c9c9

File tree

6 files changed

+122
-12
lines changed

6 files changed

+122
-12
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* ContainerProxy
3+
*
4+
* Copyright (C) 2016-2020 Open Analytics
5+
*
6+
* ===========================================================================
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the Apache License as published by
10+
* The Apache Software Foundation, either version 2 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* Apache License for more details.
17+
*
18+
* You should have received a copy of the Apache License
19+
* along with this program. If not, see <http://www.apache.org/licenses/>
20+
*/
21+
package eu.openanalytics.containerproxy.auth.impl.saml;
22+
23+
import org.springframework.security.core.AuthenticationException;
24+
import org.springframework.security.saml.SAMLStatusException;
25+
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
26+
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
27+
28+
import javax.servlet.ServletException;
29+
import javax.servlet.http.HttpServletRequest;
30+
import javax.servlet.http.HttpServletResponse;
31+
import java.io.IOException;
32+
33+
public class AuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
34+
35+
public void onAuthenticationFailure(HttpServletRequest request,
36+
HttpServletResponse response, AuthenticationException exception)
37+
throws IOException, ServletException {
38+
39+
40+
if (exception.getCause() instanceof SAMLStatusException) {
41+
SAMLStatusException samlException = (SAMLStatusException) exception.getCause();
42+
43+
if (samlException.getStatusCode().equals("urn:oasis:names:tc:SAML:2.0:status:RequestDenied")) {
44+
response.sendRedirect(ServletUriComponentsBuilder.fromCurrentContextPath().path("/app-access-denied").build().toUriString());
45+
return;
46+
}
47+
}
48+
49+
super.onAuthenticationFailure(request, response, exception);
50+
}
51+
52+
}

src/main/java/eu/openanalytics/containerproxy/auth/impl/saml/SAMLConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ public SavedRequestAwareAuthenticationSuccessHandler successRedirectHandler() {
311311

312312
@Bean
313313
public SimpleUrlAuthenticationFailureHandler authenticationFailureHandler() {
314-
SimpleUrlAuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler();
314+
AuthenticationFailureHandler failureHandler = new AuthenticationFailureHandler();
315315
failureHandler.setUseForward(true);
316316
failureHandler.setDefaultFailureUrl("/error");
317317
return failureHandler;

src/main/java/eu/openanalytics/containerproxy/security/WebSecurityConfig.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,10 @@
2020
*/
2121
package eu.openanalytics.containerproxy.security;
2222

23-
import java.util.List;
24-
25-
import javax.inject.Inject;
26-
23+
import eu.openanalytics.containerproxy.auth.IAuthenticationBackend;
24+
import eu.openanalytics.containerproxy.auth.UserLogoutHandler;
2725
import org.springframework.beans.factory.annotation.Autowired;
2826
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
29-
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
3027
import org.springframework.context.annotation.Bean;
3128
import org.springframework.context.annotation.Configuration;
3229
import org.springframework.core.env.Environment;
@@ -43,8 +40,8 @@
4340
import org.springframework.security.web.header.writers.StaticHeadersWriter;
4441
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
4542

46-
import eu.openanalytics.containerproxy.auth.IAuthenticationBackend;
47-
import eu.openanalytics.containerproxy.auth.UserLogoutHandler;
43+
import javax.inject.Inject;
44+
import java.util.List;
4845

4946
@Configuration
5047
@EnableWebSecurity
@@ -61,7 +58,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
6158

6259
@Inject
6360
private Environment environment;
64-
61+
6562
@Autowired(required=false)
6663
private List<ICustomSecurityConfig> customConfigs;
6764

@@ -128,8 +125,8 @@ protected void configure(HttpSecurity http) throws Exception {
128125

129126
if (auth.hasAuthorization()) {
130127
http.authorizeRequests().antMatchers(
131-
"/login", "/signin/**", "/auth-error", "/logout-success",
132-
"/favicon.ico", "/css/**", "/img/**", "/js/**", "/assets/**", "/webjars/**").permitAll();
128+
"/login", "/signin/**", "/auth-error", "/app-access-denied", "/logout-success",
129+
"/favicon.ico", "/css/**", "/img/**", "/js/**", "/assets/**", "/webjars/**").permitAll();
133130
http
134131
.formLogin()
135132
.loginPage("/login")

src/main/java/eu/openanalytics/containerproxy/service/UserService.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ public void logout(Authentication auth) {
188188
eventService.post(EventType.Logout.toString(), userId, null);
189189
if (logoutStrategy != null) logoutStrategy.onLogout(userId);
190190
log.info(String.format("User logged out [user: %s]", userId));
191+
191192
}
192193

193194
}

src/main/java/eu/openanalytics/containerproxy/ui/AuthErrorController.java renamed to src/main/java/eu/openanalytics/containerproxy/ui/AuthController.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
import eu.openanalytics.containerproxy.api.BaseController;
3333

3434
@Controller
35-
public class AuthErrorController extends BaseController {
35+
public class AuthController extends BaseController {
3636

3737
@Inject
3838
private Environment environment;
@@ -43,4 +43,9 @@ public String getAuthErrorPage(ModelMap map, HttpServletRequest request) {
4343
return "auth-error";
4444
}
4545

46+
@RequestMapping(value = "/app-access-denied", method = RequestMethod.GET)
47+
public String getAppAccessDeniedPage(ModelMap map, HttpServletRequest request) {
48+
return "app-access-denied";
49+
}
50+
4651
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<!--
2+
3+
ContainerProxy
4+
5+
Copyright (C) 2016-2020 Open Analytics
6+
7+
===========================================================================
8+
9+
This program is free software: you can redistribute it and/or modify
10+
it under the terms of the Apache License as published by
11+
The Apache Software Foundation, either version 2 of the License, or
12+
(at your option) any later version.
13+
14+
This program is distributed in the hope that it will be useful,
15+
but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
Apache License for more details.
18+
19+
You should have received a copy of the Apache License
20+
along with this program. If not, see <http://www.apache.org/licenses/>
21+
22+
-->
23+
<!DOCTYPE html>
24+
<html
25+
xmlns:th="http://www.thymeleaf.org"
26+
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
27+
28+
<head lang="en">
29+
<title th:text="${title}"></title>
30+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
31+
<link rel="stylesheet" media="screen" th:href="@{/webjars/bootstrap/3.4.1/css/bootstrap.min.css}"/>
32+
<link rel="stylesheet" media="screen" th:href="@{/css/login.css}"/>
33+
<link rel="stylesheet" media="screen" type="text/css" href="https://cdn.jsdelivr.net/bootstrap-social/5.1.1/bootstrap-social.css"/>
34+
<link rel="stylesheet" media="screen" type="text/css" href="https://cdn.jsdelivr.net/fontawesome/4.7.0/css/font-awesome.min.css"/>
35+
<script th:src="@{/webjars/jquery/3.5.0/jquery.min.js}"></script>
36+
<script th:src="@{/webjars/bootstrap/3.4.1/js/bootstrap.min.js}"></script>
37+
</head>
38+
39+
<body>
40+
<div class="container">
41+
<h2>You do not have access to this application.</h2>
42+
<p>Your account does not have the required roles or groups required for accessing this application.</p>
43+
<p>Please contact your administrator if you believe this is a mistake.</p>
44+
</div>
45+
46+
<style>
47+
h2 {
48+
margin-bottom: 20px;
49+
margin-top: 20px;
50+
}
51+
</style>
52+
53+
</body>
54+
55+
</html>

0 commit comments

Comments
 (0)