/* * Copyright 2016 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * 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 * * http://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.keycloak.testsuite.adapter.servlet; import org.jboss.resteasy.annotations.cache.NoCache; import org.keycloak.adapters.saml.SamlAuthenticationError; import org.keycloak.adapters.saml.SamlPrincipal; import org.keycloak.adapters.spi.AuthenticationError; import org.keycloak.saml.processing.core.saml.v2.constants.X500SAMLProfileConstants; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.io.IOException; import java.security.Principal; import java.util.Arrays; import java.util.Collections; import java.util.List; /** * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author mhajas * @version $Revision: 1 $ */ @Path("/") public class SendUsernameServlet { private static boolean checkRoles = false; private static SamlAuthenticationError authError; private static Principal sentPrincipal; private static List<String> checkRolesList = Collections.singletonList("manager"); @Context private HttpServletRequest httpServletRequest; @GET @NoCache public Response doGet(@QueryParam("checkRoles") boolean checkRolesFlag) throws ServletException, IOException { System.out.println("In SendUsername Servlet doGet() check roles is " + (checkRolesFlag || checkRoles)); if (httpServletRequest.getUserPrincipal() != null && (checkRolesFlag || checkRoles) && !checkRoles()) { return Response.status(Response.Status.FORBIDDEN).entity("Forbidden").build(); } return Response.ok(getOutput()).header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_HTML_TYPE + ";charset=UTF-8").build(); } @POST @NoCache public Response doPost(@QueryParam("checkRoles") boolean checkRolesFlag) throws ServletException, IOException { System.out.println("In SendUsername Servlet doPost() check roles is " + (checkRolesFlag || checkRoles)); if (httpServletRequest.getUserPrincipal() != null && (checkRolesFlag || checkRoles) && !checkRoles()) { throw new RuntimeException("User: " + httpServletRequest.getUserPrincipal() + " do not have required role"); } return Response.ok(getOutput()).header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_HTML_TYPE + ";charset=UTF-8").build(); } @GET @Path("getAttributes") public Response getSentPrincipal() throws IOException { System.out.println("In SendUsername Servlet getSentPrincipal()"); sentPrincipal = httpServletRequest.getUserPrincipal(); return Response.ok(getAttributes()).header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_HTML_TYPE + ";charset=UTF-8").build(); } @GET @Path("{path}") public Response doGetElseWhere(@PathParam("path") String path, @QueryParam("checkRoles") boolean checkRolesFlag) throws ServletException, IOException { System.out.println("In SendUsername Servlet doGetElseWhere() - path: " + path); return doGet(checkRolesFlag); } @POST @Path("{path}") public Response doPostElseWhere(@PathParam("path") String path, @QueryParam("checkRoles") boolean checkRolesFlag) throws ServletException, IOException { System.out.println("In SendUsername Servlet doPostElseWhere() - path: " + path); return doPost(checkRolesFlag); } @POST @Path("error.html") public Response errorPagePost() { authError = (SamlAuthenticationError) httpServletRequest.getAttribute(AuthenticationError.class.getName()); Integer statusCode = (Integer) httpServletRequest.getAttribute("javax.servlet.error.status_code"); System.out.println("In SendUsername Servlet errorPage() status code: " + statusCode); return Response.ok(getErrorOutput(statusCode)).header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_HTML_TYPE + ";charset=UTF-8").build(); } @GET @Path("error.html") public Response errorPageGet() { return errorPagePost(); } @GET @Path("checkRoles") public String checkRolesEndPoint() { checkRoles = true; System.out.println("Setting checkRoles to true"); return "Roles will be checked"; } @GET @Path("uncheckRoles") public String uncheckRolesEndPoint() { checkRoles = false; System.out.println("Setting checkRoles to false"); checkRolesList = Collections.singletonList("manager"); return "Roles will not be checked"; } @GET @Path("setCheckRoles") public String setCheckRoles(@QueryParam("roles") String roles) { checkRolesList = Arrays.asList(roles.split(",")); checkRoles = true; System.out.println("Setting checkRolesList to " + checkRolesList.toString()); return "These roles will be checked: " + checkRolesList.toString(); } private boolean checkRoles() { for (String role : checkRolesList) { System.out.println("In checkRoles() checking role " + role + " for user " + httpServletRequest.getUserPrincipal().getName()); if (!httpServletRequest.isUserInRole(role)) { System.out.println("User is not in role " + role); return false; } } return true; } private String getOutput() { String output = "request-path: "; output += httpServletRequest.getServletPath(); output += "\n"; output += "principal="; Principal principal = httpServletRequest.getUserPrincipal(); if (principal == null) { return output + "null"; } sentPrincipal = principal; return output + principal.getName(); } private String getErrorOutput(Integer statusCode) { String output = "<html><head><title>Error Page</title></head><body><h1>There was an error</h1>"; if (statusCode != null) output += "<br/>HTTP status code: " + statusCode; if (authError != null) output += "<br/>Error info: " + authError.toString(); return output + "</body></html>"; } private String getAttributes() { SamlPrincipal principal = (SamlPrincipal) sentPrincipal; String output = "attribute email: " + principal.getAttribute(X500SAMLProfileConstants.EMAIL.get()); output += "<br /> topAttribute: " + principal.getAttribute("topAttribute"); output += "<br /> boolean-attribute: " + principal.getAttribute("boolean-attribute"); output += "<br /> level2Attribute: " + principal.getAttribute("level2Attribute"); output += "<br /> group: " + principal.getAttributes("group").toString(); output += "<br /> friendlyAttribute email: " + principal.getFriendlyAttribute("email"); output += "<br /> phone: " + principal.getAttribute("phone"); output += "<br /> friendlyAttribute phone: " + principal.getFriendlyAttribute("phone"); output += "<br /> hardcoded-attribute: "; for (String attr : principal.getAttributes("hardcoded-attribute")) { output += attr + ","; } return output; } }