001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.aspects.security;
023:
024: import java.security.Principal;
025: import java.security.GeneralSecurityException;
026: import javax.security.auth.Subject;
027: import org.jboss.logging.Logger;
028: import org.jboss.security.AuthenticationManager;
029: import org.jboss.security.RunAsIdentity;
030:
031: /**
032: * The AuthenticationInterceptor authenticates the caller.
033: *
034: * @author <a href="mailto:Scott.Stark@jboss.org">Scott Stark</a>.
035: * @author <a href="bill@jboss.org">Bill Burke</a>
036: * @version $Revision: 57186 $
037: */
038: public class AuthenticationInterceptor implements
039: org.jboss.aop.advice.Interceptor {
040: protected Logger log = Logger.getLogger(this .getClass());
041: protected AuthenticationManager authenticationManager;
042:
043: public AuthenticationInterceptor(AuthenticationManager manager) {
044: authenticationManager = manager;
045: }
046:
047: public String getName() {
048: return "AuthenticationInterceptor";
049: }
050:
051: protected void handleGeneralSecurityException(
052: GeneralSecurityException gse) {
053: throw new SecurityException(gse.getMessage());
054: }
055:
056: /**
057: * Authenticates the caller using the principal and credentials in the
058: * Infocation if thre is a security manager and an invcocation method.
059: */
060: public Object invoke(org.jboss.aop.joinpoint.Invocation invocation)
061: throws Throwable {
062: try {
063: authenticate(invocation);
064: } catch (GeneralSecurityException gse) {
065: handleGeneralSecurityException(gse);
066: }
067:
068: Object oldDomain = SecurityContext.currentDomain.get();
069: try {
070: SecurityContext.currentDomain.set(authenticationManager);
071: return invocation.invokeNext();
072: } finally {
073: SecurityContext.currentDomain.set(oldDomain);
074: // so that the principal doesn't keep being associated with thread if the thread is pooled
075: // only pop if it's been pushed
076: RunAsIdentity callerRunAsIdentity = SecurityActions
077: .peekRunAsIdentity();
078: if (authenticationManager == null
079: || callerRunAsIdentity == null)
080: SecurityActions.popSubjectContext();
081:
082: if (invocation.getMetaData("security", "principal") != null) {
083: SecurityActions.setPrincipal(null);
084: SecurityActions.setCredential(null);
085: }
086: }
087: }
088:
089: protected void authenticate(
090: org.jboss.aop.joinpoint.Invocation invocation)
091: throws Exception {
092: Principal principal = (Principal) invocation.getMetaData(
093: "security", "principal");
094: Object credential = invocation.getMetaData("security",
095: "credential");
096:
097: if (principal == null) {
098: principal = SecurityActions.getPrincipal();
099: }
100: if (credential == null) {
101: credential = SecurityActions.getCredential();
102: }
103:
104: if (authenticationManager == null) {
105: SecurityActions.pushSubjectContext(principal, credential,
106: null);
107: return;
108: }
109:
110: // authenticate the current principal
111: RunAsIdentity callerRunAsIdentity = SecurityActions
112: .peekRunAsIdentity();
113: if (callerRunAsIdentity == null) {
114: // Check the security info from the method invocation
115: Subject subject = new Subject();
116: if (authenticationManager.isValid(principal, credential,
117: subject) == false) {
118: /* todo support CSIV2 authenticationObserver
119: // Notify authentication observer
120: if (authenticationObserver != null)
121: authenticationObserver.authenticationFailed();
122: */
123: // Check for the security association exception
124: Exception ex = SecurityActions.getContextException();
125: if (ex != null)
126: throw ex;
127: // Else throw a generic SecurityException
128: String msg = "Authentication exception, principal="
129: + principal;
130: SecurityException e = new SecurityException(msg);
131: throw e;
132: } else {
133: SecurityActions.pushSubjectContext(principal,
134: credential, subject);
135: if (log.isTraceEnabled()) {
136: log.trace("Authenticated principal=" + principal);
137: }
138: }
139: }
140: }
141: }
|