Keywords: Spring Boot | AngularJS | CORS | Cross-Domain Authentication | Spring Security
Abstract: This technical paper provides an in-depth analysis of Cross-Origin Resource Sharing (CORS) implementation in Spring Boot backend and AngularJS frontend architectures. Through detailed examination of common 401 unauthorized errors, the article explores proper CORS filter configuration, Spring Security integration, and frontend-backend coordination mechanisms. Based on best practices, it offers complete code examples and configuration guidelines to help developers resolve cross-domain authentication issues efficiently.
Background of Cross-Origin Resource Sharing Issues
In modern web application development, frontend-backend separation architecture has become the mainstream pattern. However, when an AngularJS frontend application runs on http://localhost:50029 while the Spring Boot backend service operates on http://localhost:8080, browsers block cross-origin requests due to security concerns, resulting in 401 unauthorized errors even after successful authentication.
CORS Core Mechanism Analysis
Cross-Origin Resource Sharing (CORS) is a W3C standard that allows web application servers to specify which external domains can access their resources. When browsers detect cross-origin requests, they first send preflight (OPTIONS) requests to verify whether the server permits such cross-domain access. Only when the server returns appropriate CORS headers will the actual request be executed.
Spring Boot CORS Filter Implementation
Based on best practices, we recommend the following simplified CORS filter implementation:
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class SimpleCORSFilter implements Filter {
private final Logger log = LoggerFactory.getLogger(SimpleCORSFilter.class);
public SimpleCORSFilter() {
log.info("SimpleCORSFilter init");
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void destroy() {
}
}
Key Configuration Parameters Explained
The critical configuration items in the above filter require special attention:
- Access-Control-Allow-Origin: Set to the request's Origin header for dynamic matching with frontend application addresses
- Access-Control-Allow-Credentials: Set to
"true"to allow transmission of authentication information like cookies - Access-Control-Allow-Methods: Explicit list of permitted HTTP methods
- Access-Control-Allow-Headers: Includes authentication-related
remember-meheader
Spring Security Integration Configuration
When using Spring Security, CORS support must be enabled in the security configuration:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and()
.csrf().disable()
// Other security configurations remain unchanged
.authorizeRequests()
.antMatchers("/api/admin/**").hasRole("ADMIN")
// Continue with other configurations
}
AngularJS Frontend Configuration Optimization
In the frontend AngularJS service, ensure proper setting of authentication-related parameters:
adminServices.factory('AdminService', ['$resource', '$http', 'conf', function($resource, $http, conf) {
var s = {};
s.isAdminLoggedIn = function(data) {
return $http({
method: 'GET',
url: 'http://localhost:8080/api/admin/isloggedin',
withCredentials: true, // Critical: Enable credential transmission
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
});
};
// Other service methods
return s;
}]);
Common Issue Troubleshooting
In actual deployment, developers frequently encounter the following issues:
- Preflight Request Failure: Ensure OPTIONS method is included in the allowed methods list
- Authentication Information Loss: Check
withCredentials: truesetting andAccess-Control-Allow-Credentials: trueconfiguration - Missing Headers: Verify all required authentication headers are listed in
Access-Control-Allow-Headers
Alternative Configuration Approaches
Beyond the filter approach, Spring provides other CORS configuration options:
- Using
@CrossOriginannotation for controller-level configuration - Implementing global CORS configuration through
WebMvcConfigurer - Combining with Spring Security's CORS configurator
Conclusion and Best Practices
By properly configuring CORS filters and integrating with Spring Security, cross-domain authentication issues in frontend-backend separated applications can be effectively resolved. The key is to ensure all relevant CORS headers are correctly set and maintain consistency in authentication information transmission between frontend and backend. It is recommended to use dynamic Origin configuration in development environments while restricting to specific trusted domains in production environments.