001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.security.auth;
016    
017    import com.liferay.portal.kernel.util.GetterUtil;
018    import com.liferay.portal.kernel.util.ParamUtil;
019    import com.liferay.portal.kernel.util.PwdGenerator;
020    import com.liferay.portal.kernel.util.Validator;
021    import com.liferay.portal.kernel.util.WebKeys;
022    import com.liferay.portal.service.permission.PortletPermissionUtil;
023    import com.liferay.portal.util.PortalUtil;
024    import com.liferay.portal.util.PropsValues;
025    import com.liferay.portlet.SecurityPortletContainerWrapper;
026    
027    import javax.servlet.http.HttpServletRequest;
028    import javax.servlet.http.HttpSession;
029    
030    /**
031     * @author Amos Fong
032     */
033    public class SessionAuthToken implements AuthToken {
034    
035            /**
036             * @deprecated As of 7.0.0
037             */
038            @Deprecated
039            @Override
040            public void check(HttpServletRequest request) throws PrincipalException {
041                    checkCSRFToken(
042                            request, SecurityPortletContainerWrapper.class.getName());
043            }
044    
045            @Override
046            public void checkCSRFToken(HttpServletRequest request, String origin)
047                    throws PrincipalException {
048    
049                    if (!PropsValues.AUTH_TOKEN_CHECK_ENABLED) {
050                            return;
051                    }
052    
053                    String sharedSecret = ParamUtil.getString(request, "p_auth_secret");
054    
055                    if (AuthTokenWhitelistUtil.isValidSharedSecret(sharedSecret)) {
056                            return;
057                    }
058    
059                    long companyId = PortalUtil.getCompanyId(request);
060    
061                    if (AuthTokenWhitelistUtil.isCSRFOrigintWhitelisted(
062                                    companyId, origin)) {
063    
064                            return;
065                    }
066    
067                    if (origin.equals(SecurityPortletContainerWrapper.class.getName())) {
068                            String ppid = ParamUtil.getString(request, "p_p_id");
069    
070                            String portletNamespace = PortalUtil.getPortletNamespace(ppid);
071    
072                            String strutsAction = ParamUtil.getString(
073                                    request, portletNamespace + "struts_action");
074    
075                            if (AuthTokenWhitelistUtil.isPortletCSRFWhitelisted(
076                                            companyId, ppid, strutsAction)) {
077    
078                                    return;
079                            }
080                    }
081    
082                    String csrfToken = ParamUtil.getString(request, "p_auth");
083    
084                    if (Validator.isNull(csrfToken)) {
085                            csrfToken = GetterUtil.getString(request.getHeader("X-CSRF-Token"));
086                    }
087    
088                    String sessionToken = getSessionAuthenticationToken(
089                            request, _CSRF, false);
090    
091                    if (!csrfToken.equals(sessionToken)) {
092                            throw new PrincipalException("Invalid authentication token");
093                    }
094            }
095    
096            @Override
097            public String getToken(HttpServletRequest request) {
098                    return getSessionAuthenticationToken(request, _CSRF, true);
099            }
100    
101            @Override
102            public String getToken(
103                    HttpServletRequest request, long plid, String portletId) {
104    
105                    return getSessionAuthenticationToken(
106                            request, PortletPermissionUtil.getPrimaryKey(plid, portletId),
107                            true);
108            }
109    
110            @Override
111            public boolean isValidPortletInvocationToken(
112                    HttpServletRequest request, long plid, String portletId,
113                    String strutsAction, String tokenValue) {
114    
115                    long companyId = PortalUtil.getCompanyId(request);
116    
117                    if (AuthTokenWhitelistUtil.isPortletInvocationWhitelisted(
118                                    companyId, portletId, strutsAction)) {
119    
120                            return true;
121                    }
122    
123                    if (Validator.isNotNull(tokenValue)) {
124                            String key = PortletPermissionUtil.getPrimaryKey(plid, portletId);
125    
126                            String sessionToken = getSessionAuthenticationToken(
127                                    request, key, false);
128    
129                            if (Validator.isNotNull(sessionToken) &&
130                                    sessionToken.equals(tokenValue)) {
131    
132                                    return true;
133                            }
134                    }
135    
136                    return false;
137            }
138    
139            protected String getSessionAuthenticationToken(
140                    HttpServletRequest request, String key, boolean createToken) {
141    
142                    HttpSession session = request.getSession();
143    
144                    String tokenKey = WebKeys.AUTHENTICATION_TOKEN.concat(key);
145    
146                    String sessionAuthenticationToken = (String)session.getAttribute(
147                            tokenKey);
148    
149                    if (createToken && Validator.isNull(sessionAuthenticationToken)) {
150                            sessionAuthenticationToken = PwdGenerator.getPassword(
151                                    PropsValues.AUTH_TOKEN_LENGTH);
152    
153                            session.setAttribute(tokenKey, sessionAuthenticationToken);
154                    }
155    
156                    return sessionAuthenticationToken;
157            }
158    
159            private static final String _CSRF = "#CSRF";
160    
161    }