When I try to get user name on backend
@CrossOrigin(origins = "*")
@RestController
@RequestMapping("/persons")
public class PersonController {
...
@PostMapping
public ResponseEntity<PersonDto> addPerson(@RequestBody PersonDto objectDto, @AuthenticationPrincipal Principal principal){
System.out.println(principal.getName());
I got an error
2021-10-27 23:30:39.309 ERROR 10744 --- [nio-8081-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
I can see that frontent is sending JWT token (don't look at 'accessToken' I added it manually to header).
POST /persons HTTP/1.1
Host: localhost:8081
Connection: keep-alive
Content-Length: 217
sec-ch-ua: "Chromium";v="94", "Google Chrome";v="94", ";Not A Brand";v="99"
accessToken: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJHaWVuZWsiLCJpYXQiOjE2MzUzNjg1MjQsImV4cCI6MTYzNTQ1NDkyNH0.leuqnc-8fHNBVhTmukruom-RudxicWP3ykkMyMiapwY8bBVCFLwlNssXNK-gyo0RHig9d-dg83-QG9LDqVO9VA
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36
Content-Type: application/json
Accept: application/json, text/plain, */*
x-access-token: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJHaWVuZWsiLCJpYXQiOjE2MzUzNjg1MjQsImV4cCI6MTYzNTQ1NDkyNH0.leuqnc-8fHNBVhTmukruom-RudxicWP3ykkMyMiapwY8bBVCFLwlNssXNK-gyo0RHig9d-dg83-QG9LDqVO9VA
sec-ch-ua-platform: "Windows"
Origin: http://localhost:4200
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost:4200/
Accept-Encoding: gzip, deflate, br
Accept-Language: pl-PL,pl;q=0.9,en-US;q=0.8,en;q=0.7
What is the reason that backend does not see it?
Attaching Security Config - please let me know if you need more details
package pl.portal.randkowy.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.core.userdetails.UserDetailsService;
@Configuration
@EnableWebSecurity(debug=true)
@EnableGlobalMethodSecurity(
// securedEnabled = true,
// jsr250Enabled = true,
prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
UserDetailsService userDetailsService;
@Autowired
private AuthEntryPointJwt unauthorizedHandler;
@Bean
public AuthTokenFilter authenticationJwtTokenFilter() {
return new AuthTokenFilter();
}
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests().antMatchers("/api/auth/**").permitAll()
.antMatchers("/api/test/**").permitAll()
.antMatchers("/persons").permitAll()
.antMatchers("/persons/**").permitAll()
.antMatchers("/preferences/**").permitAll()
.antMatchers("/interests/**").permitAll()
.antMatchers("/secretdata/**").permitAll()
.anyRequest().authenticated();
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
When I am trying to check this way
@PostMapping
public ResponseEntity<PersonDto> addPerson(@RequestBody PersonDto objectDto, Principal principal){
//zalogowany użytkownik
Object principal2 = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
System.out.println("--------------------------------------*****************");
if (principal2 instanceof UserDetailsImpl) {
String username = ((UserDetailsImpl)principal2).getUsername();
System.out.println(username);
} else {
String username = principal2.toString();
System.out.println(username);
}
System.out.println("--------------------------------------*****************");
I got
--------------------------------------*****************
anonymousUser
--------------------------------------*****************
Why Spring Security does not read this token? It is sended to frontend after login procedure, so it should be fine. Spring should get in in header from this x-access-token option?
EDIT: I found out during debugging that jwt is null, but why - I can see that request has inside jwt token from frontend?
CodePudding user response:
Debug into your parseJwt(request)
to see how your application extracts the token from the request. The practice for the access token
is: it's usually in the Authorization
header and starts with Bearer
Request headers
Authorization: Bearer access-token
CodePudding user response:
try changing the webSecurityConfig like this
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests().antMatchers("/api/auth/**").permitAll()
.antMatchers("/api/test/**").permitAll()
.antMatchers("/persons/**").permitAll()
.antMatchers("/preferences/**").permitAll()
.antMatchers("/interests/**").permitAll()
.antMatchers("/secretdata/**").permitAll()
.anyRequest().authenticated();
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}