View Javadoc

1   package org.astrogrid.security;
2   
3   import java.net.URISyntaxException;
4   import org.astrogrid.community.client.security.service.SecurityServiceDelegate;
5   import org.astrogrid.community.common.exception.CommunityException;
6   import org.astrogrid.community.common.exception.CommunityIdentifierException;
7   import org.astrogrid.community.common.exception.CommunitySecurityException;
8   import org.astrogrid.community.common.security.data.SecurityToken;
9   import org.astrogrid.community.resolver.CommunityTokenResolver;
10  import org.astrogrid.community.resolver.security.service.SecurityServiceResolver;
11  import org.astrogrid.registry.RegistryException;
12  import org.astrogrid.store.Ivorn;
13  
14  /***
15   * Trivial extension of
16   * org.astrogrid.community.common.security.data.SecurityToken.
17   * This class just changes the name, so as to be more specific
18   * about what kind of token is represented.
19   *
20   * A NonceToken composes an account name, which must be expressed
21   * as an IVORN and a nonce.
22   *
23   * @author Guy Rixon
24   */
25  public class NonceToken extends SecurityToken {
26  
27    /***
28     * Obtains a nonce token by signing on to the community service.
29     * This requires the single-sign-on (SSO) account-name and
30     * password.
31     *
32     * @param accountName the SSO account-name
33     * @param password the SSO password
34     * @return the nonce token
35     * @throws InvalidCredentialException if the SSO password is rejected
36     * @throws InvalidAccountException if the SSO account is rejected
37     * @throws AuthenticatorUnavailable if the community service fails
38     */
39    public static NonceToken signOn (String accountName,
40                                     String password)
41          throws AuthenticatorUnavailableException,
42    		       InvalidAccountException,
43  		       InvalidCredentialException {
44  	try {
45  	  SecurityServiceResolver ssr = new SecurityServiceResolver();
46  	  SecurityServiceDelegate ssd = ssr.resolve(new Ivorn(accountName));
47  	  SecurityToken token = ssd.checkPassword(accountName, password);
48  	  return new NonceToken(token);
49      }
50      catch (URISyntaxException use) {
51        throw new InvalidAccountException("The account name was rejected", use);
52      }
53      catch (CommunityIdentifierException cie) {
54        throw new InvalidAccountException("The account name was rejected", cie);
55      }
56      catch (CommunitySecurityException cse) {
57        throw new InvalidCredentialException("The password was rejected", cse);
58      }
59      catch (Exception e) {
60  	  throw new AuthenticatorUnavailableException(
61  		            "Authentication failed because the community managing " +
62  		            "the account is not reachable",
63  		            e
64  		        );
65      }
66    }
67  
68  
69    /***
70     * Constructs a NonceToken from a given string.
71     * The string must follow the conventions of the
72     * AstroGrid community component.
73     *
74     * @param token the nonce, including both nonce and account name
75     */
76    public NonceToken (String token) {
77      super(token);
78    }
79  
80    /***
81     * Constructs a NonceToken from a pair of strings.
82     * The strings must follow the conventions of the
83     * AstroGrid community component.
84     *
85     * @param account the account name
86     * @param nonce   the nonce
87     */
88    public NonceToken (String account, String nonce) {
89      super(account, nonce);
90    }
91  
92  
93    /***
94     * Constructs a NonceToken by cloning a token
95     * obtained from the community service.
96     *
97     * @param t the community's original token
98     */
99    public NonceToken (SecurityToken t) {
100     super();
101     this.setAccount(t.getAccount());
102     this.setToken(t.getToken());
103     this.setStatus(t.getStatus());
104   }
105 
106 
107   /***
108    * Validates this nonce token.  Validation involves
109    * sending the token to the community service that issued it.
110    * If the validation succeeds, the community issues a new nonce
111    * to the given account and this object extracts and stores the
112    * new nonce.  If the validation fails, then an exception is thrown.
113    *
114    * @throws AuthenticatorUnavailableException if the community or registry fail
115    * @throws InvalidAccountException if the account name is rejected
116    * @throws InvalidCredentialException if the nonce is rejected
117    *
118    */
119   public void validate () throws AuthenticatorUnavailableException,
120                                  InvalidAccountException,
121                                  InvalidCredentialException {
122     try {
123 
124 
125       // Validate this token.  An exception is thrown here if
126       // validation fails.
127       System.out.println("Validating token: " + this.toString());
128       CommunityTokenResolver resolver = new CommunityTokenResolver();
129       SecurityToken newToken = resolver.checkToken(this);
130 
131       // Update the nonce. Leave the account name unchanged.
132       this.setToken(newToken.getToken());
133     }
134     catch (CommunityIdentifierException cie) {
135       throw new InvalidAccountException("The account name was rejected", cie);
136     }
137     catch (CommunitySecurityException cse) {
138       throw new InvalidCredentialException("The password was rejected", cse);
139     }
140     catch (Exception e) {
141   	  throw new AuthenticatorUnavailableException(
142   	  	            "Authentication failed because the community managing " +
143   		            "the account is not reachable",
144   		            e
145   		        );
146     }
147   }
148 
149 
150   /***
151    * Create an extra nonce token. The creation process validates the
152    * existing nonce and thus replaces it.  If this validation fails,
153    * then an exception is thrown .
154    *
155    * @throws AuthenticatorUnavailableException if the community or registry fail
156    * @throws InvalidAccountException if the account name is rejected
157    * @throws InvalidCredentialException if the nonce is rejected
158    *
159    */
160   public NonceToken split () throws AuthenticatorUnavailableException,
161                                     InvalidAccountException,
162                                     InvalidCredentialException {
163     try {
164 
165       // Split this token.  An exception is thrown here if
166       // validation fails.
167       System.out.println("Existing token: " + this.toString());
168       CommunityTokenResolver resolver = new CommunityTokenResolver();
169       Object[] o = resolver.splitToken(this, 2);
170       assert(o.length == 2);
171       assert(o[0] instanceof SecurityToken);
172       assert(o[1] instanceof SecurityToken);
173 
174       // Update the nonce. Leave the account name unchanged.
175       this.setToken(((SecurityToken) o[0]).getToken());
176 
177       // Return the second token as a nonce token.
178       return new NonceToken((SecurityToken) o[1]);
179     }
180     catch (CommunityIdentifierException cie) {
181 	  throw new InvalidAccountException("The account name was rejected", cie);
182 	}
183 	catch (CommunitySecurityException cse) {
184 	  throw new InvalidCredentialException("The password was rejected", cse);
185 	}
186 	catch (Exception e) {
187 	  throw new AuthenticatorUnavailableException(
188 	    	        "Authentication failed because the community managing " +
189 	  		        "the account is not reachable",
190 	  		        e
191 	  		    );
192     }
193   }
194 }