diff --git a/src/main/java/de/thm/arsnova/config/SecurityConfig.java b/src/main/java/de/thm/arsnova/config/SecurityConfig.java index 6f43c5b03318d87277d2ff1a0477ab7d8543cfcf..4f85089c3a28687a5ec52ac577baa698917f0d2f 100644 --- a/src/main/java/de/thm/arsnova/config/SecurityConfig.java +++ b/src/main/java/de/thm/arsnova/config/SecurityConfig.java @@ -584,6 +584,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { public OauthCallbackFilter oauthCallbackFilter() throws Exception { final OauthCallbackFilter callbackFilter = new OauthCallbackFilter(oauthConfig(), OAUTH_CALLBACK_PATH); callbackFilter.setAuthenticationManager(authenticationManager()); + callbackFilter.setAuthenticationSuccessHandler(successHandler()); + callbackFilter.setAuthenticationFailureHandler(failureHandler()); return callbackFilter; } diff --git a/src/main/java/de/thm/arsnova/controller/AuthenticationController.java b/src/main/java/de/thm/arsnova/controller/AuthenticationController.java index 7dead0ff264aa83cea65e9f328e1cb3c89f9d57b..83c08591f9d661fb50203058f7648eb1d1bf8971 100644 --- a/src/main/java/de/thm/arsnova/controller/AuthenticationController.java +++ b/src/main/java/de/thm/arsnova/controller/AuthenticationController.java @@ -18,13 +18,25 @@ package de.thm.arsnova.controller; +import java.io.IOException; +import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.pac4j.core.context.J2EContext; +import org.pac4j.oidc.client.OidcClient; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.cas.web.CasAuthenticationEntryPoint; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.View; +import org.springframework.web.servlet.view.RedirectView; +import de.thm.arsnova.config.SecurityConfig; import de.thm.arsnova.model.ClientAuthentication; import de.thm.arsnova.model.LoginCredentials; import de.thm.arsnova.model.UserProfile; @@ -34,22 +46,25 @@ import de.thm.arsnova.service.UserService; @RequestMapping("/auth") public class AuthenticationController { private UserService userService; + private OidcClient oidcClient; + private CasAuthenticationEntryPoint casEntryPoint; public AuthenticationController(final UserService userService) { this.userService = userService; } - @PostMapping("/login") - public ClientAuthentication login() { - return userService.getCurrentClientAuthentication(); + @Autowired(required = false) + public void setOidcClient(final OidcClient oidcClient) { + this.oidcClient = oidcClient; } - @PostMapping("/login/registered") - public ClientAuthentication loginRegistered(@RequestBody final LoginCredentials loginCredentials, - final HttpServletRequest request) { - final String loginId = loginCredentials.getLoginId().toLowerCase(); - userService.authenticate(new UsernamePasswordAuthenticationToken(loginId, loginCredentials.getPassword()), - UserProfile.AuthProvider.ARSNOVA, request.getRemoteAddr()); + @Autowired(required = false) + public void setCasEntryPoint(final CasAuthenticationEntryPoint casEntryPoint) { + this.casEntryPoint = casEntryPoint; + } + + @PostMapping("/login") + public ClientAuthentication login() { return userService.getCurrentClientAuthentication(); } @@ -65,4 +80,49 @@ public class AuthenticationController { return userService.getCurrentClientAuthentication(); } + + @PostMapping("/login/{providerId}") + public ClientAuthentication loginViaProvider( + @PathVariable final String providerId, + @RequestBody final LoginCredentials loginCredentials, + final HttpServletRequest request) { + switch (providerId) { + case "registered": + final String loginId = loginCredentials.getLoginId().toLowerCase(); + userService.authenticate(new UsernamePasswordAuthenticationToken( + loginId, loginCredentials.getPassword()), + UserProfile.AuthProvider.ARSNOVA, request.getRemoteAddr()); + + return userService.getCurrentClientAuthentication(); + case SecurityConfig.LDAP_PROVIDER_ID: + userService.authenticate(new UsernamePasswordAuthenticationToken( + loginCredentials.getLoginId(), loginCredentials.getPassword()), + UserProfile.AuthProvider.LDAP, request.getRemoteAddr()); + + return userService.getCurrentClientAuthentication(); + default: + throw new IllegalArgumentException("Invalid provider ID."); + } + } + + @GetMapping("/sso/{providerId}") + public View redirectToSso(@PathVariable final String providerId, + final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException { + switch (providerId) { + case SecurityConfig.OIDC_PROVIDER_ID: + if (oidcClient == null) { + throw new IllegalArgumentException("Invalid provider ID."); + } + return new RedirectView( + oidcClient.getRedirectAction(new J2EContext(request, response)).getLocation()); + case SecurityConfig.CAS_PROVIDER_ID: + if (casEntryPoint == null) { + throw new IllegalArgumentException("Invalid provider ID."); + } + casEntryPoint.commence(request, response, null); + return null; + default: + throw new IllegalArgumentException("Invalid provider ID."); + } + } } diff --git a/src/main/java/de/thm/arsnova/controller/v2/AuthenticationController.java b/src/main/java/de/thm/arsnova/controller/v2/AuthenticationController.java index 9f2782e5242c3a7a864c76c0d7c391bdece9f1dc..dd0beb4fb9ccb2e10392cd129b528ba4280c51d6 100644 --- a/src/main/java/de/thm/arsnova/controller/v2/AuthenticationController.java +++ b/src/main/java/de/thm/arsnova/controller/v2/AuthenticationController.java @@ -66,6 +66,8 @@ import de.thm.arsnova.controller.AbstractController; import de.thm.arsnova.model.ServiceDescription; import de.thm.arsnova.model.UserProfile; import de.thm.arsnova.model.migration.v2.ClientAuthentication; +import de.thm.arsnova.security.LoginAuthenticationFailureHandler; +import de.thm.arsnova.security.LoginAuthenticationSucessHandler; import de.thm.arsnova.security.User; import de.thm.arsnova.service.UserService; import de.thm.arsnova.web.exceptions.UnauthorizedException; @@ -208,8 +210,8 @@ public class AuthenticationController extends AbstractController { } } - request.getSession().setAttribute("ars-login-success-url", serverUrl + successUrl); - request.getSession().setAttribute("ars-login-failure-url", serverUrl + failureUrl); + request.getSession().setAttribute(LoginAuthenticationSucessHandler.URL_ATTRIBUTE, serverUrl + successUrl); + request.getSession().setAttribute(LoginAuthenticationFailureHandler.URL_ATTRIBUTE, serverUrl + failureUrl); if (casProperties.isEnabled() && "cas".equals(type)) { casEntryPoint.commence(request, response, null); diff --git a/src/main/java/de/thm/arsnova/security/LoginAuthenticationFailureHandler.java b/src/main/java/de/thm/arsnova/security/LoginAuthenticationFailureHandler.java index c3330f1eb8584a65b7df30059e258e77e66c6121..d5b5f1600c06d0a2544fdcdf8e15fcad0f9468e1 100644 --- a/src/main/java/de/thm/arsnova/security/LoginAuthenticationFailureHandler.java +++ b/src/main/java/de/thm/arsnova/security/LoginAuthenticationFailureHandler.java @@ -34,6 +34,7 @@ import org.springframework.security.web.authentication.SimpleUrlAuthenticationFa */ public class LoginAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { + public static final String URL_ATTRIBUTE = "ars-login-failure-url"; private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); private String failureUrl; @@ -45,8 +46,8 @@ public class LoginAuthenticationFailureHandler extends final AuthenticationException exception ) throws IOException, ServletException { final HttpSession session = request.getSession(); - if (session != null && session.getAttribute("ars-login-failure-url") != null) { - failureUrl = (String) session.getAttribute("ars-login-failure-url"); + if (session != null && session.getAttribute(URL_ATTRIBUTE) != null) { + failureUrl = (String) session.getAttribute(URL_ATTRIBUTE); } redirectStrategy.sendRedirect(request, response, failureUrl); diff --git a/src/main/java/de/thm/arsnova/security/LoginAuthenticationSucessHandler.java b/src/main/java/de/thm/arsnova/security/LoginAuthenticationSucessHandler.java index fe16ae086ac33c41e5e49466ac570a9ed877cec1..bc9f0aa10e81624492d96ae14218e8f6e97dbc6b 100644 --- a/src/main/java/de/thm/arsnova/security/LoginAuthenticationSucessHandler.java +++ b/src/main/java/de/thm/arsnova/security/LoginAuthenticationSucessHandler.java @@ -18,29 +18,55 @@ package de.thm.arsnova.security; +import java.io.IOException; +import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; +import de.thm.arsnova.security.jwt.JwtService; + /** * This class gets called when a user successfully logged in. */ public class LoginAuthenticationSucessHandler extends SimpleUrlAuthenticationSuccessHandler { + public static final String URL_ATTRIBUTE = "ars-login-success-url"; + private static final String AUTHENTICATION_ATTRIBUTE = "authentication"; + private JwtService jwtService; private String targetUrl; + @Autowired + public void setJwtService(final JwtService jwtService) { + this.jwtService = jwtService; + } + @Override protected String determineTargetUrl( final HttpServletRequest request, final HttpServletResponse response) { - final HttpSession session = request.getSession(); - if (session == null || session.getAttribute("ars-login-success-url") == null) { - return targetUrl; + final HttpSession session = request.getSession(false); + if (session == null || session.getAttribute(URL_ATTRIBUTE) == null) { + final Authentication authentication = (Authentication) request.getAttribute(AUTHENTICATION_ATTRIBUTE); + final String token = jwtService.createSignedToken((User) authentication.getPrincipal()); + return targetUrl + "?token=" + token; } - return (String) session.getAttribute("ars-login-success-url"); + final String url = (String) session.getAttribute(URL_ATTRIBUTE); + session.removeAttribute(URL_ATTRIBUTE); + + return url; + } + + @Override + public void onAuthenticationSuccess(final HttpServletRequest request, final HttpServletResponse response, + final Authentication authentication) throws IOException, ServletException { + request.setAttribute(AUTHENTICATION_ATTRIBUTE, authentication); + super.onAuthenticationSuccess(request, response, authentication); } public void setTargetUrl(final String url) {