Java tutorial
/* Copyright (c) 2011 Danish Maritime Authority * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this library. If not, see <http://www.gnu.org/licenses/>. */ package net.e2.bw.idreg; import net.e2.bw.idreg.client.AccessTokenData; import net.e2.bw.idreg.client.AuthErrorException; import net.e2.bw.idreg.client.OIDCClient; import net.e2.bw.idreg.client.OIDCUtils; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.PostConstruct; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.util.logging.Level; import java.util.logging.Logger; /** * Used for OpenID Connect authentication */ @Controller @SuppressWarnings("unused") public class OIDCService { private final static Logger log = Logger.getLogger(OIDCService.class.getName()); private OIDCClient oidcClient; /** * Called when the service is initialized */ @PostConstruct public void init() throws Exception { String filePath = System.getProperty("keycloak.json"); // Use keycloak.json defined by system property. Otherwise, use keycloak.json in classpath InputStream keycloakConfigFile = (filePath != null) ? new FileInputStream(new File(filePath)) : OIDCService.class.getResourceAsStream("/keycloak.json"); try (Reader configFile = new InputStreamReader(keycloakConfigFile)) { oidcClient = OIDCClient.newBuilder().configuration(configFile).customClaims("mmsi").build(); } } /** * Called in order to authenticate via OpenID Connect. * * @param request the servlet request * @param response the servlet response * @throws IOException */ @RequestMapping(value = "/oidc-login") public void oidcLogin(HttpServletRequest request, HttpServletResponse response) throws IOException { log.info("OpenID Connect login called"); OIDCUtils.nocache(response); String callbackUrl = OIDCUtils.getUrl(request, "/oidc-callback"); oidcClient.redirectToAuthServer(response, callbackUrl); } /** * The callback endpoint called by the OpenID Connect service. * * @param request the servlet request * @param response the servlet response * @throws IOException */ @RequestMapping(value = "/oidc-callback") public void oidcCallback(HttpServletRequest request, HttpServletResponse response) throws IOException { if (request.getSession() != null) { request.getSession().invalidate(); } log.info("OpenID Connect callback called"); try { OIDCUtils.nocache(response); String callbackUrl = OIDCUtils.getUrl(request, "/oidc-callback"); AccessTokenData accessTokenData = oidcClient.handleAuthServerCallback(request, callbackUrl); log.info("OpenID Connect authentication success: " + accessTokenData); request.getSession(true).setAttribute("user", accessTokenData); } catch (AuthErrorException e) { log.log(Level.SEVERE, "OpenID Connect authentication error", e); request.getSession(true).setAttribute("error", e.getMessage()); } response.sendRedirect("/"); } /** * Returns the currently logged in user * @return the currently logged in user */ @RequestMapping(value = "/user", method = RequestMethod.GET, produces = "application/json;charset=UTF-8") @ResponseBody public AccessTokenData getUser(HttpServletRequest request) { return (AccessTokenData) request.getSession(true).getAttribute("user"); } /** * Returns and removes the last error * @return the last error */ @RequestMapping(value = "/error", method = RequestMethod.GET, produces = "text/plain;charset=UTF-8") @ResponseBody public String getError(HttpServletRequest request) { if (request.getSession() != null) { String error = (String) request.getSession().getAttribute("error"); request.getSession().removeAttribute("error"); return error; } return null; } /** * Invalidates the user http session. * * @param response the servlet response * @throws IOException */ @RequestMapping(value = "/logout") public void logout(HttpServletRequest request, HttpServletResponse response) throws IOException { if (request.getSession() != null) { request.getSession().invalidate(); } response.sendRedirect("/"); } /** * Logs the user out and redirects to the auth server to log out the session there * * @param request the servlet request * @param response the servlet response * @throws IOException */ @RequestMapping(value = "/logout-auth-server") public void logoutAuthServer(HttpServletRequest request, HttpServletResponse response) throws IOException { if (request.getSession() != null) { request.getSession().invalidate(); } OIDCUtils.nocache(response); String callbackUrl = OIDCUtils.getUrl(request); oidcClient.redirectToAuthServerLogout(response, callbackUrl); } /** * Redirects to the edit-account page for the current user * * @param response the servlet response * @throws IOException */ @RequestMapping(value = "/account") public void editAccount(HttpServletRequest request, HttpServletResponse response) throws IOException { OIDCUtils.nocache(response); oidcClient.redirectToAuthServerAccount(response); } }