1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.mortbay.jetty.client.security;
16
17
18 import java.io.IOException;
19 import java.security.MessageDigest;
20 import java.util.Map;
21
22 import org.mortbay.jetty.HttpHeaders;
23 import org.mortbay.jetty.client.HttpExchange;
24 import org.mortbay.util.StringUtil;
25 import org.mortbay.util.TypeUtil;
26
27 public class DigestAuthorization implements Authorization
28 {
29 private static final String NC = "00000001";
30 Realm securityRealm;
31 Map details;
32
33 public DigestAuthorization(Realm realm, Map details)
34 {
35 this.securityRealm=realm;
36 this.details=details;
37 }
38
39
40 public void setCredentials( HttpExchange exchange )
41 throws IOException
42 {
43 StringBuilder buffer = new StringBuilder().append("Digest");
44
45 buffer.append(" ").append("username").append('=').append('"').append(securityRealm.getPrincipal()).append('"');
46
47 buffer.append(", ").append("realm").append('=').append('"').append(String.valueOf(details.get("realm"))).append('"');
48
49 buffer.append(", ").append("nonce").append('=').append('"').append(String.valueOf(details.get("nonce"))).append('"');
50
51 buffer.append(", ").append("uri").append('=').append('"').append(exchange.getURI()).append('"');
52
53 buffer.append(", ").append("algorithm").append('=').append(String.valueOf(details.get("algorithm")));
54
55 String cnonce = newCnonce(exchange, securityRealm, details);
56
57 buffer.append(", ").append("response").append('=').append('"').append(newResponse(cnonce,
58 exchange, securityRealm, details)).append('"');
59
60 buffer.append(", ").append("qop").append('=').append(String.valueOf(details.get("qop")));
61
62
63 buffer.append(", ").append("nc").append('=').append(NC);
64
65 buffer.append(", ").append("cnonce").append('=').append('"').append(cnonce).append('"');
66
67 exchange.setRequestHeader( HttpHeaders.AUTHORIZATION,
68 new String(buffer.toString().getBytes(StringUtil.__ISO_8859_1)));
69 }
70
71 protected String newResponse(String cnonce, HttpExchange exchange, Realm securityRealm, Map details)
72 {
73 try{
74 MessageDigest md = MessageDigest.getInstance("MD5");
75
76
77 md.update(securityRealm.getPrincipal().getBytes(StringUtil.__ISO_8859_1));
78 md.update((byte)':');
79 md.update(String.valueOf(details.get("realm")).getBytes(StringUtil.__ISO_8859_1));
80 md.update((byte)':');
81 md.update(securityRealm.getCredentials().getBytes(StringUtil.__ISO_8859_1));
82 byte[] ha1 = md.digest();
83
84 md.reset();
85 md.update(exchange.getMethod().getBytes(StringUtil.__ISO_8859_1));
86 md.update((byte)':');
87 md.update(exchange.getURI().getBytes(StringUtil.__ISO_8859_1));
88 byte[] ha2=md.digest();
89
90 md.update(TypeUtil.toString(ha1,16).getBytes(StringUtil.__ISO_8859_1));
91 md.update((byte)':');
92 md.update(String.valueOf(details.get("nonce")).getBytes(StringUtil.__ISO_8859_1));
93 md.update((byte)':');
94 md.update(NC.getBytes(StringUtil.__ISO_8859_1));
95 md.update((byte)':');
96 md.update(cnonce.getBytes(StringUtil.__ISO_8859_1));
97 md.update((byte)':');
98 md.update(String.valueOf(details.get("qop")).getBytes(StringUtil.__ISO_8859_1));
99 md.update((byte)':');
100 md.update(TypeUtil.toString(ha2,16).getBytes(StringUtil.__ISO_8859_1));
101 byte[] digest=md.digest();
102
103
104 return encode(digest);
105 }
106 catch(Exception e)
107 {
108 e.printStackTrace();
109 return null;
110 }
111 }
112
113 protected String newCnonce(HttpExchange exchange, Realm securityRealm, Map details)
114 {
115 try
116 {
117 MessageDigest md = MessageDigest.getInstance("MD5");
118 byte[] b= md.digest(String.valueOf(System.currentTimeMillis()).getBytes(StringUtil.__ISO_8859_1));
119 return encode(b);
120 }
121 catch(Exception e)
122 {
123 e.printStackTrace();
124 return null;
125 }
126 }
127
128 private static String encode(byte[] data)
129 {
130 StringBuilder buffer = new StringBuilder();
131 for (int i=0; i<data.length; i++)
132 {
133 buffer.append(Integer.toHexString((data[i] & 0xf0) >>> 4));
134 buffer.append(Integer.toHexString(data[i] & 0x0f));
135 }
136 return buffer.toString();
137 }
138
139 }