Spring security returns String as principal instead of UserDetails on controller












1















The question is: I have an Auth server(spring security) and a Resource server,The Resource server can't get principal user correctly.



Spring Boot Version: 2.0.7
Spring Cloud Version: Finchley.SR2



Firstly, I go to get access token from Auth-server, and It is the success.
Then, I use the token to post the Resource-server, and the controller of Resource-server can get a principal.
However, the principal is a string, not a UserDetails Object.



Auth Server websecurity config like this:



@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MaliUserDetailsService maliUserDetailsService;

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.csrf().disable();
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(maliUserDetailsService).passwordEncoder(passwordEncoder());
}

@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}


Auth Server UserDetailsService:



@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username);
}
return user;
}


Resouce Server Controller:



@GetMapping("/test")
public String test(Authentication authentication) {
UserDetails userDetails = (UserDetails) authentication.getPrincipal();

return "hello " + userDetails.getUsername();
}


When I post to resource server, it cast a exception:



java.lang.ClassCastException: class java.lang.String cannot be cast to class org.springframework.security.core.userdetails.UserDetails (java.lang.String is in module java.base of loader 'bootstrap'; org.springframework.security.core.userdetails.UserDetails is in unnamed module of loader 'app')


enter image description here



===============
Then I tried to change to controller code like this:



@GetMapping("/test")
public String test(Authentication authentication) {
return "hello " + authentication.getPrincipal().toString();
}


The result is "hello admin". (admin is my username)
enter image description here



Why the principal in the controller is a string instead of UserDetails Object? How to solve it.










share|improve this question

























  • Comments are not for extended discussion; this conversation has been moved to chat.

    – Samuel Liew
    Jan 2 at 13:29











  • I was having a similar issue and the chat thread pointed out my problem, which was fairly obvious in the end. I had a custom filter that did authentication using auth tokens. When setting the principal property of UsernamePasswordAuthenticationToken I was using the username instead of a UserDetails object.

    – Doughnuts
    Feb 18 at 0:34
















1















The question is: I have an Auth server(spring security) and a Resource server,The Resource server can't get principal user correctly.



Spring Boot Version: 2.0.7
Spring Cloud Version: Finchley.SR2



Firstly, I go to get access token from Auth-server, and It is the success.
Then, I use the token to post the Resource-server, and the controller of Resource-server can get a principal.
However, the principal is a string, not a UserDetails Object.



Auth Server websecurity config like this:



@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MaliUserDetailsService maliUserDetailsService;

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.csrf().disable();
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(maliUserDetailsService).passwordEncoder(passwordEncoder());
}

@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}


Auth Server UserDetailsService:



@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username);
}
return user;
}


Resouce Server Controller:



@GetMapping("/test")
public String test(Authentication authentication) {
UserDetails userDetails = (UserDetails) authentication.getPrincipal();

return "hello " + userDetails.getUsername();
}


When I post to resource server, it cast a exception:



java.lang.ClassCastException: class java.lang.String cannot be cast to class org.springframework.security.core.userdetails.UserDetails (java.lang.String is in module java.base of loader 'bootstrap'; org.springframework.security.core.userdetails.UserDetails is in unnamed module of loader 'app')


enter image description here



===============
Then I tried to change to controller code like this:



@GetMapping("/test")
public String test(Authentication authentication) {
return "hello " + authentication.getPrincipal().toString();
}


The result is "hello admin". (admin is my username)
enter image description here



Why the principal in the controller is a string instead of UserDetails Object? How to solve it.










share|improve this question

























  • Comments are not for extended discussion; this conversation has been moved to chat.

    – Samuel Liew
    Jan 2 at 13:29











  • I was having a similar issue and the chat thread pointed out my problem, which was fairly obvious in the end. I had a custom filter that did authentication using auth tokens. When setting the principal property of UsernamePasswordAuthenticationToken I was using the username instead of a UserDetails object.

    – Doughnuts
    Feb 18 at 0:34














1












1








1








The question is: I have an Auth server(spring security) and a Resource server,The Resource server can't get principal user correctly.



Spring Boot Version: 2.0.7
Spring Cloud Version: Finchley.SR2



Firstly, I go to get access token from Auth-server, and It is the success.
Then, I use the token to post the Resource-server, and the controller of Resource-server can get a principal.
However, the principal is a string, not a UserDetails Object.



Auth Server websecurity config like this:



@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MaliUserDetailsService maliUserDetailsService;

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.csrf().disable();
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(maliUserDetailsService).passwordEncoder(passwordEncoder());
}

@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}


Auth Server UserDetailsService:



@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username);
}
return user;
}


Resouce Server Controller:



@GetMapping("/test")
public String test(Authentication authentication) {
UserDetails userDetails = (UserDetails) authentication.getPrincipal();

return "hello " + userDetails.getUsername();
}


When I post to resource server, it cast a exception:



java.lang.ClassCastException: class java.lang.String cannot be cast to class org.springframework.security.core.userdetails.UserDetails (java.lang.String is in module java.base of loader 'bootstrap'; org.springframework.security.core.userdetails.UserDetails is in unnamed module of loader 'app')


enter image description here



===============
Then I tried to change to controller code like this:



@GetMapping("/test")
public String test(Authentication authentication) {
return "hello " + authentication.getPrincipal().toString();
}


The result is "hello admin". (admin is my username)
enter image description here



Why the principal in the controller is a string instead of UserDetails Object? How to solve it.










share|improve this question
















The question is: I have an Auth server(spring security) and a Resource server,The Resource server can't get principal user correctly.



Spring Boot Version: 2.0.7
Spring Cloud Version: Finchley.SR2



Firstly, I go to get access token from Auth-server, and It is the success.
Then, I use the token to post the Resource-server, and the controller of Resource-server can get a principal.
However, the principal is a string, not a UserDetails Object.



Auth Server websecurity config like this:



@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MaliUserDetailsService maliUserDetailsService;

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.csrf().disable();
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(maliUserDetailsService).passwordEncoder(passwordEncoder());
}

@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}


Auth Server UserDetailsService:



@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username);
}
return user;
}


Resouce Server Controller:



@GetMapping("/test")
public String test(Authentication authentication) {
UserDetails userDetails = (UserDetails) authentication.getPrincipal();

return "hello " + userDetails.getUsername();
}


When I post to resource server, it cast a exception:



java.lang.ClassCastException: class java.lang.String cannot be cast to class org.springframework.security.core.userdetails.UserDetails (java.lang.String is in module java.base of loader 'bootstrap'; org.springframework.security.core.userdetails.UserDetails is in unnamed module of loader 'app')


enter image description here



===============
Then I tried to change to controller code like this:



@GetMapping("/test")
public String test(Authentication authentication) {
return "hello " + authentication.getPrincipal().toString();
}


The result is "hello admin". (admin is my username)
enter image description here



Why the principal in the controller is a string instead of UserDetails Object? How to solve it.







java spring-security






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 2 at 10:40







Defit

















asked Jan 2 at 10:07









DefitDefit

277




277













  • Comments are not for extended discussion; this conversation has been moved to chat.

    – Samuel Liew
    Jan 2 at 13:29











  • I was having a similar issue and the chat thread pointed out my problem, which was fairly obvious in the end. I had a custom filter that did authentication using auth tokens. When setting the principal property of UsernamePasswordAuthenticationToken I was using the username instead of a UserDetails object.

    – Doughnuts
    Feb 18 at 0:34



















  • Comments are not for extended discussion; this conversation has been moved to chat.

    – Samuel Liew
    Jan 2 at 13:29











  • I was having a similar issue and the chat thread pointed out my problem, which was fairly obvious in the end. I had a custom filter that did authentication using auth tokens. When setting the principal property of UsernamePasswordAuthenticationToken I was using the username instead of a UserDetails object.

    – Doughnuts
    Feb 18 at 0:34

















Comments are not for extended discussion; this conversation has been moved to chat.

– Samuel Liew
Jan 2 at 13:29





Comments are not for extended discussion; this conversation has been moved to chat.

– Samuel Liew
Jan 2 at 13:29













I was having a similar issue and the chat thread pointed out my problem, which was fairly obvious in the end. I had a custom filter that did authentication using auth tokens. When setting the principal property of UsernamePasswordAuthenticationToken I was using the username instead of a UserDetails object.

– Doughnuts
Feb 18 at 0:34





I was having a similar issue and the chat thread pointed out my problem, which was fairly obvious in the end. I had a custom filter that did authentication using auth tokens. When setting the principal property of UsernamePasswordAuthenticationToken I was using the username instead of a UserDetails object.

– Doughnuts
Feb 18 at 0:34












0






active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54004397%2fspring-security-returns-string-as-principal-instead-of-userdetails-on-controller%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54004397%2fspring-security-returns-string-as-principal-instead-of-userdetails-on-controller%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

MongoDB - Not Authorized To Execute Command

How to fix TextFormField cause rebuild widget in Flutter

Npm cannot find a required file even through it is in the searched directory