Saya mencoba memanggil titik akhir REST pada satu aplikasi (aplikasi spring-boot) dari yang lain (angularjs). Aplikasi berjalan di host dan port berikut.
- Aplikasi REST, menggunakan spring boot,
http://localhost:8080
- Aplikasi HTML, menggunakan angularjs,
http://localhost:50029
Saya juga menggunakan spring-security
dengan aplikasi spring-boot. Dari aplikasi HTML, saya dapat mengautentikasi ke aplikasi REST, tetapi setelah itu, saya masih tidak dapat mengakses titik akhir REST. Misalnya, saya memiliki layanan angularjs yang didefinisikan sebagai berikut.
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,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
});
};
s.login = function(username, password) {
var u = 'username=' + encodeURI(username);
var p = 'password=' + encodeURI(password);
var r = 'remember_me=1';
var data = u + '&' + p + '&' + r;
return $http({
method: 'POST',
url: 'http://localhost:8080/login',
data: data,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
});
};
return s;
}]);
Pengontrol angularjs terlihat seperti berikut.
adminControllers.controller('LoginController', ['$scope', '$http', 'AdminService', function($scope, $http, AdminService) {
$scope.username = '';
$scope.password = '';
$scope.signIn = function() {
AdminService.login($scope.username, $scope.password)
.success(function(d,s) {
if(d['success']) {
console.log('ok authenticated, call another REST endpoint');
AdminService.isAdminLoggedIn()
.success(function(d,s) {
console.log('i can access a protected REST endpoint after logging in');
})
.error(function(d, s) {
console.log('huh, error checking to see if admin is logged in');
$scope.reset();
});
} else {
console.log('bad credentials?');
}
})
.error(function(d, s) {
console.log('huh, error happened!');
});
};
}]);
Saat panggilan ke http://localhost:8080/api/admin/isloggedin
, saya mendapatkan 401 Unauthorized
.
Di sisi aplikasi REST, saya memiliki filter CORS yang terlihat seperti berikut.
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CORSFilter implements Filter {
@Override
public void destroy() { }
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "http://localhost:50029");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "X-Requested-With, X-Auth-Token");
response.setHeader("Access-Control-Allow-Credentials", "true");
if(!"OPTIONS".equalsIgnoreCase(request.getMethod())) {
chain.doFilter(req, res);
}
}
@Override
public void init(FilterConfig config) throws ServletException { }
}
Konfigurasi keamanan pegas saya terlihat seperti berikut ini.
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
@Autowired
private JsonAuthSuccessHandler jsonAuthSuccessHandler;
@Autowired
private JsonAuthFailureHandler jsonAuthFailureHandler;
@Autowired
private JsonLogoutSuccessHandler jsonLogoutSuccessHandler;
@Autowired
private AuthenticationProvider authenticationProvider;
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private PersistentTokenRepository persistentTokenRepository;
@Value("${rememberme.key}")
private String rememberMeKey;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.exceptionHandling()
.authenticationEntryPoint(restAuthenticationEntryPoint)
.and()
.authorizeRequests()
.antMatchers("/api/admin/**").hasRole("ADMIN")
.antMatchers("/", "/admin", "/css/**", "/js/**", "/fonts/**", "/api/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.successHandler(jsonAuthSuccessHandler)
.failureHandler(jsonAuthFailureHandler)
.permitAll()
.and()
.logout()
.deleteCookies("remember-me", "JSESSIONID")
.logoutSuccessHandler(jsonLogoutSuccessHandler)
.permitAll()
.and()
.rememberMe()
.userDetailsService(userDetailsService)
.tokenRepository(persistentTokenRepository)
.rememberMeCookieName("REMEMBER_ME")
.rememberMeParameter("remember_me")
.tokenValiditySeconds(1209600)
.useSecureCookie(false)
.key(rememberMeKey);
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationProvider(authenticationProvider);
}
}
Semua yang dilakukan penangan adalah menuliskan tanggapan JSON seperti {success: true}
berdasarkan apakah pengguna masuk, gagal mengautentikasi, atau keluar. The RestAuthenticationEntryPoint
terlihat seperti berikut.
@Component
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest req, HttpServletResponse resp, AuthenticationException ex)
throws IOException, ServletException {
resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
}
Adakah ide tentang apa yang saya lewatkan atau lakukan salah?
sumber
API Gateway
dengan awan musim semi, yang saya pikir berlebihan .Jawaban:
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() { } }
Tidak perlu lebih mendefinisikan filter ini cukup tambahkan kelas ini. Spring akan memindai dan menambahkannya untuk Anda. SimpleCORSFilter. Berikut adalah contohnya: spring-enable-cors
sumber
HEADERS
danX_REDIRECT_LOCATION_HEADER
? 2) Apakah barisrequest.getRequestURL());
salah ketik atau salin / tempel? 3) Mengapa Anda tidak memeriksaOPTIONS
dan melanjutkan dengan rantai filter?request.getHeader("Origin")
seperti yang ditunjukkan di atas karena pemisahan respons HTTP@Order(Ordered.HIGHEST_PRECEDENCE)
.Saya pernah mengalami situasi serupa. Setelah melakukan penelitian dan pengujian, berikut temuan saya:
Dengan Spring Boot, cara yang disarankan untuk mengaktifkan CORS global adalah dengan mendeklarasikan di dalam Spring MVC dan dikombinasikan dengan
@CrossOrigin
konfigurasi halus sebagai:@Configuration public class CorsConfig { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE").allowedOrigins("*") .allowedHeaders("*"); } }; } }
Sekarang, karena Anda menggunakan Spring Security, Anda harus mengaktifkan CORS pada level Spring Security juga untuk memungkinkannya memanfaatkan konfigurasi yang ditentukan pada level Spring MVC sebagai:
@EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.cors().and()... } }
Berikut adalah tutorial yang sangat bagus yang menjelaskan dukungan CORS dalam kerangka MVC Spring.
sumber
Jika Anda ingin mengaktifkan CORS tanpa menggunakan filter atau tanpa file konfigurasi, tambahkan saja
@CrossOrigin
ke bagian atas pengontrol Anda dan berfungsi.
sumber
Untuk membangun jawaban lain di atas, jika Anda memiliki aplikasi layanan Spring boot REST (bukan Spring MVC) dengan keamanan Spring, maka mengaktifkan CORS melalui keamanan Spring sudah cukup (jika Anda menggunakan Spring MVC maka gunakan
WebMvcConfigurer
kacang seperti yang disebutkan oleh Yogen dapat cara untuk pergi karena keamanan Spring akan mendelegasikan definisi CORS yang disebutkan di dalamnya)Jadi, Anda perlu memiliki konfigurasi keamanan yang melakukan hal berikut:
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { //other http security config http.cors().configurationSource(corsConfigurationSource()); } //This can be customized as required CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); List<String> allowOrigins = Arrays.asList("*"); configuration.setAllowedOrigins(allowOrigins); configuration.setAllowedMethods(singletonList("*")); configuration.setAllowedHeaders(singletonList("*")); //in case authentication is enabled this flag MUST be set, otherwise CORS requests will fail configuration.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; }
}
Tautan ini memiliki lebih banyak informasi tentang hal yang sama: https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#cors
catatan:
UserDetailsService
misalnya) makaconfiguration.setAllowCredentials(true);
harus ditambahkanDiuji untuk Spring boot 2.0.0.RELEASE (yaitu Spring 5.0.4.RELEASE dan Spring security 5.0.3.RELEASE)
sumber
Saya menggunakan
spring boot 2.1.0
dan apa yang berhasil bagi saya adalahA. Tambahkan pemetaan kors dengan:
@Configuration public class Config implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**").allowedOrigins("*"); } }
B. Tambahkan konfigurasi di bawah ini ke my
HttpSecurity
for spring security.cors().configurationSource(new CorsConfigurationSource() { @Override public CorsConfiguration getCorsConfiguration(HttpServletRequest request) { CorsConfiguration config = new CorsConfiguration(); config.setAllowedHeaders(Collections.singletonList("*")); config.setAllowedMethods(Collections.singletonList("*")); config.addAllowedOrigin("*"); config.setAllowCredentials(true); return config; } })
Juga dalam kasus proxy Zuul Anda dapat menggunakan ini BUKAN A dan B (cukup gunakan
HttpSecurity.cors()
untuk mengaktifkannya di keamanan Spring):@Bean public CorsFilter corsFilter() { final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); final CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.addAllowedOrigin("*"); config.addAllowedHeader("*"); config.addAllowedMethod("OPTIONS"); config.addAllowedMethod("HEAD"); config.addAllowedMethod("GET"); config.addAllowedMethod("PUT"); config.addAllowedMethod("POST"); config.addAllowedMethod("DELETE"); config.addAllowedMethod("PATCH"); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); }
sumber
org.springframework.web.filter.CorsFilter
. Saya memiliki masalah yang sama ketika saya menggunakannya dari paket katalina secara tidak sengaja.Ini bekerja untuk saya:
@Configuration public class MyConfig extends WebSecurityConfigurerAdapter { //... @Override protected void configure(HttpSecurity http) throws Exception { //... http.cors().configurationSource(new CorsConfigurationSource() { @Override public CorsConfiguration getCorsConfiguration(HttpServletRequest request) { CorsConfiguration config = new CorsConfiguration(); config.setAllowedHeaders(Collections.singletonList("*")); config.setAllowedMethods(Collections.singletonList("*")); config.addAllowedOrigin("*"); config.setAllowCredentials(true); return config; } }); //... } //... }
sumber
Bagi saya, satu-satunya hal yang berhasil 100% saat pengaman pegas digunakan adalah melewatkan semua bulu tambahan dari filter dan kacang tambahan dan "sihir" tidak langsung apa pun yang terus disarankan orang yang berhasil untuk mereka tetapi tidak untuk saya.
Alih-alih memaksanya untuk menulis header yang Anda butuhkan dengan polos
StaticHeadersWriter
:@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http // your security config here .authorizeRequests() .antMatchers(HttpMethod.TRACE, "/**").denyAll() .antMatchers("/admin/**").authenticated() .anyRequest().permitAll() .and().httpBasic() .and().headers().frameOptions().disable() .and().csrf().disable() .headers() // the headers you want here. This solved all my CORS problems! .addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-Origin", "*")) .addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-Methods", "POST, GET")) .addHeaderWriter(new StaticHeadersWriter("Access-Control-Max-Age", "3600")) .addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-Credentials", "true")) .addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-Headers", "Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization")); } }
Ini adalah cara paling langsung dan eksplisit yang saya temukan untuk melakukannya. Semoga bisa membantu seseorang.
sumber
Inilah yang berhasil bagi saya.
@EnableWebSecurity public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.cors(); } } @Configuration public class WebConfiguration implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry .addMapping("/**") .allowedMethods("*") .allowedHeaders("*") .allowedOrigins("*") .allowCredentials(true); } }
sumber
Langkah 1
Dengan memberi anotasi, pengontrol dengan
@CrossOrigin
anotasi akan memungkinkan konfigurasi CORS.@CrossOrigin @RestController public class SampleController { ..... }
Langkah 2
Spring sudah memiliki CorsFilter meskipun Anda bisa mendaftarkan CorsFilter Anda sendiri sebagai kacang untuk menyediakan konfigurasi Anda sendiri sebagai berikut.
@Bean public CorsFilter corsFilter() { final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); final CorsConfiguration config = new CorsConfiguration(); config.setAllowedOrigins(Collections.singletonList("http://localhost:3000")); // Provide list of origins if you want multiple origins config.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept")); config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH")); config.setAllowCredentials(true); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); }
sumber
Periksa ini:
@Override protected void configure(HttpSecurity httpSecurity) throws Exception { ... .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() ... }
sumber
Memperluas kelas WebSecurityConfigurerAdapter dan mengganti metode configure () di kelas @EnableWebSecurity Anda akan berfungsi: Di bawah ini adalah kelas contoh
@Override protected void configure(final HttpSecurity http) throws Exception { http .csrf().disable() .exceptionHandling(); http.headers().cacheControl(); @Override public CorsConfiguration getCorsConfiguration(final HttpServletRequest request) { return new CorsConfiguration().applyPermitDefaultValues(); } }); } }
sumber
Jika awalnya program Anda tidak menggunakan keamanan pegas dan tidak mampu membayar perubahan kode, membuat proxy balik sederhana dapat membantu. Dalam kasus saya, saya menggunakan Nginx dengan konfigurasi berikut:
http { server { listen 9090; location / { if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; # # Custom headers and headers various browsers *should* be OK with but aren't # add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; # # Tell client that this pre-flight info is valid for 20 days # add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain; charset=utf-8'; add_header 'Content-Length' 0; return 204; } if ($request_method = 'POST') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'; } if ($request_method = 'GET') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'; } proxy_pass http://localhost:8080; } } }
Program saya mendengarkan : 8080 .
REF: CORS di Nginx
sumber
Jawaban ini menyalin jawaban @abosancic tetapi menambahkan keamanan ekstra untuk menghindari eksploitasi CORS .
Tip 1: Jangan mencerminkan Origin yang masuk apa adanya tanpa memeriksa daftar host yang diizinkan untuk mengakses.
Kiat 2: Izinkan permintaan yang memiliki kredensial hanya untuk host yang masuk daftar putih.
import java.io.IOException; import java.util.ArrayList; import java.util.List; 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); private List<String> allowedOrigins; public SimpleCORSFilter() { log.info("SimpleCORSFilter init"); allowedOrigins = new ArrayList<>(); allowedOrigins.add("https://mysafeorigin.com"); allowedOrigins.add("https://itrustthissite.com"); } @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; String allowedOrigin = getOriginToAllow(request.getHeader("Origin")); if(allowedOrigin != null) { response.setHeader("Access-Control-Allow-Origin", allowedOrigin); 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() { } public String getOriginToAllow(String incomingOrigin) { if(allowedOrigins.contains(incomingOrigin.toLowerCase())) { return incomingOrigin; } else { return null; } } }
sumber
Di aplikasi Spring Boot kami, kami telah menyiapkan CorsConfigurationSource seperti ini.
Urutan penambahan
allowedOrigns
pertama dan kemudian pengaturanapplyPermitDefaultValues()
membiarkan Spring mengatur nilai default untuk header yang diizinkan, header yang diekspos, metode yang diizinkan, dll. Jadi kita tidak perlu menentukannya.public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(Arrays.asList("http://localhost:8084")); configuration.applyPermitDefaultValues(); UrlBasedCorsConfigurationSource configurationSource = new UrlBasedCorsConfigurationSource(); configurationSource.registerCorsConfiguration("/**", configuration); return configurationSource; }
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/api/**") .access("@authProvider.validateApiKey(request)") .anyRequest().authenticated() .and().cors() .and().csrf().disable() .httpBasic().authenticationEntryPoint(authenticationEntryPoint); http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); }
sumber
Buat saja satu kelas seperti, semuanya akan baik-baik saja dengan ini:
@Component @Order(Ordered.HIGHEST_PRECEDENCE) public class MyCorsConfig implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { final HttpServletResponse response = (HttpServletResponse) res; response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE"); response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, enctype"); response.setHeader("Access-Control-Max-Age", "3600"); if (HttpMethod.OPTIONS.name().equalsIgnoreCase(((HttpServletRequest) req).getMethod())) { response.setStatus(HttpServletResponse.SC_OK); } else { chain.doFilter(req, res); } } @Override public void destroy() { } @Override public void init(FilterConfig config) throws ServletException { } }
sumber
Inilah yang berhasil bagi saya untuk menonaktifkan CORS antara Spring boot dan React
@Configuration public class CorsConfig implements WebMvcConfigurer { /** * Overriding the CORS configuration to exposed required header for ussd to work * * @param registry CorsRegistry */ @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("*") .allowedHeaders("*") .allowCredentials(true) .maxAge(4800); } }
Saya harus mengubah konfigurasi Keamanan juga seperti di bawah ini:
@Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .cors().configurationSource(new CorsConfigurationSource() { @Override public CorsConfiguration getCorsConfiguration(HttpServletRequest request) { CorsConfiguration config = new CorsConfiguration(); config.setAllowedHeaders(Collections.singletonList("*")); config.setAllowedMethods(Collections.singletonList("*")); config.addAllowedOrigin("*"); config.setAllowCredentials(true); return config; } }).and() .antMatcher("/api/**") .authorizeRequests() .anyRequest().authenticated() .and().httpBasic() .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and().exceptionHandling().accessDeniedHandler(apiAccessDeniedHandler()); }
sumber