问题
I'm using Spring security to secure some endpoints in my REST service.
here's the security configuration class:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true, prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// Other methods
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf()
.disable()
.exceptionHandling()
.authenticationEntryPoint(this.jwtAuthenticationEntryPoint)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/",
"/favicon.ico",
"/**/*.png",
"/**/*.gif",
"/**/*.svg",
"/**/*.jpg",
"/**/*.html",
"/**/*.css",
"/**/*.js")
.permitAll()
.antMatchers(HttpMethod.POST, "/api/auth/**")
.permitAll()
.anyRequest()
.authenticated();
// Add our custom JWT security filter
http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
As you can see i'm given the full access to /api/auth/signup and /api/auth/signin by using: .antMatchers(HttpMethod.POST, "/api/auth/**").permitAll()
for some reason when i tried those request in the postman, the "signup" request worked fine, but "signin" didn't works and gives me "401 Unauthorized"
i tried also .antMatchers("/**").permitAll()
here's my controller:
@RestController
public class UserController {
private UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@PostMapping("/api/auth/signup")
public ResponseEntity<RestResponse> registerUser(@Valid @RequestBody SignUpRequest signUpRequest,
UriComponentsBuilder uriComponentsBuilder) {
RestResponse restResponse = this.userService.register(signUpRequest);
UriComponents uriComponents = uriComponentsBuilder.path("/users").buildAndExpand();
return ResponseEntity.created(uriComponents.toUri()).body(restResponse);
}
@PostMapping("/api/auth/signin")
public ResponseEntity<JwtAuthenticationResponse> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
return ResponseEntity.ok(this.userService.login(loginRequest));
}
}
回答1:
I had the same issue, not sure, but I think you need this order:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/api/auth/**")
.permitAll()
.antMatchers("/",
"/favicon.ico",
"/**/*.png",
"/**/*.gif",
"/**/*.svg",
"/**/*.jpg",
"/**/*.html",
"/**/*.css",
"/**/*.js")
.permitAll()
.anyRequest()
.authenticated()
.and()
.cors()
.and()
.exceptionHandling()
.authenticationEntryPoint(this.jwtAuthenticationEntryPoint)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf()
.disable();
// Add our custom JWT security filter
http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
回答2:
Your configuration is not working due to order in which the antMatcher is evaluated
.and()
.authorizeRequests()
.antMatchers("/",
"/favicon.ico",
"/**/*.png",
"/**/*.gif",
"/**/*.svg",
"/**/*.jpg",
"/**/*.html",
"/**/*.css",
"/**/*.js")
.permitAll()
.antMatchers(HttpMethod.POST, "/api/auth/**")
.permitAll()
.anyRequest()
.authenticated();
The order of the request match rule matters and more specific rules should go first. There is some conflict between both antMatcher rules and therefore the second rule i.e .antMatchers(HttpMethod.POST, "/api/auth/")** is ignored.
Therefore the order should be following :-
.antMatchers(HttpMethod.POST, "/api/auth/**")
.permitAll()
.antMatchers("/",
"/favicon.ico",
"/**/*.png",
"/**/*.gif",
"/**/*.svg",
"/**/*.jpg",
"/**/*.html",
"/**/*.css",
"/**/*.js")
.permitAll()
回答3:
The last time i did it i remember the order is important.
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf()
.disable()
.exceptionHandling()
.authenticationEntryPoint(this.jwtAuthenticationEntryPoint)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/api/auth/**")
.permitAll()
.antMatchers("/",
"/favicon.ico",
"/**/*.png",
"/**/*.gif",
"/**/*.svg",
"/**/*.jpg",
"/**/*.html",
"/**/*.css",
"/**/*.js")
.permitAll()
.anyRequest()
.authenticated();
// Add our custom JWT security filter
http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
回答4:
You need to add the following to your configure method /error is the default fall back when error occurs to the application due to any exception and it is secured by default.
protected void configure(HttpSecurity httpSecurity) throws Exception {
//disable CRSF
httpSecurity
//no authentication needed for these context paths
.authorizeRequests()
.antMatchers("/error").permitAll()
.antMatchers("/error/**").permitAll()
.antMatchers("/your Urls that dosen't need security/**").permitAll()
Also the below code snippet
@Override
public void configure(WebSecurity webSecurity) throws Exception
{
webSecurity
.ignoring()
// All of Spring Security will ignore the requests
.antMatchers("/error/**")
}
Now you will not get 401 and get 500 exception with details when an exception occurred for permitAll Urls
来源:https://stackoverflow.com/questions/52904227/spring-security-401-unauthorized-even-with-permitall