KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jgroups > protocols > AUTH


1 package org.jgroups.protocols;
2
3
4 import org.jgroups.Address;
5 import org.jgroups.Event;
6 import org.jgroups.Message;
7 import org.jgroups.auth.AuthToken;
8 import org.jgroups.protocols.pbcast.GMS;
9 import org.jgroups.protocols.pbcast.JoinRsp;
10 import org.jgroups.stack.Protocol;
11 import java.util.Properties JavaDoc;
12
13
14 /**
15  * The AUTH protocol adds a layer of authentication to JGroups
16  * @author Chris Mills
17  */

18 public class AUTH extends Protocol{
19
20     static final String JavaDoc NAME = "AUTH";
21
22     /**
23      * used on the coordinator to authentication joining member requests against
24      */

25     private AuthToken serverSideToken = null;
26
27     public AUTH(){
28     }
29
30     public boolean setProperties(Properties JavaDoc props) {
31
32         String JavaDoc authClassString = props.getProperty("auth_class");
33
34         if(authClassString != null){
35             props.remove("auth_class");
36
37             try{
38                 Object JavaDoc obj = Class.forName(authClassString).newInstance();
39                 serverSideToken = (AuthToken) obj;
40                 serverSideToken.setValue(props);
41             }catch(Exception JavaDoc e){
42                 if(log.isFatalEnabled()){
43                     log.fatal("Failed to create server side token (" + authClassString + ")");
44                     log.fatal(e);
45                 }
46                 return false;
47             }
48         }
49
50         if(!props.isEmpty()) {
51             //this should never happen as everything is read in to the AuthToken instance
52
if(log.isErrorEnabled()){
53                 log.error("AUTH.setProperties(): the following properties are not recognized: " + props);
54             }
55             return false;
56         }
57         return true;
58     }
59
60     public final String JavaDoc getName() {
61         return AUTH.NAME;
62     }
63     /**
64      * Used to create a failed JOIN_RSP message to pass back down the stack
65      * @param joiner The Address of the requesting member
66      * @param message The failure message to send back to the joiner
67      * @return An Event containing a GmsHeader with a JoinRsp object
68      */

69     private Event createFailureEvent(Address joiner, String JavaDoc message){
70         Message msg = new Message(joiner, null, null);
71
72         if(log.isDebugEnabled()){
73             log.debug("Creating JoinRsp with failure message - " + message);
74         }
75         JoinRsp joinRes = new JoinRsp(message);
76         //need to specify the error message on the JoinRsp object once it's been changed
77

78         GMS.GmsHeader gmsHeader = new GMS.GmsHeader(GMS.GmsHeader.JOIN_RSP, joinRes);
79         msg.putHeader(GMS.name, gmsHeader);
80
81         if(log.isDebugEnabled()){
82             log.debug("GMSHeader created for failure JOIN_RSP");
83         }
84
85         return new Event(Event.MSG, msg);
86     }
87
88     /**
89      * An event was received from the layer below. Usually the current layer will want to examine
90      * the event type and - depending on its type - perform some computation
91      * (e.g. removing headers from a MSG event type, or updating the internal membership list
92      * when receiving a VIEW_CHANGE event).
93      * Finally the event is either a) discarded, or b) an event is sent down
94      * the stack using <code>down_prot.down()</code> or c) the event (or another event) is sent up
95      * the stack using <code>up_prot.up()</code>.
96      */

97     public Object JavaDoc up(Event evt) {
98         GMS.GmsHeader hdr = isJoinMessage(evt);
99         if((hdr != null) && (hdr.getType() == GMS.GmsHeader.JOIN_REQ)){
100             if(log.isDebugEnabled()){
101                 log.debug("AUTH got up event");
102             }
103             //we found a join message - now try and get the AUTH Header
104
Message msg = (Message)evt.getArg();
105
106             if((msg.getHeader(AUTH.NAME) != null) && (msg.getHeader(AUTH.NAME) instanceof AuthHeader)){
107                 AuthHeader authHeader = (AuthHeader)msg.getHeader(AUTH.NAME);
108
109                 if(authHeader != null){
110                     //Now we have the AUTH Header we need to validate it
111
if(this.serverSideToken.authenticate(authHeader.getToken(), msg)){
112                         //valid token
113
if(log.isDebugEnabled()){
114                             log.debug("AUTH passing up event");
115                         }
116                         up_prot.up(evt);
117                     }else{
118                         //invalid token
119
if(log.isWarnEnabled()){
120                             log.warn("AUTH failed to validate AuthHeader token");
121                         }
122                         down_prot.down(createFailureEvent(msg.getSrc(), "Authentication failed"));
123                     }
124                 }else{
125                     //Invalid AUTH Header - need to send failure message
126
if(log.isWarnEnabled()){
127                         log.warn("AUTH failed to get valid AuthHeader from Message");
128                     }
129                     down_prot.down(createFailureEvent(msg.getSrc(), "Failed to find valid AuthHeader in Message"));
130                 }
131             }else{
132                 if(log.isDebugEnabled()){
133                     log.debug("No AUTH Header Found");
134                 }
135                 //should be a failure
136
down_prot.down(createFailureEvent(msg.getSrc(), "Failed to find an AuthHeader in Message"));
137             }
138         }else{
139             //if debug
140
if(log.isDebugEnabled()){
141                 log.debug("Message not a JOIN_REQ - ignoring it");
142             }
143             return up_prot.up(evt);
144         }
145         return null;
146     }
147
148     /**
149      * An event is to be sent down the stack. The layer may want to examine its type and perform
150      * some action on it, depending on the event's type. If the event is a message MSG, then
151      * the layer may need to add a header to it (or do nothing at all) before sending it down
152      * the stack using <code>down_prot.down()</code>. In case of a GET_ADDRESS event (which tries to
153      * retrieve the stack's address from one of the bottom layers), the layer may need to send
154      * a new response event back up the stack using <code>up_prot.up()</code>.
155      */

156     public Object JavaDoc down(Event evt) {
157         GMS.GmsHeader hdr = isJoinMessage(evt);
158         if((hdr != null) && (hdr.getType() == GMS.GmsHeader.JOIN_REQ)){
159             if(log.isDebugEnabled()){
160                 log.debug("AUTH got down event");
161             }
162             //we found a join request message - now add an AUTH Header
163
Message msg = (Message)evt.getArg();
164             AuthHeader authHeader = new AuthHeader();
165             authHeader.setToken(this.serverSideToken);
166             msg.putHeader(AUTH.NAME, authHeader);
167
168             if(log.isDebugEnabled()){
169                 log.debug("AUTH passing down event");
170             }
171         }
172
173         if((hdr != null) && (hdr.getType() == GMS.GmsHeader.JOIN_RSP)){
174             if(log.isDebugEnabled()){
175                 log.debug(hdr.toString());
176             }
177         }
178
179         return down_prot.down(evt);
180     }
181
182     /**
183      * Used to check if the message type is a Gms message
184      * @param evt The event object passed in to AUTH
185      * @return A GmsHeader object or null if the event contains a message of a different type
186      */

187     private static GMS.GmsHeader isJoinMessage(Event evt){
188         Message msg;
189         switch(evt.getType()){
190           case Event.MSG:
191                 msg = (Message)evt.getArg();
192                 Object JavaDoc obj = msg.getHeader("GMS");
193                 if(obj == null || !(obj instanceof GMS.GmsHeader)){
194                     return null;
195                 }
196                 return (GMS.GmsHeader)obj;
197         }
198         return null;
199     }
200 }
201
Popular Tags