Skip to content

Should return www-authenticate even for "X-Requested-With: XMLHttpRequest" requests #16103

Closed
@MartinEmrich

Description

@MartinEmrich

Describe the bug
Since migrating to Spring Security 6, Calling APIs using simple jQuery/XHR with basic auth results in final 401 errors, despite being logged in through the browser basic auth dialog.

Analyzing the responses, they are missing the mandatory WWW-Authenticate header. Thus the browser will not attempt the (already present) basic auth credentials.

IMHO this is a bug, as that header is mandatory: https://datatracker.ietf.org/doc/html/rfc9110#name-www-authenticate

To Reproduce
Implement a simple app with

	public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
		return http
				.csrf(AbstractHttpConfigurer::disable)
				.cors(cors -> cors.disable())
				.authorizeHttpRequests(
						matchers -> matchers
								.requestMatchers("/some/**", "/some/more/**", "/error/**")
								.permitAll()
								.requestMatchers("/api/**", "/app/**")
								.authenticated()
								.anyRequest().authenticated())

				.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
				.httpBasic(basic -> basic.realmName("my-realm"))
				.build();
	}
        // a valid AuthenticationProvider, too...

Expected behavior
have a (valid) www-authenticate response header in all 401 responses.

Additional Info

The behaviour was first implemented here: 4ef0460#diff-0f2a9f7a8a020191e00efb336582d7d71dd46130bc4b5cbc86eba681c498751fR92

Current state:

entryPoints.put(X_REQUESTED_WITH, new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));

I guess this line of code just does not explicitly put the www-authenticate header.

Workaround

My workaround is to provide a simple BasicAuthenticationEntryPoint without that special treatment for XMLHttpRequest:

		BasicAuthenticationEntryPoint basicAuthEntryPoint = new BasicAuthenticationEntryPoint();
		basicAuthEntryPoint.setRealmName(BASIC_AUTH_REALM);

and setting it in the SecurityFilterChain

				.httpBasic(basic -> basic.realmName(BASIC_AUTH_REALM).authenticationEntryPoint(basicAuthEntryPoint))

Metadata

Metadata

Assignees

Labels

in: webAn issue in web modules (web, webmvc)status: invalidAn issue that we don't feel is validtype: bugA general bug

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions