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
126
127 System.out.println("Validating token: " + this.toString());
128 CommunityTokenResolver resolver = new CommunityTokenResolver();
129 SecurityToken newToken = resolver.checkToken(this);
130
131
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
166
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
175 this.setToken(((SecurityToken) o[0]).getToken());
176
177
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 }