|
18 | 18 | import com.sun.net.httpserver.Headers; |
19 | 19 | import com.sun.net.httpserver.HttpExchange; |
20 | 20 | import com.sun.net.httpserver.HttpPrincipal; |
21 | | -import com.sun.security.auth.UserPrincipal; |
| 21 | +import java.io.Serializable; |
22 | 22 | import java.nio.charset.StandardCharsets; |
| 23 | +import java.security.Principal; |
23 | 24 | import java.util.Base64; |
| 25 | +import java.util.Objects; |
24 | 26 | import javax.security.auth.Subject; |
25 | 27 |
|
| 28 | +/** Example custom authenticator */ |
26 | 29 | public class CustomAuthenticator extends Authenticator { |
27 | 30 |
|
| 31 | + private static final String AUTHORIZATION = "Authorization"; |
| 32 | + private static final String BASIC = "Basic"; |
| 33 | + |
| 34 | + private static final String USERNAME = "Prometheus"; |
| 35 | + private static final String PASSWORD = "secret"; |
| 36 | + |
28 | 37 | @Override |
29 | | - public Result authenticate(HttpExchange exch) { |
| 38 | + public Result authenticate(HttpExchange httpExchange) { |
30 | 39 | // nothing too custom, so the test works, just to demonstrate that it is plug-able |
31 | | - Headers rmap = exch.getRequestHeaders(); |
32 | | - String auth = rmap.getFirst("Authorization"); |
33 | | - if (auth == null) { |
| 40 | + Headers headers = httpExchange.getRequestHeaders(); |
| 41 | + |
| 42 | + String authorization = headers.getFirst(AUTHORIZATION); |
| 43 | + if (authorization == null) { |
34 | 44 | return new Authenticator.Retry(401); |
35 | 45 | } |
36 | | - int sp = auth.indexOf(' '); |
37 | | - if (sp == -1 || !auth.substring(0, sp).equals("Basic")) { |
| 46 | + |
| 47 | + int space = authorization.indexOf(' '); |
| 48 | + if (space == -1 || !authorization.substring(0, space).equals(BASIC)) { |
38 | 49 | return new Authenticator.Failure(401); |
39 | 50 | } |
40 | | - byte[] b = Base64.getDecoder().decode(auth.substring(sp + 1)); |
41 | | - String userpass = new String(b, StandardCharsets.UTF_8); |
42 | | - int colon = userpass.indexOf(':'); |
43 | | - String uname = userpass.substring(0, colon); |
44 | | - String pass = userpass.substring(colon + 1); |
45 | 51 |
|
46 | | - if ("Prometheus".equals(uname) && "secret".equals(pass)) { |
| 52 | + byte[] usernamePasswordBytes = |
| 53 | + Base64.getDecoder().decode(authorization.substring(space + 1)); |
| 54 | + String usernamePassword = new String(usernamePasswordBytes, StandardCharsets.UTF_8); |
| 55 | + int colon = usernamePassword.indexOf(':'); |
| 56 | + String username = usernamePassword.substring(0, colon); |
| 57 | + String password = usernamePassword.substring(colon + 1); |
| 58 | + |
| 59 | + if (USERNAME.equals(username) && PASSWORD.equals(password)) { |
47 | 60 | Subject subject = new Subject(); |
48 | | - subject.getPrincipals().add(new UserPrincipal(uname)); |
| 61 | + subject.getPrincipals().add(new UserPrincipal(username)); |
49 | 62 | // to communicate an authenticated subject for subsequent handler calls via Subject.doAs |
50 | | - exch.setAttribute("io.prometheus.jmx.CustomAuthenticatorSubjectAttribute", subject); |
51 | | - return new Authenticator.Success(new HttpPrincipal(uname, "/")); |
| 63 | + httpExchange.setAttribute( |
| 64 | + "io.prometheus.jmx.CustomAuthenticatorSubjectAttribute", subject); |
| 65 | + return new Authenticator.Success(new HttpPrincipal(username, "/")); |
52 | 66 | } else { |
53 | 67 | return new Authenticator.Failure(401); |
54 | 68 | } |
55 | 69 | } |
| 70 | + |
| 71 | + /** |
| 72 | + * Class to implement Principal |
| 73 | + * |
| 74 | + * <p>Required for ibmjava:8 since it doesn't provide com.sun.security.auth.UserPrincipal |
| 75 | + */ |
| 76 | + public static class UserPrincipal implements Principal, Serializable { |
| 77 | + |
| 78 | + private final String name; |
| 79 | + |
| 80 | + /** |
| 81 | + * Constructor |
| 82 | + * |
| 83 | + * @param name name |
| 84 | + */ |
| 85 | + public UserPrincipal(String name) { |
| 86 | + this.name = Objects.requireNonNull(name, "Name cannot be null"); |
| 87 | + } |
| 88 | + |
| 89 | + @Override |
| 90 | + public String getName() { |
| 91 | + return name; |
| 92 | + } |
| 93 | + |
| 94 | + @Override |
| 95 | + public String toString() { |
| 96 | + return "UserPrincipal{" + "name='" + name + '\'' + '}'; |
| 97 | + } |
| 98 | + |
| 99 | + @Override |
| 100 | + public boolean equals(Object object) { |
| 101 | + if (this == object) return true; |
| 102 | + if (object == null || getClass() != object.getClass()) return false; |
| 103 | + UserPrincipal that = (UserPrincipal) object; |
| 104 | + return Objects.equals(name, that.name); |
| 105 | + } |
| 106 | + |
| 107 | + @Override |
| 108 | + public int hashCode() { |
| 109 | + return Objects.hashCode(name); |
| 110 | + } |
| 111 | + } |
56 | 112 | } |
0 commit comments