You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by bu...@apache.org on 2020/05/05 10:42:14 UTC
[cxf] branch master updated: DigestAuthSupplier: fix nc-value and
update cnonce generation (#666)
This is an automated email from the ASF dual-hosted git repository.
buhhunyx pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/master by this push:
new 41c6c00 DigestAuthSupplier: fix nc-value and update cnonce generation (#666)
41c6c00 is described below
commit 41c6c0059f6745098c6f728cd652cbafe83bc986
Author: Alexey Markevich <bu...@gmail.com>
AuthorDate: Tue May 5 13:42:02 2020 +0300
DigestAuthSupplier: fix nc-value and update cnonce generation (#666)
DigestAuthSupplier: fix nc-value and update cnonce generation
---
.../org/apache/cxf/transport/http/HTTPConduit.java | 4 +-
.../transport/http/auth/DigestAuthSupplier.java | 83 ++++--------
.../cxf/transport/http/auth/HttpAuthHeader.java | 3 +-
.../http/auth/DigestAuthSupplierTest.java | 14 +-
systests/transports/pom.xml | 45 +++++++
.../http/auth/DigestAuthSupplierJettyTest.java | 140 ++++++++++++++++++++
.../http/auth/DigestAuthSupplierSpringTest.java | 145 +++++++++++++++++++++
.../test/resources/digestauth/WEB-INF/beans.xml | 3 +-
8 files changed, 362 insertions(+), 75 deletions(-)
diff --git a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
index a4d7193..4f44e9e 100644
--- a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
+++ b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
@@ -1934,7 +1934,7 @@ public abstract class HTTPConduit
// retransmit, it means we have already supplied information
// which must have been wrong, or we wouldn't be here again.
// Otherwise, the server may be 401 looping us around the realms.
- if (authURLs.contains(currentURL.toString() + realm)) {
+ if (!authURLs.add(currentURL.toString() + realm)) {
String logMessage = "Authorization loop detected on Conduit \""
+ conduitName
+ "\" on URL \""
@@ -1948,7 +1948,5 @@ public abstract class HTTPConduit
throw new IOException(logMessage);
}
- // Register that we have been here before we go.
- authURLs.add(currentURL.toString() + realm);
}
}
diff --git a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/auth/DigestAuthSupplier.java b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/auth/DigestAuthSupplier.java
index 4824fbb..f2e4488 100644
--- a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/auth/DigestAuthSupplier.java
+++ b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/auth/DigestAuthSupplier.java
@@ -19,38 +19,26 @@
package org.apache.cxf.transport.http.auth;
-import java.io.UnsupportedEncodingException;
import java.net.URI;
+import java.nio.ByteBuffer;
import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.configuration.security.AuthorizationPolicy;
import org.apache.cxf.message.Message;
+import static java.nio.charset.StandardCharsets.US_ASCII;
+
/**
*
*/
public class DigestAuthSupplier implements HttpAuthSupplier {
- private static final char[] HEXADECIMAL = {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
- };
- final MessageDigest md5Helper;
Map<URI, DigestInfo> authInfo = new ConcurrentHashMap<>();
- public DigestAuthSupplier() {
- MessageDigest md = null;
- try {
- md = MessageDigest.getInstance("MD5");
- } catch (NoSuchAlgorithmException e) {
- //ignore - set to null
- }
- md5Helper = md;
- }
-
/**
* {@inheritDoc}
* With digest, the nonce could expire and thus a rechallenge will be issued.
@@ -119,13 +107,8 @@ public class DigestAuthSupplier implements HttpAuthSupplier {
return authURI;
}
- public String createCnonce() throws UnsupportedEncodingException {
- String cnonce = Long.toString(System.currentTimeMillis());
- byte[] bytes = cnonce.getBytes("US-ASCII");
- synchronized (md5Helper) {
- bytes = md5Helper.digest(bytes);
- }
- return encode(bytes);
+ public String createCnonce() {
+ return Long.toString(System.currentTimeMillis());
}
class DigestInfo {
@@ -140,31 +123,31 @@ public class DigestAuthSupplier implements HttpAuthSupplier {
synchronized String generateAuth(String uri, String username, String password) {
try {
- nc++;
- String ncstring = String.format("%08d", nc);
- String cnonce = createCnonce();
-
String digAlg = algorithm;
if ("MD5-sess".equalsIgnoreCase(digAlg)) {
digAlg = "MD5";
}
- MessageDigest digester = MessageDigest.getInstance(digAlg);
- String a1 = username + ":" + realm + ":" + password;
+ final MessageDigest digester = MessageDigest.getInstance(digAlg);
+ String cnonce = createCnonce();
+ String a1 = username + ':' + realm + ':' + password;
if ("MD5-sess".equalsIgnoreCase(algorithm)) {
- String tmp2 = encode(digester.digest(a1.getBytes(charset)));
+ String tmp2 = StringUtils.toHexString(digester.digest(a1.getBytes(charset)));
a1 = tmp2 + ':' + nonce + ':' + cnonce;
}
- String hasha1 = encode(digester.digest(a1.getBytes(charset)));
- String a2 = method + ":" + uri;
- String hasha2 = encode(digester.digest(a2.getBytes("US-ASCII")));
- String serverDigestValue = null;
+ String hasha1 = StringUtils.toHexString(digester.digest(a1.getBytes(charset)));
+ String a2 = method + ':' + uri;
+ String hasha2 = StringUtils.toHexString(digester.digest(a2.getBytes(US_ASCII)));
+ final String serverDigestValue;
+ final String ncstring;
if (qop == null) {
- serverDigestValue = hasha1 + ":" + nonce + ":" + hasha2;
+ ncstring = null;
+ serverDigestValue = hasha1 + ':' + nonce + ':' + hasha2;
} else {
- serverDigestValue = hasha1 + ":" + nonce + ":" + ncstring + ":" + cnonce + ":"
- + qop + ":" + hasha2;
+ ncstring = StringUtils.toHexString(ByteBuffer.allocate(4).putInt(++nc).array());
+ serverDigestValue = hasha1 + ':' + nonce + ':' + ncstring + ':' + cnonce + ':'
+ + qop + ':' + hasha2;
}
- String response = encode(digester.digest(serverDigestValue.getBytes("US-ASCII")));
+ String response = StringUtils.toHexString(digester.digest(serverDigestValue.getBytes(US_ASCII)));
Map<String, String> outParams = new HashMap<>();
if (qop != null) {
outParams.put("qop", "auth");
@@ -174,7 +157,9 @@ public class DigestAuthSupplier implements HttpAuthSupplier {
outParams.put("nonce", nonce);
outParams.put("uri", uri);
outParams.put("username", username);
- outParams.put("nc", ncstring);
+ if (ncstring != null) {
+ outParams.put("nc", ncstring);
+ }
outParams.put("cnonce", cnonce);
outParams.put("response", response);
outParams.put("algorithm", algorithm);
@@ -187,24 +172,4 @@ public class DigestAuthSupplier implements HttpAuthSupplier {
}
- /**
- * Encodes the 128 bit (16 bytes) MD5 digest into a 32 characters long
- * <CODE>String</CODE> according to RFC 2617.
- *
- * @param binaryData array containing the digest
- * @return encoded MD5, or <CODE>null</CODE> if encoding failed
- */
- private static String encode(byte[] binaryData) {
- int n = binaryData.length;
- char[] buffer = new char[n * 2];
- for (int i = 0; i < n; i++) {
- int low = binaryData[i] & 0x0f;
- int high = (binaryData[i] & 0xf0) >> 4;
- buffer[i * 2] = HEXADECIMAL[high];
- buffer[(i * 2) + 1] = HEXADECIMAL[low];
- }
-
- return new String(buffer);
- }
-
}
diff --git a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/auth/HttpAuthHeader.java b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/auth/HttpAuthHeader.java
index 6d3b37d..f7b8469 100644
--- a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/auth/HttpAuthHeader.java
+++ b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/auth/HttpAuthHeader.java
@@ -135,8 +135,7 @@ public final class HttpAuthHeader {
* @return The realm, or null if it is non-existent.
*/
public String getRealm() {
- Map<String, String> map = parseHeader();
- return map.get("realm");
+ return params.get("realm");
}
public boolean authTypeIsDigest() {
diff --git a/rt/transports/http/src/test/java/org/apache/cxf/transport/http/auth/DigestAuthSupplierTest.java b/rt/transports/http/src/test/java/org/apache/cxf/transport/http/auth/DigestAuthSupplierTest.java
index 6bee107..e9dc03c 100644
--- a/rt/transports/http/src/test/java/org/apache/cxf/transport/http/auth/DigestAuthSupplierTest.java
+++ b/rt/transports/http/src/test/java/org/apache/cxf/transport/http/auth/DigestAuthSupplierTest.java
@@ -18,7 +18,6 @@
*/
package org.apache.cxf.transport.http.auth;
-import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
@@ -27,11 +26,10 @@ import org.apache.cxf.configuration.security.AuthorizationPolicy;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageImpl;
-import org.easymock.EasyMock;
-import org.easymock.IMocksControl;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
public class DigestAuthSupplierTest {
@@ -64,35 +62,33 @@ public class DigestAuthSupplierTest {
DigestAuthSupplier authSupplier = new DigestAuthSupplier() {
@Override
- public String createCnonce() throws UnsupportedEncodingException {
+ public String createCnonce() {
return "27db039b76362f3d55da10652baee38c";
}
};
- IMocksControl control = EasyMock.createControl();
AuthorizationPolicy authorizationPolicy = new AuthorizationPolicy();
authorizationPolicy.setUserName("testUser");
authorizationPolicy.setPassword("testPassword");
URI uri = new URI("http://myserver");
Message message = new MessageImpl();
- control.replay();
String authToken = authSupplier
.getAuthorization(authorizationPolicy, uri, message, fullHeader);
HttpAuthHeader authHeader = new HttpAuthHeader(authToken);
- assertEquals("Digest", authHeader.getAuthType());
+ assertTrue(authHeader.authTypeIsDigest());
+
Map<String, String> params = authHeader.getParams();
Map<String, String> expectedParams = new HashMap<>();
expectedParams.put("response", "28e616b6868f60aaf9b19bb5b172f076");
expectedParams.put("cnonce", "27db039b76362f3d55da10652baee38c");
expectedParams.put("username", "testUser");
expectedParams.put("nc", "00000001");
- expectedParams.put("nonce", "MTI0ODg3OTc5NzE2OTplZGUyYTg0Yzk2NTFkY2YyNjc1Y2JjZjU2MTUzZmQyYw==");
+ expectedParams.put("nonce", origNonce);
expectedParams.put("realm", "MyCompany realm.");
expectedParams.put("qop", "auth");
expectedParams.put("uri", "");
expectedParams.put("algorithm", "MD5");
assertEquals(expectedParams, params);
- control.verify();
}
}
diff --git a/systests/transports/pom.xml b/systests/transports/pom.xml
index 44e1f7b..5939a10 100644
--- a/systests/transports/pom.xml
+++ b/systests/transports/pom.xml
@@ -130,6 +130,12 @@
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-hc</artifactId>
<version>${project.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
@@ -148,6 +154,12 @@
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>${project.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
@@ -246,6 +258,39 @@
<version>${cxf.spring.version}</version>
</dependency>
<dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-config</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-web</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <version>${cxf.spring.boot.version}</version>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ <version>${cxf.spring.boot.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-rs-client</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
diff --git a/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/DigestAuthSupplierJettyTest.java b/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/DigestAuthSupplierJettyTest.java
new file mode 100644
index 0000000..3debbca
--- /dev/null
+++ b/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/DigestAuthSupplierJettyTest.java
@@ -0,0 +1,140 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.systest.http.auth;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.NotAuthorizedException;
+
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.testutil.common.AbstractClientServerTestBase;
+import org.apache.cxf.testutil.common.AbstractTestServerBase;
+import org.apache.cxf.transport.http.HTTPConduit;
+import org.apache.cxf.transport.http.auth.DigestAuthSupplier;
+import org.eclipse.jetty.security.ConstraintMapping;
+import org.eclipse.jetty.security.ConstraintSecurityHandler;
+import org.eclipse.jetty.security.HashLoginService;
+import org.eclipse.jetty.security.UserStore;
+import org.eclipse.jetty.security.authentication.DigestAuthenticator;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.util.security.Constraint;
+import org.eclipse.jetty.util.security.Credential;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+
+public class DigestAuthSupplierJettyTest extends AbstractClientServerTestBase {
+
+ private static final String USER = "alice";
+ private static final String PWD = "ecila";
+
+ @BeforeClass
+ public static void startServer() throws Exception {
+ launchServer(DigestAuthSupplierJettyServer.class);
+ }
+
+ @Test
+ public void test() {
+ WebClient client = WebClient.create("http://localhost:" + DigestAuthSupplierJettyServer.PORT, (String) null);
+
+ assertThrows(NotAuthorizedException.class, () -> client.get(String.class));
+
+ HTTPConduit conduit = WebClient.getConfig(client).getHttpConduit();
+ conduit.setAuthSupplier(new DigestAuthSupplier());
+ conduit.getAuthorization().setUserName(USER);
+ conduit.getAuthorization().setPassword(PWD);
+
+ assertEquals(TestServlet.RESPONSE, client.get(String.class));
+ }
+
+ public static class DigestAuthSupplierJettyServer extends AbstractTestServerBase {
+ private static final int PORT = allocatePortAsInt(DigestAuthSupplierJettyServer.class);
+
+ private static Server server;
+
+ @Override
+ protected void run() {
+ server = new Server(PORT);
+
+ HashLoginService loginService = new HashLoginService();
+ loginService.setName("My Realm");
+ UserStore userStore = new UserStore();
+ String[] roles = new String[] {"user"};
+ userStore.addUser(USER, Credential.getCredential(PWD), roles);
+ loginService.setUserStore(userStore);
+
+ Constraint constraint = new Constraint();
+ constraint.setName(Constraint.__DIGEST_AUTH);
+ constraint.setRoles(roles);
+ constraint.setAuthenticate(true);
+
+ ConstraintMapping cm = new ConstraintMapping();
+ cm.setConstraint(constraint);
+ cm.setPathSpec("/*");
+
+ ConstraintSecurityHandler csh = new ConstraintSecurityHandler();
+ csh.setAuthenticator(new DigestAuthenticator());
+ csh.addConstraintMapping(cm);
+ csh.setLoginService(loginService);
+
+ ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
+ context.setSecurityHandler(csh);
+ context.setContextPath("/");
+ server.setHandler(context);
+ context.addServlet(new ServletHolder(new TestServlet()), "/*");
+
+ try {
+ server.start();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ if (server != null) {
+ server.stop();
+ server.destroy();
+ server = null;
+ }
+ }
+ }
+
+ @SuppressWarnings("serial")
+ static class TestServlet extends HttpServlet {
+
+ static final String RESPONSE = "Hi!";
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ resp.getWriter().print(RESPONSE);
+ }
+
+ }
+
+}
diff --git a/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/DigestAuthSupplierSpringTest.java b/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/DigestAuthSupplierSpringTest.java
new file mode 100644
index 0000000..f14e0db
--- /dev/null
+++ b/systests/transports/src/test/java/org/apache/cxf/systest/http/auth/DigestAuthSupplierSpringTest.java
@@ -0,0 +1,145 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.systest.http.auth;
+
+import javax.ws.rs.NotAuthorizedException;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.transport.http.HTTPConduit;
+import org.apache.cxf.transport.http.auth.DigestAuthSupplier;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.context.annotation.Bean;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.web.authentication.www.DigestAuthenticationEntryPoint;
+import org.springframework.security.web.authentication.www.DigestAuthenticationFilter;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(
+ classes = {
+ DigestAuthSupplierSpringTest.SecurityConfig.class,
+ DigestAuthSupplierSpringTest.Controller.class
+ },
+ webEnvironment = WebEnvironment.RANDOM_PORT
+)
+@SpringBootApplication
+public class DigestAuthSupplierSpringTest {
+
+ private static final String USER = "alice";
+ private static final String PWD = "ecila";
+
+ @LocalServerPort
+ private int port;
+
+ @Test
+ public void test() {
+ WebClient client = WebClient.create("http://localhost:" + port, (String) null);
+
+ assertThrows(NotAuthorizedException.class, () -> client.get(String.class));
+
+ HTTPConduit conduit = WebClient.getConfig(client).getHttpConduit();
+ conduit.setAuthSupplier(new DigestAuthSupplier());
+ conduit.getAuthorization().setUserName(USER);
+ conduit.getAuthorization().setPassword(PWD);
+
+ assertEquals(Controller.RESPONSE, client.get(String.class));
+ }
+
+ @RestController
+ static class Controller {
+
+ static final String RESPONSE = "Hi!";
+
+ @GetMapping(produces = MediaType.TEXT_PLAIN)
+ public String get() {
+ return "Hi!";
+ }
+
+ }
+
+ static class SecurityConfig extends WebSecurityConfigurerAdapter {
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ DigestAuthenticationEntryPoint authenticationEntryPoint = digestAuthenticationEntryPoint();
+ http
+ .authorizeRequests().anyRequest().authenticated()
+ .and()
+ .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint)
+ .and()
+ .addFilter(digestAuthenticationFilter(authenticationEntryPoint));
+ }
+
+ private DigestAuthenticationFilter digestAuthenticationFilter(
+ DigestAuthenticationEntryPoint authenticationEntryPoint) {
+ DigestAuthenticationFilter digestAuthenticationFilter = new DigestAuthenticationFilter();
+ digestAuthenticationFilter.setUserDetailsService(userDetailsService());
+ digestAuthenticationFilter.setAuthenticationEntryPoint(authenticationEntryPoint);
+ return digestAuthenticationFilter;
+ }
+
+ private static DigestAuthenticationEntryPoint digestAuthenticationEntryPoint() {
+ DigestAuthenticationEntryPoint digestAuthenticationEntryPoint = new DigestAuthenticationEntryPoint();
+ digestAuthenticationEntryPoint.setKey("acegi");
+ digestAuthenticationEntryPoint.setRealmName("Digest Realm");
+ return digestAuthenticationEntryPoint;
+ }
+
+ @Override
+ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+ auth.inMemoryAuthentication()
+ .withUser(USER).password(PWD).roles("");
+ }
+
+ @Bean
+ public static PasswordEncoder passwordEncoder() {
+ return new PasswordEncoder() {
+ @Override
+ public String encode(CharSequence rawPassword) {
+ return rawPassword.toString();
+ }
+ @Override
+ public boolean matches(CharSequence rawPassword, String encodedPassword) {
+ return rawPassword.toString().equals(encodedPassword);
+ }
+ };
+ }
+ }
+
+ public static void main(String[] args) {
+ SpringApplication.run(DigestAuthSupplierSpringTest.class, args);
+ }
+
+}
diff --git a/systests/transports/src/test/resources/digestauth/WEB-INF/beans.xml b/systests/transports/src/test/resources/digestauth/WEB-INF/beans.xml
index 9c42d17..2040268 100644
--- a/systests/transports/src/test/resources/digestauth/WEB-INF/beans.xml
+++ b/systests/transports/src/test/resources/digestauth/WEB-INF/beans.xml
@@ -31,7 +31,6 @@
<http:destination name="{http://apache.org/hello_world}Mortimer.http-destination">
<!-- Nothing to Configure here for Mortimer -->
</http:destination>
- <bean id="greeterImpl" class="org.apache.cxf.systest.http.auth.GreeterImpl">
- </bean>
+ <bean id="greeterImpl" class="org.apache.cxf.systest.http.auth.GreeterImpl" />
<jaxws:endpoint address="/greeter" implementor="#greeterImpl" publish="true"/>
</beans>