001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 2004-2005 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: JACC.java 10642 2007-06-14 14:35:14Z benoitf $
023: * --------------------------------------------------------------------------
024: */package org.objectweb.jonas.security.realm.web.catalina55;
025:
026: import java.io.IOException;
027: import java.security.Principal;
028: import java.security.acl.Group;
029: import java.security.cert.X509Certificate;
030: import java.util.ArrayList;
031: import java.util.Enumeration;
032: import java.util.Iterator;
033:
034: import javax.security.auth.Subject;
035: import javax.security.auth.login.AccountExpiredException;
036: import javax.security.auth.login.CredentialExpiredException;
037: import javax.security.auth.login.FailedLoginException;
038: import javax.security.auth.login.LoginContext;
039: import javax.security.auth.login.LoginException;
040: import javax.servlet.http.HttpServletRequest;
041: import javax.servlet.http.HttpServletResponse;
042:
043: import org.apache.catalina.Context;
044: import org.apache.catalina.connector.Request;
045: import org.apache.catalina.connector.Response;
046: import org.apache.catalina.LifecycleException;
047: import org.apache.catalina.deploy.LoginConfig;
048: import org.apache.catalina.deploy.SecurityConstraint;
049: import org.apache.catalina.realm.Constants;
050: import org.apache.catalina.realm.GenericPrincipal;
051: import org.apache.catalina.realm.RealmBase;
052: import org.apache.catalina.util.StringManager;
053:
054: import org.objectweb.jonas.common.Log;
055: import org.objectweb.jonas.security.SecurityService;
056: import org.objectweb.jonas.security.auth.callback.NoInputCallbackHandler;
057: import org.objectweb.jonas.security.realm.factory.JResource;
058: import org.objectweb.jonas.security.realm.factory.JResourceException;
059: import org.objectweb.jonas.security.realm.principals.User;
060: import org.objectweb.jonas.service.ServiceManager;
061: import org.objectweb.jonas.web.lib.PermissionManager;
062:
063: import org.objectweb.security.context.SecurityContext;
064: import org.objectweb.security.context.SecurityCurrent;
065:
066: import org.objectweb.util.monolog.api.BasicLevel;
067: import org.objectweb.util.monolog.api.Logger;
068:
069: /**
070: * <p>
071: * Implementation of a Realm. (by a wrapper) Use any JOnAS realm by specifying
072: * the resource name This implementation manages the security with JACC
073: * specification It implements Cloneable to allow clones. Each context must have
074: * its own Realm. A realm can not be shared across different contexts or an
075: * engine. This is because each realm is associated to a permission manager
076: *
077: * Extends the Realmbase class of the Tomcat Server.
078: *
079: * @author Florent Benoit
080: */
081: public class JACC extends RealmBase implements Cloneable {
082:
083: /**
084: * Descriptive information about this Realm implementation.
085: */
086: private static final String NAME = "JACC_Catalina55";
087:
088: /**
089: * Descriptive information about this Realm implementation.
090: */
091: private static final String INFO = "org.objectweb.jonas.security.realm.JRealmJACCCatalina50/1.0";
092:
093: /**
094: * Name used in the JAAS config file
095: */
096: private static final String JAAS_CONFIG_NAME = "tomcat";
097:
098: /**
099: * The string manager for this package.
100: */
101: private static StringManager sm = StringManager
102: .getManager(Constants.Package);
103:
104: /**
105: * The logger used in JOnAS
106: */
107: private static Logger logger = null;
108:
109: /**
110: * The resource we will use to authenticate users and identify associated
111: * roles.
112: */
113: private JResource jResource = null;
114:
115: /**
116: * The name of the resource
117: */
118: private String resourceName = null;
119:
120: /**
121: * Reference to the JOnAS security service
122: */
123: private SecurityService securityService = null;
124:
125: /**
126: * Permission manager used by this realm for JACC permissions
127: */
128: private PermissionManager permissionManager = null;
129:
130: /**
131: * Last request that has been send to hasUserDataPermission or
132: * hasResourcePermission methods Used in hasRole to know the current servlet
133: * name.
134: * This request is store in a local thread.
135: */
136: private ThreadLocal lastRequestThread = new ThreadLocal();
137:
138: /**
139: * Context (used to retrieve web.xml informations)
140: */
141: private Context context = null;
142:
143: /**
144: * Name of this Realm for traces
145: */
146: private String realmName = NAME;
147:
148: /**
149: * Return descriptive information about this Realm implementation and the
150: * corresponding version number, in the format
151: * <code><description>/<version></code>.
152: *
153: * @return the info.
154: */
155: public String getInfo() {
156: return INFO;
157: }
158:
159: /**
160: * Return the resource name we will be using.
161: *
162: * @return the resource name.
163: */
164: public String getResourceName() {
165: return resourceName;
166: }
167:
168: /**
169: * Set the resource name we will be using.
170: *
171: * @param resourceName The new resource name
172: */
173: public void setResourceName(String resourceName) {
174: this .resourceName = resourceName;
175:
176: }
177:
178: /**
179: * Set the permission manager used by this realm
180: *
181: * @param permissionManager the permission manager to use
182: */
183: public void setPermissionManager(PermissionManager permissionManager) {
184: this .permissionManager = permissionManager;
185:
186: }
187:
188: /**
189: * Return the SecurityConstraints configured to guard the request URI for
190: * this request, or <code>null</code> if there is no such constraint.
191: *
192: * @param request Request we are processing
193: * @param context Context the Request is mapped to
194: * @return security constraints configured to guard the request URI
195: */
196: public SecurityConstraint[] findSecurityConstraints(
197: Request request, Context context) {
198: // Use super Method
199: return super .findSecurityConstraints(request, context);
200: }
201:
202: /**
203: * Perform access control based on the specified authorization constraint.
204: *
205: * @return <code>true</code> if this constraint is satisfied and
206: * processing should continue, or <code>false</code> otherwise.
207: *
208: * @param request Request we are processing
209: * @param response Response we are creating
210: * @param constraints Security constraint we are enforcing
211: * @param context The Context to which client of this class is attached.
212: *
213: * @exception IOException if an input/output error occurs
214: */
215: public boolean hasResourcePermission(Request request,
216: Response response, SecurityConstraint[] constraints,
217: Context context) throws IOException {
218:
219: // Update request
220: lastRequestThread.set(request);
221:
222: // --- Use code of RealmBase for the Login / Error pages
223:
224: // Specifically allow access to the form login and form error pages
225: // and the "j_security_check" action
226: LoginConfig config = context.getLoginConfig();
227: if (config != null
228: && Constants.FORM_METHOD.equals(config.getAuthMethod())) {
229: String requestURI = request.getDecodedRequestURI();
230: String loginPage = context.getPath()
231: + config.getLoginPage();
232: if (loginPage.equals(requestURI)) {
233: if (logger.isLoggable(BasicLevel.DEBUG)) {
234: logger
235: .log(BasicLevel.DEBUG, realmName
236: + "Allow access to login page "
237: + loginPage);
238: }
239: return true;
240: }
241:
242: String errorPage = context.getPath()
243: + config.getErrorPage();
244: if (errorPage.equals(requestURI)) {
245: if (logger.isLoggable(BasicLevel.DEBUG)) {
246: logger
247: .log(BasicLevel.DEBUG, realmName
248: + "Allow access to error page "
249: + errorPage);
250: }
251: return true;
252: }
253: if (requestURI.endsWith(Constants.FORM_ACTION)) {
254: if (logger.isLoggable(BasicLevel.DEBUG)) {
255: logger
256: .log(
257: BasicLevel.DEBUG,
258: realmName
259: + "Allow access to username/password submission");
260: }
261: return true;
262: }
263: }
264:
265: // Which user principal have we already authenticated?
266: Principal principal = request.getUserPrincipal();
267:
268: // --- End of code from RealmBase class
269:
270: String[] roles = null;
271: String principalName = null;
272: if (principal instanceof GenericPrincipal) {
273: roles = ((GenericPrincipal) principal).getRoles();
274: principalName = principal.getName();
275: }
276:
277: if (permissionManager == null) {
278: logger
279: .log(
280: BasicLevel.ERROR,
281: realmName
282: + "No permission manager is set. It means that you are using this realm without using the JOnAS deployer but only Tomcat.");
283: return false;
284: }
285:
286: boolean hasResourcePermission = permissionManager
287: .checkWebResourcePermission(request, principalName,
288: roles);
289:
290: // Need to send HTTP status code as invoke() method of Authenticator
291: // expect that it is
292: // done by the realm.
293: if (!hasResourcePermission) {
294: // Return a "Forbidden" message denying access to this resource
295: response.sendError(HttpServletResponse.SC_FORBIDDEN, sm
296: .getString("realmBase.forbidden"));
297: }
298:
299: return hasResourcePermission;
300: }
301:
302: /**
303: * @return <code>true</code> if the specified Principal has the specified
304: * security role, within the context of this Realm; otherwise return
305: * <code>false</code>. This method can be overridden by Realm
306: * implementations, but the default is adequate when an instance of
307: * <code>GenericPrincipal</code> is used to represent
308: * authenticated Principals from this Realm.
309: *
310: * @param principal Principal for whom the role is to be checked
311: * @param role Security role to be checked
312: */
313: public boolean hasRole(Principal principal, String role) {
314:
315: if ((principal == null) || (role == null)
316: || !(principal instanceof GenericPrincipal)) {
317: return false;
318: }
319:
320: if (logger.isLoggable(BasicLevel.DEBUG)) {
321: logger.log(BasicLevel.DEBUG, realmName + "Principal = "
322: + principal);
323: logger.log(BasicLevel.DEBUG, realmName + "Role = " + role);
324: }
325:
326: if (context == null) {
327: logger
328: .log(
329: BasicLevel.ERROR,
330: realmName
331: + "Cannot find a servlet name for isUserInRole() as no context was found");
332: return false;
333: }
334:
335: Request req = (Request) lastRequestThread.get();
336:
337: if (req == null) {
338: logger
339: .log(
340: BasicLevel.ERROR,
341: realmName
342: + "Cannot find a servlet name for isUserInRole(). No previous request !");
343: return false;
344: }
345: String servletName = findServletName(req);
346: String[] roles = null;
347: String principalName = null;
348:
349: if (principal instanceof GenericPrincipal) {
350: roles = ((GenericPrincipal) principal).getRoles();
351: principalName = principal.getName();
352: }
353:
354: if (permissionManager == null) {
355: logger
356: .log(
357: BasicLevel.ERROR,
358: realmName
359: + "No permission manager is set. It means that you are using this realm without using the JOnAS deployer but only Tomcat.");
360: return false;
361: }
362:
363: boolean hasRole = permissionManager.checkWebRoleRefPermission(
364: req, servletName, principalName, roles, role);
365: return hasRole;
366: }
367:
368: /**
369: * @return the name of the servlet (or "" if it's a JSP for example) This
370: * servlet name is used to build JACC permission for the hasRole
371: * method
372: *
373: * @param request the servlet request with which we have to find
374: * servlet name
375: */
376: private String findServletName(Request request) {
377:
378: // Pattern of the user (remove path)
379: String userPattern = request.getRequestURI().substring(
380: request.getContextPath().length());
381:
382: if (logger.isLoggable(BasicLevel.DEBUG)) {
383: logger.log(BasicLevel.DEBUG, realmName + "User Pattern = "
384: + userPattern);
385: }
386:
387: String servletName = "";
388: String[] patterns = context.findServletMappings();
389: boolean foundServlet = false;
390: String pattern = "";
391: int i = 0;
392:
393: // Try to search servlet name
394: while ((i < patterns.length) && !foundServlet) {
395: pattern = patterns[i];
396: if (logger.isLoggable(BasicLevel.DEBUG)) {
397: logger.log(BasicLevel.DEBUG, realmName
398: + "Pattern found = " + pattern);
399: logger.log(BasicLevel.DEBUG, realmName
400: + "Servlet name for pattern = "
401: + context.findServletMapping(pattern));
402: }
403:
404: // Extension pattern and ends with extension
405: if (pattern.startsWith("*.")
406: && userPattern.endsWith(pattern.substring(1))) {
407: foundServlet = true;
408: continue;
409: }
410:
411: // Exact Servlet name (ie pattern = /ServletName and userPattern =
412: // /ServletName)
413: if (pattern.equals(userPattern)) {
414: foundServlet = true;
415: continue;
416: }
417:
418: i++;
419: }
420:
421: if (foundServlet) {
422: servletName = context.findServletMapping(pattern);
423: // JSP case. servlet name must be empty as required by JACC
424: // specification
425: if (servletName.equals("jsp")) {
426: servletName = "";
427: }
428: if (logger.isLoggable(BasicLevel.DEBUG)) {
429: logger.log(BasicLevel.DEBUG, realmName
430: + "Found servlet name = " + servletName);
431: }
432: }
433: return servletName;
434: }
435:
436: /**
437: * Enforce any user data constraint required by the security constraint
438: * guarding this request URI.
439: *
440: * @return <code>true</code> if this constraint was not violated and
441: * processing should continue, or <code>false</code> if we have
442: * created a response already.
443: *
444: * @param request Request we are processing
445: * @param response Response we are creating
446: * @param constraints Security constraints being checked
447: *
448: * @exception IOException if an input/output error occurs
449: */
450: public boolean hasUserDataPermission(Request request,
451: Response response, SecurityConstraint[] constraints)
452: throws IOException {
453:
454: // Update request
455: lastRequestThread.set(request);
456:
457: // ---- Start of copy from RealmBase class ---
458:
459: // Validate the request against the user data constraint
460: if (request.getRequest().isSecure()) {
461: if (logger.isLoggable(BasicLevel.DEBUG)) {
462: logger.log(BasicLevel.DEBUG, realmName
463: + "User data constraint already satisfied");
464: }
465: return true;
466: }
467:
468: // Which user principal have we already authenticated?
469: Principal principal = ((HttpServletRequest) request)
470: .getUserPrincipal();
471:
472: // ---- End of copy from RealmBase class ---
473:
474: String[] roles = null;
475: String principalName = null;
476: if (principal instanceof GenericPrincipal) {
477: roles = ((GenericPrincipal) principal).getRoles();
478: principalName = principal.getName();
479: }
480:
481: // ---- Start of copy from RealmBase class ---
482: for (int i = 0; i < constraints.length; i++) {
483: SecurityConstraint constraint = constraints[i];
484: // Use redirect only if it the transport protocol is integral or
485: // confidential
486: String userConstraint = constraint.getUserConstraint();
487:
488: // Redirect only if the constraint is INTEGRAL or CONFIDENTIAL !
489: if (userConstraint != null
490: && (userConstraint
491: .equals(Constants.INTEGRAL_TRANSPORT) || userConstraint
492: .equals(Constants.CONFIDENTIAL_TRANSPORT))) {
493: // Initialize variables we need to determine the appropriate action
494: int redirectPort = request.getConnector()
495: .getRedirectPort();
496:
497: // Is redirecting disabled?
498: if (redirectPort <= 0) {
499: if (logger.isLoggable(BasicLevel.DEBUG)) {
500: logger.log(BasicLevel.DEBUG, realmName
501: + "SSL redirect is disabled");
502: }
503: response.sendError(
504: HttpServletResponse.SC_FORBIDDEN, request
505: .getRequestURI());
506: return false;
507: }
508:
509: // Redirect to the corresponding SSL port
510: StringBuffer file = new StringBuffer();
511: String protocol = "https";
512: String host = request.getServerName();
513: // Protocol
514: file.append(protocol).append("://");
515: // Host with port
516: file.append(host).append(":").append(redirectPort);
517: // URI
518: file.append(request.getRequestURI());
519: String requestedSessionId = request
520: .getRequestedSessionId();
521: if ((requestedSessionId != null)
522: && request.isRequestedSessionIdFromURL()) {
523: file.append(";jsessionid=");
524: file.append(requestedSessionId);
525: }
526: String queryString = request.getQueryString();
527: if (queryString != null) {
528: file.append('?');
529: file.append(queryString);
530: }
531:
532: if (logger.isLoggable(BasicLevel.DEBUG)) {
533: logger.log(BasicLevel.DEBUG, realmName
534: + "Redirecting to " + file.toString());
535: }
536: response.sendRedirect(file.toString());
537:
538: return false;
539: }
540: }
541:
542: // ---- End of copy from RealmBase ---
543: if (permissionManager == null) {
544: logger
545: .log(
546: BasicLevel.ERROR,
547: realmName
548: + "No permission manager is set. It means that you are using this realm without using the JOnAS deployer but only Tomcat.");
549: return false;
550: }
551:
552: // If Transport protocol is NONE :
553: boolean hasUserDataPermission = permissionManager
554: .checkWebUserDataPermission(request, principalName,
555: roles);
556: return hasUserDataPermission;
557:
558: }
559:
560: /**
561: * Return the Principal associated with the specified username and
562: * credentials, if there is one; otherwise return <code>null</code>.
563: *
564: * @param username Username of the Principal to look up
565: * @param credentials Password or other credentials to use in authenticating
566: * this username
567: * @return the principal associated
568: */
569: public Principal authenticate(String username, String credentials) {
570: // Use JOnAS resource if present
571: if (jResource != null) {
572: return authenticateResource(username, credentials);
573: } else {
574: // else use JAAS mechanism
575: return authenticateJAAS(username, credentials);
576: }
577: }
578:
579: /**
580: * Return the Principal associated with the specified username and
581: * credentials, if there is one; otherwise return <code>null</code>.
582: *
583: * @param username Username of the Principal to look up
584: * @param credentials Password or other credentials to use in authenticating
585: * this username
586: * @return the principal associated
587: */
588: public Principal authenticateResource(String username,
589: String credentials) {
590:
591: // No authentication can be made with a null username
592: if (username == null) {
593: if (logger.isLoggable(BasicLevel.DEBUG)) {
594: logger.log(BasicLevel.DEBUG, realmName
595: + "No username so no authentication");
596: }
597: return null;
598: }
599:
600: // Does a user with this username exist?
601: User user = null;
602: try {
603: user = jResource.findUser(username);
604: } catch (Exception jre) {
605: // could not retrieve user
606: logger.log(BasicLevel.ERROR, realmName
607: + "Can not find the user : " + jre.getMessage());
608: return null;
609: }
610:
611: // User was not found
612: if (user == null) {
613: if (logger.isLoggable(BasicLevel.DEBUG)) {
614: logger.log(BasicLevel.DEBUG, realmName + "User "
615: + username + " not found.");
616: }
617: return null;
618: }
619:
620: boolean validated = jResource.isValidUser(user, credentials);
621: if (!validated) {
622: logger.log(BasicLevel.ERROR, realmName
623: + "The password for the user " + username
624: + " is not valid");
625: return null;
626: }
627:
628: ArrayList combinedRoles = null;
629: try {
630: combinedRoles = jResource.getArrayListCombinedRoles(user);
631: } catch (JResourceException jre) {
632: logger.log(BasicLevel.ERROR, realmName + jre.getMessage(),
633: jre);
634: return null;
635: }
636:
637: GenericPrincipal principal = new GenericPrincipal(this , user
638: .getName(), user.getPassword(), combinedRoles);
639: SecurityContext ctx = new SecurityContext(principal.getName(),
640: combinedRoles);
641: SecurityCurrent current = SecurityCurrent.getCurrent();
642: current.setSecurityContext(ctx);
643:
644: return principal;
645: }
646:
647: /**
648: * Return the Principal associated with the specified username and
649: * credentials, if there is one; otherwise return <code>null</code>.
650: *
651: * @param username Username of the Principal to look up
652: * @param credentials Password or other credentials to use in
653: * authenticating this username
654: * @return the principal associated
655: */
656: public Principal authenticateJAAS(String username,
657: String credentials) {
658:
659: // No authentication can be made with a null username
660: if (username == null) {
661: log("No username so no authentication");
662: return null;
663: }
664: // Establish a LoginContext to use for authentication
665: LoginContext loginContext = null;
666: try {
667: loginContext = new LoginContext(JAAS_CONFIG_NAME,
668: new NoInputCallbackHandler(username, credentials));
669: } catch (LoginException e) {
670: logger.log(BasicLevel.ERROR, "loginException for user '"
671: + username + "'", e);
672: return null;
673: }
674: // Negotiate a login via this LoginContext
675: Subject subject = null;
676: try {
677: loginContext.login();
678: subject = loginContext.getSubject();
679: if (subject == null) {
680: if (logger.isLoggable(BasicLevel.ERROR)) {
681: logger.log(BasicLevel.ERROR,
682: "failedLoginlogin for user :" + username);
683: }
684: return null;
685: }
686: } catch (AccountExpiredException e) {
687: if (logger.isLoggable(BasicLevel.ERROR)) {
688: logger.log(BasicLevel.ERROR,
689: "accountExpired for user :" + username, e);
690: }
691: return null;
692: } catch (CredentialExpiredException e) {
693: if (logger.isLoggable(BasicLevel.ERROR)) {
694: logger.log(BasicLevel.ERROR,
695: "credentialExpired for user :" + username, e);
696: }
697: return null;
698: } catch (FailedLoginException e) {
699: if (logger.isLoggable(BasicLevel.ERROR)) {
700: logger.log(BasicLevel.ERROR, "failedLogin for user :"
701: + username, e);
702: }
703: return null;
704: } catch (LoginException e) {
705: if (logger.isLoggable(BasicLevel.ERROR)) {
706: logger.log(BasicLevel.ERROR,
707: "loginException for user :" + username, e);
708: }
709: return null;
710: }
711:
712: // Get credentials iterators from the subject
713: Iterator credentialsIterator = subject.getPrivateCredentials()
714: .iterator();
715: String credential = (String) credentialsIterator.next();
716:
717: // Retrieve first principal name found (without groups)
718: Iterator iterator = subject.getPrincipals(Principal.class)
719: .iterator();
720: String userName = null;
721: while (iterator.hasNext() && (userName == null)) {
722: Principal principal = (Principal) iterator.next();
723: if (!(principal instanceof Group)) {
724: userName = principal.getName();
725: }
726: }
727:
728: // No name --> error
729: if (userName == null) {
730: logger.log(BasicLevel.ERROR,
731: "No Username found in the subject");
732: return null;
733: }
734:
735: // Retrieve all roles of the user (Roles are members of the Group.class)
736: iterator = subject.getPrincipals(Group.class).iterator();
737: ArrayList roles = new ArrayList();
738: while (iterator.hasNext()) {
739: Group group = (Group) iterator.next();
740: Enumeration e = group.members();
741: while (e.hasMoreElements()) {
742: Principal p = (Principal) e.nextElement();
743: roles.add(p.getName());
744: }
745: }
746:
747: GenericPrincipal principal = new GenericPrincipal(this ,
748: userName, credential, roles);
749: //instanciation of the security context
750: SecurityContext ctx = new SecurityContext(userName, roles);
751: SecurityCurrent current = SecurityCurrent.getCurrent();
752: current.setSecurityContext(ctx);
753:
754: return principal;
755: }
756:
757: /**
758: * Return the Principal associated with the specified chain of X509 client
759: * certificates. If there is none, return <code>null</code>.
760: *
761: * @param cert Array of client certificates, with the first one in the array
762: * being the certificate of the client itself.
763: * @return the associated Principal
764: */
765: public Principal authenticate(X509Certificate[] cert) {
766: String dn = cert[0].getSubjectDN().getName();
767: return authenticate(dn, "tomcat");
768: }
769:
770: /**
771: * Return a short name for this Realm implementation.
772: *
773: * @return the name
774: */
775: protected String getName() {
776: return NAME;
777: }
778:
779: /**
780: * Return the password associated with the given principal's user name.
781: *
782: * @param username the given principal's user name.
783: * @return the password associated.
784: */
785: protected String getPassword(String username) {
786: return null;
787: }
788:
789: /**
790: * Return the Principal associated with the given user name.
791: *
792: * @param username the given principal's user name.
793: * @return the Principal associated
794: */
795: protected Principal getPrincipal(String username) {
796: return null;
797: }
798:
799: /**
800: * Set the context of this Realm. This is used to retrieve xml information
801: * of the web.xml file
802: *
803: * @param context Context for this realm
804: */
805: public void setContext(Context context) {
806: this .context = context;
807: StringBuffer sb = new StringBuffer();
808: sb.append("[");
809: sb.append(NAME);
810: sb.append(":");
811: sb.append(resourceName);
812: sb.append(":");
813: if (context != null) {
814: sb.append(context.getName());
815: }
816: sb.append("] ");
817: this .realmName = sb.toString();
818: }
819:
820: /**
821: * Prepare for active use of the public methods of this Component.
822: *
823: * @exception LifecycleException if this component detects a fatal error
824: * that prevents it from being started
825: */
826: public synchronized void start() throws LifecycleException {
827:
828: if (logger == null) {
829: logger = Log.getLogger(Log.JONAS_SECURITY_PREFIX);
830: }
831:
832: // Get the Security Service
833: try {
834: securityService = (SecurityService) ServiceManager
835: .getInstance().getSecurityService();
836: } catch (Exception e) {
837: // Can't retrieve Security service
838: throw new LifecycleException(
839: "can't retrieve Security service");
840: }
841:
842: // Get the resource from the security service if working with resource mode
843: if (resourceName != null) {
844: jResource = securityService.getJResource(resourceName);
845: if (jResource == null) {
846: throw new LifecycleException(
847: "Can't retrieve resource '" + resourceName
848: + "' from the security service");
849:
850: }
851: }
852:
853: // Perform normal superclass initialization
854: super .start();
855:
856: }
857:
858: /**
859: * Gracefully shut down active use of the public methods of this Component.
860: *
861: * @exception LifecycleException if this component detects a fatal error
862: * that needs to be reported
863: */
864: public synchronized void stop() throws LifecycleException {
865: // Perform normal superclass finalization
866: super .stop();
867:
868: // Release reference to our resource
869: jResource = null;
870: }
871:
872: /**
873: * Log a message on the Logger associated with our Container (if any)
874: *
875: * @param message Message to be logged
876: */
877: protected void log(String message) {
878: if (logger.isLoggable(BasicLevel.DEBUG)) {
879: logger.log(BasicLevel.DEBUG, message);
880: }
881: }
882:
883: /**
884: * Creates and returns a copy of this object.
885: *
886: * @return copy of this object.
887: * @throws CloneNotSupportedException if the copy fails
888: */
889: public Object clone() throws CloneNotSupportedException {
890: JACC jRealm = new JACC();
891: jRealm.setResourceName(resourceName);
892: return jRealm;
893: }
894:
895: /**
896: * @return the permission manager used by this realm.
897: */
898: public PermissionManager getPermissionManager() {
899: return permissionManager;
900: }
901:
902: }
|