1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.acegisecurity.ui.digestauth;
17
18 import java.io.IOException;
19
20 import javax.servlet.ServletException;
21 import javax.servlet.ServletRequest;
22 import javax.servlet.ServletResponse;
23 import javax.servlet.http.HttpServletResponse;
24
25 import org.acegisecurity.AuthenticationException;
26 import org.acegisecurity.ui.AuthenticationEntryPoint;
27 import org.apache.commons.codec.binary.Base64;
28 import org.apache.commons.codec.digest.DigestUtils;
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.springframework.beans.factory.InitializingBean;
32 import org.springframework.core.Ordered;
33
34
35
36
37
38
39
40
41
42
43
44
45
46 public class DigestProcessingFilterEntryPoint implements AuthenticationEntryPoint, InitializingBean, Ordered {
47
48
49 private static final Log logger = LogFactory.getLog(DigestProcessingFilterEntryPoint.class);
50
51
52
53 private String key;
54 private String realmName;
55 private int nonceValiditySeconds = 300;
56 private int order = Integer.MAX_VALUE;
57
58
59
60 public int getOrder() {
61 return order;
62 }
63
64 public void setOrder(int order) {
65 this.order = order;
66 }
67
68 public void afterPropertiesSet() throws Exception {
69 if ((realmName == null) || "".equals(realmName)) {
70 throw new IllegalArgumentException("realmName must be specified");
71 }
72
73 if ((key == null) || "".equals(key)) {
74 throw new IllegalArgumentException("key must be specified");
75 }
76 }
77
78 public void commence(ServletRequest request, ServletResponse response, AuthenticationException authException)
79 throws IOException, ServletException {
80 HttpServletResponse httpResponse = (HttpServletResponse) response;
81
82
83
84
85 long expiryTime = System.currentTimeMillis() + (nonceValiditySeconds * 1000);
86 String signatureValue = new String(DigestUtils.md5Hex(expiryTime + ":" + key));
87 String nonceValue = expiryTime + ":" + signatureValue;
88 String nonceValueBase64 = new String(Base64.encodeBase64(nonceValue.getBytes()));
89
90
91
92
93 String authenticateHeader = "Digest realm=\"" + realmName + "\", " + "qop=\"auth\", nonce=\""
94 + nonceValueBase64 + "\"";
95
96 if (authException instanceof NonceExpiredException) {
97 authenticateHeader = authenticateHeader + ", stale=\"true\"";
98 }
99
100 if (logger.isDebugEnabled()) {
101 logger.debug("WWW-Authenticate header sent to user agent: " + authenticateHeader);
102 }
103
104 httpResponse.addHeader("WWW-Authenticate", authenticateHeader);
105 httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage());
106 }
107
108 public String getKey() {
109 return key;
110 }
111
112 public int getNonceValiditySeconds() {
113 return nonceValiditySeconds;
114 }
115
116 public String getRealmName() {
117 return realmName;
118 }
119
120 public void setKey(String key) {
121 this.key = key;
122 }
123
124 public void setNonceValiditySeconds(int nonceValiditySeconds) {
125 this.nonceValiditySeconds = nonceValiditySeconds;
126 }
127
128 public void setRealmName(String realmName) {
129 this.realmName = realmName;
130 }
131 }