Apereo CAS 5.3.x: how to get logged user, from CAS server, after login in java cas client

Viewed 3283

Following the official Apereo CAS documentation. I ca not understand (after various research and guides).

How to recover the user just logged in after authentication. The authentication and the SSO between projects work correctly. But I can not get information about logged user.

Here my configuration on Application.properties:

##
# CAS Server Context Configuration
#
server.context-path=/cas
server.port=8443
server.ssl.key-store=file:/etc/cas/thekeystore
server.ssl.key-store-password=changeit
server.ssl.key-password=changeit
server.max-http-header-size=2097152
server.use-forward-headers=true
server.connection-timeout=20000
server.error.include-stacktrace=ALWAYS
server.compression.enabled=true
server.compression.mime-types=application/javascript,application/json,application/xml,text/html,text/xml,text/plain
server.tomcat.max-http-post-size=2097152
server.tomcat.basedir=build/tomcat
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%t %a "%r" %s (%D ms)
server.tomcat.accesslog.suffix=.log
server.tomcat.min-spare-threads=10
server.tomcat.max-threads=200
server.tomcat.port-header=X-Forwarded-Port
server.tomcat.protocol-header=X-Forwarded-Proto
server.tomcat.protocol-header-https-value=https
server.tomcat.remote-ip-header=X-FORWARDED-FOR
server.tomcat.uri-encoding=UTF-8
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true

##
# CAS Cloud Bus Configuration
#
spring.cloud.bus.enabled=false

# Indicates that systemPropertiesOverride can be used.
# Set to false to prevent users from changing the default accidentally. Default true.
spring.cloud.config.allow-override=true

# External properties should override system properties.
spring.cloud.config.override-system-properties=false

# When allowOverride is true, external properties should take lowest priority, and not override any
# existing property sources (including local config files).
spring.cloud.config.override-none=false

# spring.cloud.bus.refresh.enabled=true
# spring.cloud.bus.env.enabled=true
# spring.cloud.bus.destination=CasCloudBus
# spring.cloud.bus.ack.enabled=true

endpoints.enabled=false
endpoints.sensitive=true

endpoints.restart.enabled=false
endpoints.shutdown.enabled=false

# Control the security of the management/actuator endpoints
# The 'enabled' flag below here controls the rendering of details for the health endpoint amongst other things.
management.security.enabled=true
management.security.roles=ACTUATOR,ADMIN
management.security.sessions=if_required
management.context-path=/status
management.add-application-context-header=false

# Define a CAS-specific "WARN" status code and its order
management.health.status.order=WARN, DOWN, OUT_OF_SERVICE, UNKNOWN, UP

# Control the security of the management/actuator endpoints
# With basic authentication, assuming Spring Security and/or relevant modules are on the classpath.
security.basic.authorize-mode=role
security.basic.path=/cas/status/**
# security.basic.enabled=true
# security.user.name=casuser
# security.user.password=

##
# CAS Web Application Session Configuration
#
server.session.timeout=300
server.session.cookie.http-only=true
server.session.tracking-modes=COOKIE

##
# CAS Thymeleaf View Configuration
#
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.cache=true
spring.thymeleaf.mode=HTML
spring.thymeleaf.template-resolver-order=100
##
# CAS Log4j Configuration
#
# logging.config=file:/etc/cas/log4j2.xml
server.context-parameters.isLog4jAutoInitializationDisabled=true

##
# CAS AspectJ Configuration
#
spring.aop.auto=true
spring.aop.proxy-target-class=true

##
# CAS Authentication Credentials
#
# cas.authn.accept.users=casuser::Mellon

cas.authn.accept.users=
logging.level.org.apereo=DEBUG

cas.authn.jdbc.query[0].sql=SELECT * FROM USERS WHERE uid=?
cas.authn.jdbc.query[0].url=jdbc:mysql://localhost:3306/casdatabase?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.MySQLDialect
cas.authn.jdbc.query[0].user=cas
cas.authn.jdbc.query[0].password=cas
cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver
cas.authn.jdbc.query[0].fieldPassword=psw

cas.authn.jdbc.query[0].passwordEncoder.type=DEFAULT
cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm=MD5
cas.authn.jdbc.query[0].passwordEncoder.characterEncoding=UTF-8

# Services
 cas.serviceRegistry.watcherEnabled=true
 cas.serviceRegistry.schedule.repeatInterval=120000
 cas.serviceRegistry.schedule.startDelay=15000

# Auto-initialize the registry from default JSON service definitions
 cas.serviceRegistry.initFromJson=true

#cas.serviceRegistry.managementType=DEFAULT|DOMAIN
cas.serviceRegistry.managementType=DEFAULT
cas.serviceRegistry.json.location=WEB-INF/classes/services


cas.tgc.path=/
cas.tgc.maxAge=-1
cas.tgc.domain=www.myDomain.it
cas.tgc.name=TGC
cas.tgc.secure=true
cas.tgc.httpOnly=false
cas.tgc.rememberMeMaxAge=1209600

Here my registered service in JSON on my CAS server (compA-10000003.json)

{
  "@class" : "org.apereo.cas.services.RegexRegisteredService",
  "serviceId" : "^https://www.myproject.com:8443/compA/servlet",
  "name" : "compA",
  "theme" : "apereo",
  "id" : 10000003,
  "description" : "descrizione servizio compA",
  "evaluationOrder" : 10000
}

Here my web.xml CAS client java application:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
    <servlet>
        <servlet-name>servlet</servlet-name>
        <servlet-class>it.seed.compa.servlet</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>logout</servlet-name>
        <servlet-class>it.seed.compa.logout</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>login</servlet-name>
        <servlet-class>it.seed.compa.login</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>servlet</servlet-name>
        <url-pattern>/servlet</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>logout</servlet-name>
        <url-pattern>/logout</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>login</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>
   <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <!--filter>
        <filter-name>CAS Filter</filter-name>
        <filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>
        <init-param>
            <param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>
            <param-value>https://192.168.91.42:8443/apereoCAS/login</param-value>
        </init-param>
        <init-param>
            <param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
            <param-value>https://192.168.91.42:8443/apereoCAS/serviceValidate</param-value>
        </init-param>
        <init-param>
            <param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
            <param-value>192.168.91.98:8084</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>CAS Filter</filter-name>
        <url-pattern>/servlet</url-pattern>
    </filter-mapping-->

    <filter>
        <filter-name>CAS Single Sign Out Filter</filter-name>
        <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
        <init-param>
            <param-name>casServerUrlPrefix</param-name>
            <param-value>https://www.cas.server.glauco.it:8443/apereoCAS</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CAS Single Sign Out Filter</filter-name>
        <url-pattern>/logout</url-pattern>
    </filter-mapping>


    <!-- Listener to clean sessions -->
    <listener>
        <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener
        </listener-class>
    </listener>


    <!-- Define the protected urls of your application -->
    <!-- #### change with your own CAS server and your host name #### -->
    <filter>
        <filter-name>CAS Authentication Filter</filter-name>
        <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
        <init-param>
            <param-name>casServerLoginUrl</param-name>
            <param-value>https://www.cas.server.glauco.it:8443/apereoCAS/login
            </param-value>
        </init-param>
        <init-param>
            <param-name>serverName</param-name>
            <param-value>https://www.progetto2.glauco.it:8443</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CAS Authentication Filter</filter-name>
        <url-pattern>/servlet</url-pattern>
    </filter-mapping>




    <!-- Define the urls on which you can validate a service ticket -->
    <!-- #### change with your own CAS server and your host name #### -->
    <filter>
        <filter-name>CAS Validation Filter</filter-name>
        <filter-class>org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter</filter-class>
        <init-param>
            <param-name>casServerUrlPrefix</param-name>
            <param-value>https://www.cas.server.glauco.it:8443/apereoCAS</param-value>
        </init-param>



        <init-param>
            <param-name>redirectAfterValidation</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>useSession</param-name>
            <param-value>true</param-value>
        </init-param>



        <init-param>
            <param-name>serverName</param-name>
            <param-value>https://www.progetto2.glauco.it:8443</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CAS Validation Filter</filter-name>
        <url-pattern>/p</url-pattern>
    </filter-mapping>



    <!-- Put the CAS principal in the HTTP request -->
    <filter>
        <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
        <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
        <url-pattern>/* </url-pattern>
    </filter-mapping>
</web-app>

Finally the servlet where I try to read informations about logged user:

package it.seed.compa;


import com.google.gson.Gson;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.authentication.AttributePrincipalImpl;
import org.jasig.cas.client.authentication.SimplePrincipal;

public class servlet extends HttpServlet {


    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        try (PrintWriter out = response.getWriter()) {

            Gson g = new Gson();

            System.out.println(  g.toJson(request.getCookies())  );
            System.out.println("-----------getParameterMap-------------------");
            System.out.println(  g.toJson(request.getParameterMap() )  );
            System.out.println("----------------getParameterNames--------------");
            System.out.println(  g.toJson(request.getParameterNames() )  );
            System.out.println("---------------getQueryString---------------");
            System.out.println(  g.toJson(request.getQueryString() )  );
            System.out.println("------------getSession------------------");
            System.out.println(  g.toJson(request.getSession() )  );
            System.out.println("------------getRemoteUser------------------");
            System.out.println(  request.getRemoteUser()  );

            System.out.println("------------getParameter principal------------------");
            System.out.println(  request.getParameter("principal")  );

            System.out.println("------------getParameter id------------------");
            System.out.println(  request.getParameter("id")  );

            System.out.println("response");


            /* TODO output your page here. You may use following sample code. */
            out.println("<!DOCTYPE html>");
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet servlet</title>");            
            out.println("</head>");
            out.println("<body>");

            System.out.println(request.getParameter("ticket"));

            if(request.getUserPrincipal() != null) // this is always NULL
            {
                AttributePrincipal principal = (AttributePrincipal)request.getUserPrincipal();

                Map attributes = principal.getAttributes();

                Iterator attributeNames = attributes.keySet().iterator();

                out.println("<table>");

                for (; attributeNames.hasNext();) {
                out.println("<tr><th>");
                String attributeName = (String) attributeNames.next();
                      out.println(attributeName);
                      out.println("</th><td>");
                      Object attributeValue = attributes.get(attributeName);
                      out.println(attributeValue);
                      out.println("</td></tr>");
                }

                out.println("</table>");

            } else{
                System.out.println("nothing");
            }


            out.println("</body>");
            out.println("</html>");
        }
    }


    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    public String getServletInfo() {
        return "Short description";
    }

}

Can someone help me to retrieve the logged user?

1 Answers

The code is already in the your servlet. After CAS successfully validates the service ticket it created, the user information is present in the "AttributePrincipal" object.

you already have

 AttributePrincipal principal = (AttributePrincipal)request.getUserPrincipal();

Which will give you the principal. The name used for logging in can then be fetched using

String userName = principal.getName();
Related