📄 jaasauthenticationprovider.java
字号:
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * 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.acegisecurity.providers.jaas;import org.acegisecurity.AcegiSecurityException;import org.acegisecurity.Authentication;import org.acegisecurity.AuthenticationException;import org.acegisecurity.GrantedAuthority;import org.acegisecurity.context.HttpSessionContextIntegrationFilter;import org.acegisecurity.context.SecurityContext;import org.acegisecurity.providers.AuthenticationProvider;import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;import org.acegisecurity.providers.jaas.event.JaasAuthenticationFailedEvent;import org.acegisecurity.providers.jaas.event.JaasAuthenticationSuccessEvent;import org.acegisecurity.ui.session.HttpSessionDestroyedEvent;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.springframework.beans.BeansException;import org.springframework.beans.factory.InitializingBean;import org.springframework.context.*;import org.springframework.core.io.Resource;import org.springframework.util.Assert;import java.io.IOException;import java.security.Principal;import java.security.Security;import java.util.Arrays;import java.util.HashSet;import java.util.Iterator;import java.util.Set;import javax.security.auth.callback.Callback;import javax.security.auth.callback.CallbackHandler;import javax.security.auth.callback.UnsupportedCallbackException;import javax.security.auth.login.Configuration;import javax.security.auth.login.LoginContext;import javax.security.auth.login.LoginException;/** * An {@link AuthenticationProvider} implementation that retrieves user details from a JAAS login configuration. * * <p>This <code>AuthenticationProvider</code> is capable of validating {@link * org.acegisecurity.providers.UsernamePasswordAuthenticationToken} requests contain the correct username and * password.</p> * <p>This implementation is backed by a <a * href="http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/JAASRefGuide.html">JAAS</a> configuration. The * loginConfig property must be set to a given JAAS configuration file. This setter accepts a Spring {@link * org.springframework.core.io.Resource} instance. It should point to a JAAS configuration file containing an index * matching the {@link #setLoginContextName(java.lang.String) loginContextName} property. * </p> * <p> * For example: If this JaasAuthenticationProvider were configured in a Spring WebApplicationContext the xml to * set the loginConfiguration could be as follows... * <pre> * <property name="loginConfig"> * <value>/WEB-INF/login.conf</value> * </property> * </pre> * </p> * <p> * The loginContextName should coincide with a given index in the loginConfig specifed. The loginConfig file * used in the JUnit tests appears as the following... * <pre> JAASTest { * org.acegisecurity.providers.jaas.TestLoginModule required; * }; * </pre> * Using the example login configuration above, the loginContextName property would be set as <i>JAASTest</i>... * <pre> * <property name="loginContextName"> <value>JAASTest</value> </property> * </pre> * </p> * <p>When using JAAS login modules as the authentication source, sometimes the * <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/security/auth/login/LoginContext.html">LoginContext</a> will * require <i>CallbackHandler</i>s. The JaasAuthenticationProvider uses an internal * <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/security/auth/callback/CallbackHandler.html">CallbackHandler * </a> to wrap the {@link JaasAuthenticationCallbackHandler}s configured in the ApplicationContext. * When the LoginContext calls the internal CallbackHandler, control is passed to each * {@link JaasAuthenticationCallbackHandler} for each Callback passed. * </p> * <p>{@link JaasAuthenticationCallbackHandler}s are passed to the JaasAuthenticationProvider through the {@link * #setCallbackHandlers(org.acegisecurity.providers.jaas.JaasAuthenticationCallbackHandler[]) callbackHandlers} * property. * <pre> * <property name="callbackHandlers"> * <list> * <bean class="org.acegisecurity.providers.jaas.TestCallbackHandler"/> * <bean class="{@link JaasNameCallbackHandler org.acegisecurity.providers.jaas.JaasNameCallbackHandler}"/> * <bean class="{@link JaasPasswordCallbackHandler org.acegisecurity.providers.jaas.JaasPasswordCallbackHandler}"/> * </list> * </property> * </pre> * </p> * <p> * After calling LoginContext.login(), the JaasAuthenticationProvider will retrieve the returned Principals * from the Subject (LoginContext.getSubject().getPrincipals). Each returned principal is then passed to the * configured {@link AuthorityGranter}s. An AuthorityGranter is a mapping between a returned Principal, and a role * name. If an AuthorityGranter wishes to grant an Authorization a role, it returns that role name from it's {@link * AuthorityGranter#grant(java.security.Principal)} method. The returned role will be applied to the Authorization * object as a {@link GrantedAuthority}.</p> * <p>AuthorityGranters are configured in spring xml as follows... * <pre> * <property name="authorityGranters"> * <list> * <bean class="org.acegisecurity.providers.jaas.TestAuthorityGranter"/> * </list> * </property> * </pre> * A configuration note: The JaasAuthenticationProvider uses the security properites * "e;login.config.url.X"e; to configure jaas. If you would like to customize the way Jaas gets configured, * create a subclass of this and override the {@link #configureJaas(Resource)} method. * </p> * * @author Ray Krueger * @version $Id: JaasAuthenticationProvider.java 1985 2007-08-29 11:51:02Z luke_t $ */public class JaasAuthenticationProvider implements AuthenticationProvider, ApplicationEventPublisherAware, InitializingBean, ApplicationListener { //~ Static fields/initializers ===================================================================================== protected static final Log log = LogFactory.getLog(JaasAuthenticationProvider.class); //~ Instance fields ================================================================================================ private LoginExceptionResolver loginExceptionResolver = new DefaultLoginExceptionResolver(); private Resource loginConfig; private String loginContextName = "ACEGI"; private AuthorityGranter[] authorityGranters; private JaasAuthenticationCallbackHandler[] callbackHandlers; private ApplicationEventPublisher applicationEventPublisher; //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.notNull(loginConfig, "loginConfig must be set on " + getClass()); Assert.hasLength(loginContextName, "loginContextName must be set on " + getClass()); configureJaas(loginConfig); Assert.notNull(Configuration.getConfiguration(), "As per http://java.sun.com/j2se/1.5.0/docs/api/javax/security/auth/login/Configuration.html " + "\"If a Configuration object was set via the Configuration.setConfiguration method, then that object is " + "returned. Otherwise, a default Configuration object is returned\". Your JRE returned null to " + "Configuration.getConfiguration()."); } /** * Attempts to login the user given the Authentication objects principal and credential * * @param auth The Authentication object to be authenticated. * * @return The authenticated Authentication object, with it's grantedAuthorities set. * * @throws AuthenticationException This implementation does not handle 'locked' or 'disabled' accounts. This method * only throws a AuthenticationServiceException, with the message of the LoginException that will be * thrown, should the loginContext.login() method fail. */ public Authentication authenticate(Authentication auth) throws AuthenticationException { if (auth instanceof UsernamePasswordAuthenticationToken) { UsernamePasswordAuthenticationToken request = (UsernamePasswordAuthenticationToken) auth; try { //Create the LoginContext object, and pass our InternallCallbackHandler LoginContext loginContext = new LoginContext(loginContextName, new InternalCallbackHandler(auth)); //Attempt to login the user, the LoginContext will call our InternalCallbackHandler at this point. loginContext.login(); //create a set to hold the authorities, and add any that have already been applied. Set authorities = new HashSet(); if (request.getAuthorities() != null) { authorities.addAll(Arrays.asList(request.getAuthorities())); } //get the subject principals and pass them to each of the AuthorityGranters Set principals = loginContext.getSubject().getPrincipals(); for (Iterator iterator = principals.iterator(); iterator.hasNext();) { Principal principal = (Principal) iterator.next(); for (int i = 0; i < authorityGranters.length; i++) { AuthorityGranter granter = authorityGranters[i]; Set roles = granter.grant(principal); //If the granter doesn't wish to grant any authorities, it should return null. if ((roles != null) && !roles.isEmpty()) { for (Iterator roleIterator = roles.iterator(); roleIterator.hasNext();) { String role = roleIterator.next().toString(); authorities.add(new JaasGrantedAuthority(role, principal)); } } } } //Convert the authorities set back to an array and apply it to the token. JaasAuthenticationToken result = new JaasAuthenticationToken(request.getPrincipal(), request.getCredentials(), (GrantedAuthority[]) authorities.toArray(new GrantedAuthority[authorities.size()]), loginContext); //Publish the success event publishSuccessEvent(result); //we're done, return the token. return result; } catch (LoginException loginException) { AcegiSecurityException ase = loginExceptionResolver.resolveException(loginException); publishFailureEvent(request, ase); throw ase;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -