I'm trying it set up a proof of concept using Spring Boot and OAuth2. I've set up some project very similar to the ones outlined here:
https://spring.io/guides/tutorials/spring-boot-oauth2/
and here: https://spring.io/guides/tutorials/spring-security-and-angular-js/
The main difference with mine is I've left out all the AngularJS stuff.
I have the following services:
Authorization server
Resource server (as protected OAuth2 client)
UI server (as protected OAuth2 client)
All that I want to happen is this:
Hit the UI server
Get redirected to auth server and get prompted for credentials
UI server will then fetch some text from resource server and display them
I can get this all to work fine with Basic authentication on the auth server. However I want to be able to replace the basic authentication with that from Active Directory.
I have a couple of other Spring Boot projects that can do the AD authentication and it works, however whenever I try and drop it into this things go wrong. I think it's to do with the security around the auth server endpoints, but I'm not sure what.
Also, it's not clear to me which endpoints should be secured by what protocol (OAuth2 v. Basic) in a production environment? The docs recommend some endpoints should be secured with Basic. Should all 'OAuth2 clients' somehow include these credentials in their requests?
Here's my auth server application (with bits for Active Directory added):
#EnableResourceServer
#EnableAuthorizationServer
#SpringBootApplication
#RestController
public class AuthServerLdapApplication {
public static void main(String[] args) {
SpringApplication.run(AuthServerLdapApplication.class, args);
}
#RequestMapping("/user")
public Principal user(Principal user) {
return user;
}
#Order(ManagementServerProperties.ACCESS_OVERRIDE_ORDER)
#Configuration
protected static class ActiveDirectoryConfig extends WebSecurityConfigurerAdapter {
#Value("${activedirectory.url}")
private String activeDirectoryUrl;
#Value("${activedirectory.domain}")
private String getActiveDirectoryDomain;
#Autowired private AuthenticationManager authenticationManager;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(getActiveDirectoryDomain,
activeDirectoryUrl);
provider.setConvertSubErrorCodesToExceptions(true);
provider.setUseAuthenticationRequestCredentials(true);
auth.authenticationProvider(provider);
auth.parentAuthenticationManager(authenticationManager);
}
}
}
Basically what then happens is that I get this when I hit the UI server:
<oauth>
<error_description>
Full authentication is required to access this resource
</error_description>
<error>unauthorized</error>
</oauth>
If I do this against the authorization server:
curl -v http://localhost:9004/uaa/login
* Trying ::1...
* Connected to localhost (::1) port 9004 (#0)
> GET /uaa/login HTTP/1.1
> Host: localhost:9004
> User-Agent: curl/7.44.0
> Accept: */*
>
< HTTP/1.1 401 Unauthorized
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Cache-Control: no-store
< Pragma: no-cache
< WWW-Authenticate: Bearer realm="null", error="unauthorized", error_description="Full authentication is required to access this resource"
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Tue, 01 Dec 2015 12:38:53 GMT
<
{"error":"unauthorized","error_description":"Full authentication is required to access this resource"}* Connection #0 to host localhost left intact
It looks like the login endpoint now expects a bearer token? I'm not sure how to proceed now...
Any help/advice would be appreciated...
You #EnableResourceServer but you haven't provided any rules for the resources you want to protect so it's trying to protect everything. You need to add a #Bean of type ResourceServerConfigurerAdapter and set the request matchers (as well as whatever other rules you want).
Related
Using Spring Boot 2.7 (Spring Security 5.7.1) and trying to configure an API as a resource server and OAuth2 client I find a behavior I don't get to understand:
#EnableWebSecurity
public class SecurityConfig {
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.mvcMatchers("/swagger-ui/**", "/api-docs/**").permitAll()
.anyRequest().permitAll())
// register OAuth2 resource server
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
// register OAuth2 client
.oauth2Client(withDefaults());
return http.build();
}
}
Checking the logs, all this filters apply
o.s.s.web.DefaultSecurityFilterChain : Will secure any request with
org.springframework.security.web.session.DisableEncodeUrlFilter#320ca97c,
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter#3c592c0c,
org.springframework.security.web.context.SecurityContextPersistenceFilter#2b33e616,
org.springframework.security.web.header.HeaderWriterFilter#2e9bff08,
org.springframework.security.web.csrf.CsrfFilter#7926d092,
org.springframework.security.web.authentication.logout.LogoutFilter#37227aa7,
org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter#6f18445b,
org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter#42af2977,
org.springframework.security.web.savedrequest.RequestCacheAwareFilter#79e3f444, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter#1252d480,
org.springframework.security.web.authentication.AnonymousAuthenticationFilter#3979c6e8,
org.springframework.security.oauth2.client.web.OAuth2AuthorizationCodeGrantFilter#19faa9dc,
org.springframework.security.web.session.SessionManagementFilter#7d3b4646,
org.springframework.security.web.access.ExceptionTranslationFilter#6cb2d5ea,
So far, this configuration works as expected in the other APIs I'm protecting. However, in this particular one, AND not having protected any endpoint I see that:
I can access any GET endpoint but any POST endpoint returns a 403 FORBIDDEN. However, I can access them if I add a token to the request EVEN if its an expired token
This alone I can't understand as .anyRequest().permitAll() should unprotect anything, if I'm not wrong.
If I comment out the line configuring the oauth2 ResourceServer
`// .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)`
this filter dissapears
org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter
And can't use POST endpoints anymore, even with the expired token
Logically, I want the API to be oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt) so
How it is I can't access POST endpoints when using .anyRequest().permitAll())?
DISCLAIMER: I know it makes no sense to declare the API as resource server if all endpoints must be public. Endpoints will be accessed by Discord callbacks and I have to figure out if I can protect them with OAuth
EDIT:
server.servlet.context-path = /api
Controller
#RestController
#RequestMapping("/slack")
public class SlackBotController {
#PostMapping("/test")
public String test(#RequestBody String a) {
return a;
}
#GetMapping("/test")
public String testGet() {
return "OK";
}
}
Request
GET/POST http://localhost:8081/api/slack/test
Request headers
User-Agent: PostmanRuntime/7.29.0
Accept: */*
Postman-Token: f20ba7a6-26e5-47c4-a827-0596afec27b8
Host: localhost:8081
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 3
Cookie: JSESSIONID=D1C2B2668DC130C63DDE03F30574ED5F; JSESSIONID=823D79956CFBF14F3C77C96E29F4131C
Response headers
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json
Transfer-Encoding: chunked
Date: Fri, 03 Jun 2022 12:03:00 GMT
Keep-Alive: timeout=60
Connection: keep-alive
The reason why the POST endpoint or the POST returns a 403 FORBIDDEN because the CSRF protection is enabled by default in spring.
That means that every modifying request (POST, PUT, DELETE, PATCH) requires a CSRF token. Otherwise the request gets denied to prevent CSRF attacks.
To disable the CSRF protection:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable();
}
The problem here is the CSRF protection. When you use http.oauth2ResourceServer() Spring Security configures CSRF to ignore requests that contains the header Authorization: Bearer whatever, note that it has to contain the Bearer prefix.
In the request sample that you shared, you are not including the Authorization header.
Take a look at the code in Spring Security.
I've been struggling with this one for a while and can't figure out what I'm doing wrong.
I'm supposed to add basic authentication to my SOAP web service in Spring. I made the security config pretty simple (maybe too simple) so it concentrates on basic auth only (see below).
When I'm accessing the base URL from the browser, the authentication seems to be working, it asks for the credentials and if I provide them correctly, it accepts them.
However, when I want to send the SOAP request that contains the basic auth header to my web service endpoint, Spring Security sends back 401 to me. I tried sending the request with SOAPUI, Postman and from Windows Powershell via Invoke-WebRequest, and the result is the same whereas if I catch the request with Wireshark, the right header is there.
I'm using Spring Boot 2.1.8 for this project (same version with Spring Web Services and Security).
The security config class:
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("foo")
.password(passwordEncoder().encode("bar"))
.roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and().httpBasic();
}
#Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
To my understanding, there is nothing specific I have to add to the web service config itself so all related basic auth settings can be done in the security config class. Or am I wrong?
Appreciate your help.
Update
Here is the request/response pair:
REQUEST:
POST /foo/endpoint/ HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "http://foo.bar"
Authorization: Basic Zm9vOmJhcg==
Content-Length: 9688
Host: localhost:1502
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:foo="http://foobar.com/">
<soapenv:Header/>
<soapenv:Body>
// body omitted
</soapenv:Body>
</soapenv:Envelope>
RESPONSE
HTTP/1.1 401
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
WWW-Authenticate: Basic realm="Realm"
Content-Length: 0
Date: Thu, 13 Aug 2020 14:22:29 GMT
configure(HttpSecurity http) needs some modifications to enable the http basic authentication in your code.
authorizeRequests() is used for authorization purposes. Once after a user successfully logged in, what all the resources(endpoints) should be accessible to logged-in user, is defined by authorizeRequests(). I also recommend, while authorizing the endpoints, you better use the antMatchers. For Example: I have modified the above code as
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("foo")
.password(passwordEncoder().encode("bar"))
.roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().and()
.authorizeRequests()
.antMatchers("/simple/**").hasRole("USER");
}
#Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
I hope this would work for you. Try & let me know.
NOTE: In Spring boot, just by adding the spring-boot-starter-security dependency, security gets enabled, without any configurations. So now, you trying to re-configure the basic auto-configuration. By extending, WebSecurityConfigurerAdapter class. That's correct.
POSTMAN: use authorization header
I have the class below which uses antMatchers to remove authentication from a public endpoint.
However the public endpoint is also being blocked and I keep getting a HTTP/1.1 401.
Can anyone please help me to spot what's wrong below?
#Configuration
#EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
#Autowired
private UsersService usersService;
#Autowired
private UsersRepository usersRepo;
#Bean
public BCryptPasswordEncoder bCryptPasswordEncoder()
{
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable();
http.authorizeRequests().antMatchers(HttpMethod.POST, "/public").permitAll()
.anyRequest().authenticated()
.and().addFilter(getAuthenticationFilter());
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(usersService).passwordEncoder(bCryptPasswordEncoder());
}
private AuthenticationFilter getAuthenticationFilter() throws Exception {
final AuthenticationFilter filter = new AuthenticationFilter(authenticationManager(),
usersService);
return filter;
}
}
---------------update 1-------------------
I tried with http POST, using curl and I get back the below.
It seems like the request is caught somewhere but not in the controller I am trying to hit:
$ curl -X POST http://localhost:8083/public -H 'Content-Type:
application/json' -H 'cache-control: no-cache' -d '{
"email":"test2#test.com", "password":"12345678" }' -v
* Trying ::1:8083...
* Connected to localhost (::1) port 8083 (#0)
> POST /user HTTP/1.1
> Host: localhost:8083
> User-Agent: curl/7.69.1
> Accept: */*
> Content-Type: application/json
> cache-control: no-cache
> Content-Length: 51
>
* upload completely sent off: 51 out of 51 bytes
* Mark bundle as not supporting multiuse
< HTTP/1.1 401
< Set-Cookie: JSESSIONID=72AB25425322A17AE7014832D25284FD; Path=/;
HttpOnly
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< WWW-Authenticate: Basic realm="Realm"
< Content-Length: 0
< Date: Tue, 31 Mar 2020 11:36:10 GMT
<
* Connection #0 to host localhost left intact
You might want to override the WebSecurity method to completely ignore your /public path from Spring Security processing.
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/public/**");
}
It is difficult to know without seeing all of your code, but I suspect that this has nothing to do with the authorizeRequests() portion of your configuration. Instead, I suspect it is the AuthenticationFilter which is attempting to authenticate the request because you have included credentials in the request. The default is to try to authenticate anytime the AuthenticationConverter returns credentials. Then AuthenticationFailureHandler will respond with HTTP 401 if invalid credentials are provided.
To resolve this, you can remove the credentials from your request. Alternatively, you can limit which requests AuthenticationFilter are invoked on by setting the requestMatcher. Something like this would limit to processing POST to /authenticate:
private AuthenticationFilter getAuthenticationFilter() throws Exception {
final AuthenticationFilter filter = new AuthenticationFilter(authenticationManager(),
usersService);
filter.setRequestMatcher(new AntPathRequestMatcher("/authenticate", "POST"));
return filter;
}
While debugging a CORS issue I am experiencing I've found the following behaviour. Chrome makes the following OPTIONS preflight request (rewritten in CURL by Chrome itself):
curl -v 'https://www.example.com/api/v1/users' -X OPTIONS -H 'Access-Control-Request-Method: POST' -H 'Origin: http://example.com' -H 'Accept-Encoding: gzip,deflate,sdch' -H 'Accept-Language: es-ES,es;q=0.8,en;q=0.6' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36' -H 'Accept: */*' -H 'Referer: http://example.com/users/new' -H 'Connection: keep-alive' -H 'Access-Control-Request-Headers: accept, x-api-key, content-type'
The response from the server to this request if the following:
< HTTP/1.1 403 Forbidden
< Date: Thu, 21 Jul 2016 14:16:56 GMT
* Server Apache/2.4.7 (Ubuntu) is not blacklisted
< Server: Apache/2.4.7 (Ubuntu)
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< Strict-Transport-Security: max-age=31536000 ; includeSubDomains
< X-Frame-Options: SAMEORIGIN
< Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
< Content-Length: 20
< Keep-Alive: timeout=5, max=100
< Connection: Keep-Alive
being the body of the response 'Invalid CORS request'. If I repeat the request removing the header 'Access-Control-Request-Method' (and only that header) the OPTIONS requests succeeds with the following reponse:
< HTTP/1.1 200 OK
< Date: Thu, 21 Jul 2016 14:21:27 GMT
* Server Apache/2.4.7 (Ubuntu) is not blacklisted
< Server: Apache/2.4.7 (Ubuntu)
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< Strict-Transport-Security: max-age=31536000 ; includeSubDomains
< X-Frame-Options: SAMEORIGIN
< Access-Control-Allow-Headers: origin, content-type, accept, x-requested-with, x-api-key
< Access-Control-Max-Age: 60
< Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
< Access-Control-Allow-Origin: *
< Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
< Content-Length: 0
< Keep-Alive: timeout=5, max=100
< Connection: Keep-Alive
However, the offending header is a CORS spec standard header so it should not prevent the request from succeeding, right? Why is this header causing such behaviour?
And how can I tweak the access control headers sent by my server to make the request work when made with Chrome?
By the way, I am using Chrome 36.0, and the server is using Spring Boot, with the CORS headers being managed by Spring.
When the request is made by Firefox (v47.0) the behaviour is different but with an analogue result. Firefox does not even send the preflight request, it directly sends the POST request, which receives as response a 403 Forbidden. However, if I copy the request with the 'Copy as cURL' option, and repeat it from a terminal window, It succeeds and sends the correct CORS headers in the response.
Any idea?
Update: Firefox does send the preflight OPTIONS request (as shown by the Live HTTP headers plugin), but Firebug masks it, so the behaviour in both browsers it exactly the same. In both browsers is the 'Access-control-request-method' header the difference that makes the request fail.
After a lot of struggling, I finally found the problem. I configured a request mapping in Spring to handle OPTIONS traffic, like this:
#RequestMapping(value= "/api/**", method=RequestMethod.OPTIONS)
public void corsHeaders(HttpServletResponse response) {
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.addHeader("Access-Control-Allow-Headers", "origin, content-type, accept, x-requested-with");
response.addHeader("Access-Control-Max-Age", "3600");
}
I did not know that by default Spring uses a default CORS processor, and it seems it was interfering with my request mapping. Deleting my request mapping and adding the #CrossOrigin annotation to the appropriate request mappings solved the problem.
i also faced the same issue and find solution for enabling global cors issue in spring boot
#Configuration
#EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE").allowedOrigins("*")
.allowedHeaders("*");
}
}
after this , we need to enable CORS in spring security level also, so for this
add cors() in your SecurityConfiguration class which extent WebSecurityConfigurerAdapter
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.cors()
.and()
.csrf().disable()
.authorizeRequests()..
}
I had the same issue. I've resolve it by adding 'OPTIONS' to allowed CORS methods in my Spring MVC configuration.
#Configuration
#EnableWebMvc
#ComponentScan
public class RestApiServletConfig extends WebMvcConfigurerAdapter {
#Override
public void addCorsMappings(CorsRegistry registry) {
super.addCorsMappings(registry);
registry.addMapping("/**")
.allowedOrigins("http://localhost:3000", "http://localhost:8080")
.allowedMethods("GET", "PUT", "POST", "DELETE", "OPTIONS");
}
}
For me I have added #crossorigin annotation in each of controller api call.
#CrossOrigin
#PostMapping(path = "/getListOfIndividuals", produces = { "application/json" }, consumes = { "application/json" })
public ResponseEntity<String> test(#RequestBody String viewIndividualModel)
throws Exception {
String individualDetails = globalService.getIndividualDetails(viewIndividualModel);
finalString = discSpecAssmentService.getViewFormForDisciplineEvaluation( viewIndividualModel);
return new ResponseEntity<String>(finalString, HttpStatus.OK);
}
Edit: Enable CORS in security configuration and make sure options requests bypass security
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.cors()
.and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
// More security configuration here
}
I added this as an answer because I couldn't format it well for the top voted answer.
I found this post helpful as well: How to handle HTTP OPTIONS with Spring MVC?
DispatchServlet must be configured to pass along options request, or else it never reaches the mapped request:
...
<servlet>
<servlet-name>yourServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>dispatchOptionsRequest</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
...
I came across this really while testing the CORS on our endpoints using test-cors.org website and it exhibits the exact same behavior that is described above.
The approach that I did was to use the Global CORS filter instead of using the #CrossOrigin annotation.
#Configuration
class CorsConfig : WebMvcConfigurer {
override fun addCorsMappings(registry: CorsRegistry) {
registry.addMapping("/**")
.allowCredentials(true)
.allowedHeaders("*")
.allowedMethods("*")
.allowedOrigins("*")
.maxAge(3600)
}
}
Note that you should not use #EnableWebMvc unless you want to take control Spring Boot Auto-configuration as noted here...which will probably cause some "issues" as noted here and here
This next custom configuration is also needed (solution partially lifted from here) or else you will get that particular CORS pre-flight issue:
#Configuration
class CustomWebSecurityConfigurerAdapter : WebSecurityConfigurerAdapter() {
override fun configure(http: HttpSecurity) {
http.cors().and().csrf().disable()
}
}
I want to disable the Trace verb on the serve so that endpoints are untraceable.
My endpoints are created using Spring MVC and there is a option endpoints.trace.enabled=false.
Pain is how to test this, if trace is disabled or not. I tried chrome plug-ins live HTTP Headers but it for generic site. I want to check my endpoint.
For example:
curl --insecure -v -X TRACE -H http://localhost:8080/toy/49f6a7d3-eb20-3ab2-be3b-8399e7f28abf
HTTP/1.1 200 OK
< Date: Sat, 21 Mar 2015 04:34:03 GMT
< Content-Type: message/http; charset=UTF-8
< Content-Length: 270
<
TRACE /toy/49f6a7d3-eb20-3ab2-be3b-8399e7f28abf HTTP/1.1
User-Agent: curl/7.37.1
Host: localhost:8080
Accept: */*
* Connection #0 to host localhost left intact
I tried below but now it denies all the request.
#Configuration
#EnableWebMvcSecurity
#EnableGlobalMethodSecurity(securedEnabled=true, prePostEnabled = true, jsr250Enabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatchers()
.and()
.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.TRACE, "/**").denyAll();
}
}
AFAIK TRACE is disabled by default on Tomcat, as well as Jetty 6,
You can use curl to make sure:
curl -v -X TRACE http://www.example.com
You want to see 405 method not allowed in the response.