abstractauthenticator.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 796 行 · 第 1/2 页
JAVA
796 行
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source 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, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */package com.caucho.server.security;import com.caucho.security.BasicPrincipal;import com.caucho.server.session.SessionImpl;import com.caucho.server.session.SessionManager;import com.caucho.server.webapp.Application;import com.caucho.util.Alarm;import com.caucho.util.L10N;import com.caucho.util.LruCache;import com.caucho.webbeans.component.*;import javax.annotation.PostConstruct;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import java.lang.ref.SoftReference;import java.security.MessageDigest;import java.security.Principal;import java.util.ArrayList;import java.util.logging.Level;import java.util.logging.Logger;/** * All applications should extend AbstractAuthenticator to implement * their custom authenticators. While this isn't absolutely required, * it protects implementations from API changes. * * <p>The AbstractAuthenticator provides a single-signon cache. Users * logged into one web-app will share the same principal. */public class AbstractAuthenticator implements ServletAuthenticator, HandleAware, java.io.Serializable{ private static final Logger log = Logger.getLogger(AbstractAuthenticator.class.getName()); static final L10N L = new L10N(AbstractAuthenticator.class); public static final String LOGIN_NAME = "com.caucho.servlet.login.name"; protected int _principalCacheSize = 4096; protected LruCache<String,PrincipalEntry> _principalCache; protected String _passwordDigestAlgorithm = "MD5-base64"; protected String _passwordDigestRealm = "resin"; protected PasswordDigest _passwordDigest; private boolean _logoutOnTimeout = true; private Object _serializationHandle; /** * Returns the size of the principal cache. */ public int getPrincipalCacheSize() { return _principalCacheSize; } /** * Sets the size of the principal cache. */ public void setPrincipalCacheSize(int size) { _principalCacheSize = size; } /** * Returns the password digest */ public PasswordDigest getPasswordDigest() { return _passwordDigest; } /** * Sets the password digest. The password digest of the form: * "algorithm-format", e.g. "MD5-base64". */ public void setPasswordDigest(PasswordDigest digest) { _passwordDigest = digest; } /** * Returns the password digest algorithm */ public String getPasswordDigestAlgorithm() { return _passwordDigestAlgorithm; } /** * Sets the password digest algorithm. The password digest of the form: * "algorithm-format", e.g. "MD5-base64". */ public void setPasswordDigestAlgorithm(String digest) { _passwordDigestAlgorithm = digest; } /** * Returns the password digest realm */ public String getPasswordDigestRealm() { return _passwordDigestRealm; } /** * Sets the password digest realm. */ public void setPasswordDigestRealm(String realm) { _passwordDigestRealm = realm; } /** * Returns true if the user should be logged out on a session timeout. */ public boolean getLogoutOnSessionTimeout() { return _logoutOnTimeout; } /** * Sets true if the principal should logout when the session times out. */ public void setLogoutOnSessionTimeout(boolean logout) { _logoutOnTimeout = logout; } /** * Adds a role mapping. */ public void addRoleMapping(Principal principal, String role) { } /** * Initialize the authenticator with the application. */ @PostConstruct public void init() throws ServletException { if (_principalCacheSize > 0) _principalCache = new LruCache<String,PrincipalEntry>(_principalCacheSize); if (_passwordDigest != null) { if (_passwordDigest.getAlgorithm() == null || _passwordDigest.getAlgorithm().equals("none")) _passwordDigest = null; } else if (_passwordDigestAlgorithm == null || _passwordDigestAlgorithm.equals("none")) { } else { int p = _passwordDigestAlgorithm.indexOf('-'); if (p > 0) { String algorithm = _passwordDigestAlgorithm.substring(0, p); String format = _passwordDigestAlgorithm.substring(p + 1); _passwordDigest = new PasswordDigest(); _passwordDigest.setAlgorithm(algorithm); _passwordDigest.setFormat(format); _passwordDigest.setRealm(_passwordDigestRealm); _passwordDigest.init(); } } } /** * Logs the user in with any appropriate password. */ public Principal login(HttpServletRequest request, HttpServletResponse response, ServletContext app, String user, String password) throws ServletException { String digestPassword = getPasswordDigest(request, response, app, user, password); Principal principal = loginImpl(request, response, app, user, digestPassword); if (principal != null) { SessionImpl session = (SessionImpl) request.getSession(); session.setUser(principal); if (_principalCache != null) { PrincipalEntry entry = new PrincipalEntry(principal); entry.addSession(session); _principalCache.put(session.getId(), entry); } } return principal; } /** * Returns the digest view of the password. The default * uses the PasswordDigest class if available, and returns the * plaintext password if not. */ public String getPasswordDigest(HttpServletRequest request, HttpServletResponse response, ServletContext app, String user, String password) throws ServletException { if (_passwordDigest != null) return _passwordDigest.getPasswordDigest(request, response, app, user, password); else return password; } /** * Authenticate (login) the user. */ protected Principal loginImpl(HttpServletRequest request, HttpServletResponse response, ServletContext application, String user, String password) throws ServletException { return null; } /** * Validates the user when using HTTP Digest authentication. * DigestLogin will call this method. Most other AbstractLogin * implementations, like BasicLogin and FormLogin, will use * getUserPrincipal instead. * * <p>The HTTP Digest authentication uses the following algorithm * to calculate the digest. The digest is then compared to * the client digest. * * <code><pre> * A1 = MD5(username + ':' + realm + ':' + password) * A2 = MD5(method + ':' + uri) * digest = MD5(A1 + ':' + nonce + A2) * </pre></code> * * @param request the request trying to authenticate. * @param response the response for setting headers and cookies. * @param app the servlet context * @param user the username * @param realm the authentication realm * @param nonce the nonce passed to the client during the challenge * @param uri te protected uri * @param qop * @param nc * @param cnonce the client nonce * @param clientDigest the client's calculation of the digest * * @return the logged in principal if successful */ public Principal loginDigest(HttpServletRequest request, HttpServletResponse response, ServletContext app, String user, String realm, String nonce, String uri, String qop, String nc, String cnonce, byte []clientDigest) throws ServletException { Principal principal = loginDigestImpl(request, response, app, user, realm, nonce, uri, qop, nc, cnonce, clientDigest); if (principal != null) { SessionImpl session = (SessionImpl) request.getSession(); session.setUser(principal); if (_principalCache != null) { PrincipalEntry entry = new PrincipalEntry(principal); entry.addSession(session); _principalCache.put(session.getId(), entry); } } return principal; } /** * Validates the user when HTTP Digest authentication. * The HTTP Digest authentication uses the following algorithm * to calculate the digest. The digest is then compared to * the client digest. * * <code><pre> * A1 = MD5(username + ':' + realm + ':' + password) * A2 = MD5(method + ':' + uri) * digest = MD5(A1 + ':' + nonce + A2) * </pre></code> * * @param request the request trying to authenticate. * @param response the response for setting headers and cookies. * @param app the servlet context * @param user the username * @param realm the authentication realm * @param nonce the nonce passed to the client during the challenge * @param uri te protected uri * @param qop * @param nc * @param cnonce the client nonce * @param clientDigest the client's calculation of the digest * * @return the logged in principal if successful */ public Principal loginDigestImpl(HttpServletRequest request, HttpServletResponse response, ServletContext app, String user, String realm, String nonce, String uri, String qop, String nc, String cnonce, byte []clientDigest) throws ServletException { try { if (clientDigest == null) return null; MessageDigest digest = MessageDigest.getInstance("MD5"); byte []a1 = getDigestSecret(request, response, app, user, realm, "MD5"); if (a1 == null) return null; digestUpdateHex(digest, a1); digest.update((byte) ':'); for (int i = 0; i < nonce.length(); i++) digest.update((byte) nonce.charAt(i)); if (qop != null) { digest.update((byte) ':'); for (int i = 0; i < nc.length(); i++) digest.update((byte) nc.charAt(i)); digest.update((byte) ':'); for (int i = 0; cnonce != null && i < cnonce.length(); i++) digest.update((byte) cnonce.charAt(i)); digest.update((byte) ':'); for (int i = 0; qop != null && i < qop.length(); i++) digest.update((byte) qop.charAt(i)); } digest.update((byte) ':'); byte []a2 = digest(request.getMethod() + ":" + uri); digestUpdateHex(digest, a2);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?