Annotation of java/classes/org/w3c/jigsaw/acl/AclFilter.java, revision 1.6.4.2
1.1 bmahe 1: // AclFilter.java
1.6.4.2 ! ylafon 2: // $Id: AclFilter.java,v 1.9 2000/12/07 14:30:33 ylafon Exp $
1.1 bmahe 3: // (c) COPYRIGHT MIT, INRIA and Keio, 1999.
4: // Please first read the full copyright statement in file COPYRIGHT.html
1.6.4.2 ! ylafon 5:
1.1 bmahe 6: package org.w3c.jigsaw.acl;
7:
1.2 bmahe 8: import java.security.Principal;
9: import java.security.acl.Permission;
10: import java.security.acl.Acl;
11:
12: import org.w3c.jigsaw.html.HtmlGenerator;
13: import org.w3c.jigsaw.http.HTTPException;
14: import org.w3c.jigsaw.http.Reply;
15: import org.w3c.jigsaw.http.Request;
16:
17: import org.w3c.tools.resources.Attribute;
18: import org.w3c.tools.resources.AttributeRegistry;
19: import org.w3c.tools.resources.BooleanAttribute;
20: import org.w3c.tools.resources.IntegerAttribute;
21: import org.w3c.tools.resources.LookupResult;
22: import org.w3c.tools.resources.LookupState;
23: import org.w3c.tools.resources.ProtocolException;
1.5 bmahe 24: import org.w3c.tools.resources.ResourceFrame;
1.1 bmahe 25: import org.w3c.tools.resources.ResourceFilter;
1.2 bmahe 26: import org.w3c.tools.resources.RequestInterface;
27: import org.w3c.tools.resources.ReplyInterface;
1.3 bmahe 28: import org.w3c.tools.resources.StringAttribute;
1.2 bmahe 29:
30: import org.w3c.www.http.HTTP;
31: import org.w3c.www.http.HttpChallenge;
1.1 bmahe 32:
33: /**
1.6.4.2 ! ylafon 34: * @version $Revision: 1.9 $
1.1 bmahe 35: * @author Benoît Mahé (bmahe@w3.org)
36: */
37: public class AclFilter extends ResourceFilter {
1.3 bmahe 38:
1.2 bmahe 39: /**
40: * Attribute index - Security level 0=Basic 1=Digest...
41: */
42: protected static int ATTR_SECURITY_LEVEL = -1;
43: /**
1.3 bmahe 44: * Attribute index - The algorithm used
45: */
46: protected static int ATTR_ALGORITHM = -1 ;
47: /**
48: * Attribute index - The nonce time to live (in seconds)
49: */
50: protected static int ATTR_NONCE_TTL = -1 ;
51: /**
1.2 bmahe 52: * Attribute index - And or Or for multiple Acls
53: */
54: protected static int ATTR_STRICT_ACL_MERGE_POLICY = -1;
55: /**
56: * Attribute index - Is caching allowed by a shared cache ?
57: */
58: protected static int ATTR_SHARED_CACHABILITY = -1;
59: /**
60: * Attribute index - Is caching allowed in private cache ?
61: */
62: protected static int ATTR_PRIVATE_CACHABILITY = -1;
63: /**
64: * Attribute index - Is public caching of protected documents allowed ?
65: */
66: protected static int ATTR_PUBLIC_CACHABILITY = -1;
67:
68: /**
69: * The JAcl class.
70: */
71: protected static Class JAcl_class = null;
72:
1.3 bmahe 73: protected SecurityLevel security = null;
74:
1.2 bmahe 75: static {
76: Attribute a = null ;
77: Class c = null ;
78: try {
79: c = Class.forName("org.w3c.jigsaw.acl.AclFilter");
80: JAcl_class = Class.forName("org.w3c.jigsaw.acl.JAcl");
81: } catch (Exception ex) {
82: ex.printStackTrace() ;
83: System.exit(1) ;
84: }
85: // security level
86: a = new IntegerAttribute("security-level",
87: new Integer(0),
88: Attribute.EDITABLE);
89: ATTR_SECURITY_LEVEL = AttributeRegistry.registerAttribute(c, a);
90: // do we use a strict acl merge policy
91: a = new BooleanAttribute("strict-acl-merge-policy"
92: , Boolean.TRUE
93: , Attribute.EDITABLE);
94: ATTR_STRICT_ACL_MERGE_POLICY =
95: AttributeRegistry.registerAttribute(c, a);
1.3 bmahe 96: // The algorithm used for digest and checksum
97: a = new StringAttribute("algorithm"
98: , null
99: , Attribute.EDITABLE);
100: ATTR_ALGORITHM = AttributeRegistry.registerAttribute(c, a) ;
101: a = new IntegerAttribute("nonce_ttl"
102: , new Integer(300)
103: , Attribute.EDITABLE);
104: ATTR_NONCE_TTL = AttributeRegistry.registerAttribute(c, a) ;
1.5 bmahe 105: // Can protected documents be saved in shared cache ?
106: a = new BooleanAttribute("shared-cachability"
107: , Boolean.FALSE
108: , Attribute.EDITABLE);
109: ATTR_SHARED_CACHABILITY = AttributeRegistry.registerAttribute(c, a);
1.2 bmahe 110: // Can protected documents be shared in private cache ?
111: a = new BooleanAttribute("private-cachability"
112: , Boolean.FALSE
113: , Attribute.EDITABLE);
114: ATTR_PRIVATE_CACHABILITY = AttributeRegistry.registerAttribute(c, a);
115: // Can protected documents be publicly cached ?
116: a = new BooleanAttribute("public-cachability"
117: , Boolean.FALSE
118: , Attribute.EDITABLE);
119: ATTR_PUBLIC_CACHABILITY = AttributeRegistry.registerAttribute(c, a);
120: }
121:
122: /**
123: * Get the security level.
124: * @return an integer;
125: */
126: public int getSecurityLevel() {
127: return getInt(ATTR_SECURITY_LEVEL, 0);
128: }
129:
130: /**
1.3 bmahe 131: * Get the algorithm used
132: */
133: public String getAlgorithm() {
134: return (String) getValue(ATTR_ALGORITHM, "MD5") ;
135: }
136:
137: public int getNonceTTL() {
138: return getInt(ATTR_NONCE_TTL, 300);
139: }
140:
141: /**
1.2 bmahe 142: * Returns true if we have a strict acl merge policy.
143: * @return a boolean.
144: */
145: public boolean isStrictAclMergePolicy() {
146: return getBoolean(ATTR_STRICT_ACL_MERGE_POLICY, true);
147: }
148:
149: /**
150: * Is this document publicly cachable ?
151: * @return A boolean.
152: */
153: public boolean getPublicCachability() {
154: return getBoolean(ATTR_PUBLIC_CACHABILITY, false);
155: }
156:
157: /**
158: * Is this document cachable in private caches ?
159: * @return A boolean.
160: */
161: public boolean getPrivateCachability() {
162: return getBoolean(ATTR_PRIVATE_CACHABILITY, false);
163: }
164:
165: /**
166: * Is this document cachable in shared caches ?
167: * @return A boolean.
168: */
169: public boolean getSharedCachability() {
170: return getBoolean(ATTR_SHARED_CACHABILITY, false);
171: }
172:
173: protected JAcl[] getAcls() {
1.5 bmahe 174: ResourceFrame frames[] = collectFrames(JAcl_class);
175: JAcl acls[] = new JAcl[frames.length];
176: for (int i = 0 ; i < frames.length ; i++)
177: acls[i] = (JAcl) frames[i];
178: return acls;
1.2 bmahe 179: }
180:
181: /**
182: * Authenticate the given request for the given client.
183: * This method is invoked prior to any request handling on its target
184: * entity. If the used authentication method allows so, AuthFilters
185: * should set the <strong>authuser</strong> attribute of the request.
186: * @param request The request.
187: * @exception ProtocolException If authentication failed.
188: */
189:
190: public boolean lookup(LookupState ls, LookupResult lr)
191: throws ProtocolException
192: {
193: JAcl acls[] = getAcls();
1.6.4.1 ylafon 194: if ((acls == null) || (ls.getRequest() == null)) {
1.2 bmahe 195: return false;
1.6.4.1 ylafon 196: }
1.2 bmahe 197: authenticate((Request)ls.getRequest(), acls);
198: return false;
199: }
200:
201: /**
202: * Authenticate the given request.
203: * @param request The request to be authentified.
204: * @param acls The Access Control List array.
205: * @exception org.w3c.tools.resources.ProtocolException if authentication
206: * failed
207: */
208: protected void authenticate(Request request, JAcl acls[])
209: throws ProtocolException
210: {
211: Permission perm = new HTTPPermission(request);
1.6 bmahe 212: Principal princ = security.getPrincipal(request, getAlgorithm());
1.2 bmahe 213: boolean strict = isStrictAclMergePolicy();
214: boolean authorized = false;
1.5 bmahe 215: Acl acl = acls[0];
1.3 bmahe 216:
217: if (princ != null) {
218: if (strict) {
219: authorized = true;
220: for (int i = 0 ; i < acls.length ; i++) {
221: boolean check = acls[i].checkPermission(princ, perm);
222: if (!check) {
223: authorized = false;
224: acl = acls[i];
225: break;
226: }
227: }
228: } else {
229: for (int i = 0 ; i < acls.length ; i++) {
230: boolean check = acls[i].checkPermission(princ, perm);
231: if (check) {
232: authorized = true;
233: break;
234: }
1.2 bmahe 235: }
236: }
237: }
238: if (!authorized) {
239: HttpChallenge challenge =
1.3 bmahe 240: security.getChallenge(acl.getName(), princ);
1.2 bmahe 241: Reply e = null;
242: if ( request.isProxy() ) {
243: e = request.makeReply(HTTP.PROXY_AUTH_REQUIRED);
244: e.setProxyAuthenticate(challenge);
245: } else {
246: e = request.makeReply(HTTP.UNAUTHORIZED);
247: e.setWWWAuthenticate(challenge);
248: }
249: HtmlGenerator g = new HtmlGenerator("Unauthorized");
250: g.append ("<h1>Unauthorized access</h1>"+
251: "<p>You are denied access to this resource.");
252: e.setStream(g);
253: throw new HTTPException (e);
1.3 bmahe 254: } else {
255: security.updateRequestStates(request, princ);
1.2 bmahe 256: }
257: }
1.6.4.2 ! ylafon 258:
1.2 bmahe 259: /**
260: * Add the appropriate cache control directives on the way back.
261: * @param request The request that has been processed.
262: * @param reply The original reply.
263: * @return Always <strong>null</strong>.
264: */
265: public ReplyInterface outgoingFilter(RequestInterface request,
266: ReplyInterface reply)
267: {
268: Reply rep = (Reply) reply;
269: if ( getPrivateCachability() ) {
270: rep.setMustRevalidate(true);
271: } else if ( getSharedCachability() ) {
272: rep.setProxyRevalidate(true);
273: } else if ( getPublicCachability() ) {
274: rep.setPublic(true);
275: }
1.3 bmahe 276: security.updateReply(rep, (Request) request);
1.2 bmahe 277: return null;
1.3 bmahe 278: }
279:
280: /**
281: * Catch set value to maintain cached values.
282: */
283: public void setValue(int idx, Object value) {
284: super.setValue(idx, value);
1.6.4.2 ! ylafon 285: if ((idx == ATTR_SECURITY_LEVEL) || (idx == ATTR_ALGORITHM )) {
1.3 bmahe 286: security = SecurityLevel.getSecurityLevel(this);
287: }
288: }
1.6.4.2 ! ylafon 289:
1.3 bmahe 290: /**
291: * Initialize the filter.
292: */
293: public void initialize(Object values[]) {
294: super.initialize(values) ;
295: security = SecurityLevel.getSecurityLevel(this);
1.2 bmahe 296: }
1.1 bmahe 297: }
Webmaster