2017-03-22 4 views
0

Ich verstehe, dass Spring den Principal in Controller-Methode übergeben wird, wenn ich es als Methodenparameter einschließen.Spring Security - Implementierung von UserDetailsService

Ich versuche, diese Funktionalität zu erweitern, indem UserDetailsService Umsetzung:

habe ich eine Klasse CustomUserDetails genannt, die org.springframework.security.core.userdetails.User erstreckt

ich einen Dienst erstellt CustomUserDetailsService benannt

UserDetailsService

Exception implementiert

HTTP-Status 500 - Anforderungsverarbeitung fehlgeschlagen; verschachtelte Ausnahme ist java.lang.ClassCastException: org.springframework.security.authentication.UsernamePasswordAuthenticationToken nicht

Die folgende Zeile in meiner Controller-Methode wirft die Ausnahme com.demo.model.CustomUserDetails gegossen werden:

CustomUserDetails userDetails = (CustomUserDetails) principal; 

Controller.java

@RequestMapping(value = "/dashboard", method = RequestMethod.GET) 
    public ModelAndView displayHomePage(ModelAndView modelAndView, Principal principal, HttpServletRequest request) { 

     // Throws exception here 
     CustomUserDetails userDetails = (CustomUserDetails) principal;  

     System.out.println(userDetails.getFirstName()); 

     // Tried this and it also throws exception 
     // User cannot be cast to CustomUserDetails 
     //Authentication auth = SecurityContextHolder.getContext().getAuthentication(); 
     //CustomUserDetails userDetails = (CustomUserDetails)auth.getPrincipal(); 

     // Render template located at 
     // src/main/resources/templates/dashboard.html 
     modelAndView.setViewName("dashboard"); 

     return modelAndView; 
    } 

SecurityConfiguration.java

@Configuration 
@EnableWebSecurity 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private BCryptPasswordEncoder bCryptPasswordEncoder; 

    @Autowired 
    private DataSource dataSource; 

    @Value("${spring.queries.users-query}") 
    private String usersQuery; 

    @Value("${spring.queries.roles-query}") 
    private String rolesQuery; 

    @Autowired 
    SecurityHandler successHandler; 

    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth.jdbcAuthentication().usersByUsernameQuery(usersQuery).authoritiesByUsernameQuery(rolesQuery) 
       .dataSource(dataSource).passwordEncoder(bCryptPasswordEncoder); 
    } 


    @Override 
    protected void configure(HttpSecurity http) throws Exception { 

     http.authorizeRequests().antMatchers("/").permitAll().antMatchers("/register*").permitAll() 
       .antMatchers("/reset").permitAll().antMatchers("/forgot").permitAll().antMatchers("/grid").permitAll() 
       .antMatchers("/login").permitAll().antMatchers("/admin/**").hasAuthority("ADMIN").anyRequest() 
       .authenticated().and().formLogin().loginPage("/login").failureUrl("/login?error") 
       .defaultSuccessUrl("/dashboard").successHandler(successHandler).usernameParameter("email") 
       .passwordParameter("password").and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")) 
       .logoutSuccessUrl("/login?logout").and().exceptionHandling().accessDeniedPage("/access-denied"); 

    } 

    @Override 
    public void configure(WebSecurity web) throws Exception { 
     web.ignoring().antMatchers("/error**", "/resources/**", "/static/**", "/css/**", "/js/**", "/img/**"); 
    } 

} 

CustomUserDetails.java

public class CustomUserDetails extends org.springframework.security.core.userdetails.User { 

    public CustomUserDetails(String username, String password, 
     Collection<? extends GrantedAuthority> authorities) {    
     super(username, password, authorities); 
    } 

    private String firstName; 
    private String lastName; 


    public String getFirstName() { 
     return firstName; 
    } 

    public void setFirstName(String firstName) { 
     this.firstName = firstName; 
    } 

    public String getLastName() { 
     return lastName; 
    } 

    public void setLastName(String lastName) { 
     this.lastName = lastName; 
    } 

} 

CustomUserDetailsService.java

@Service 
public class CustomUserDetailsService implements UserDetailsService{ 

    @Override 
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException{   

     if(StringUtils.isEmpty(userName)) 
      throw new UsernameNotFoundException("User name is empty"); 

     //if you don't use authority based security, just add empty set 
     Set<GrantedAuthority> authorities = new HashSet<>(); 
     CustomUserDetails userDetails = new CustomUserDetails(userName, "", authorities);    

     userDetails.setFirstName("Testing: " + new Date()); 


     return userDetails; 
    } 

} 
+0

Die 'Principal' man bekommt, ist das' Authentication' Objekt und nicht Ihre Benutzer. Auf diesem können Sie 'getPrincipal' aufrufen, um den tatsächlichen Benutzer zu erhalten. (Dies ist auch, was die Klassenausnahme-Ausnahme Ihnen sagt). –

+0

können Sie den Code veröffentlichen, in dem die Ausnahme tatsächlich ausgelöst wird? – rptmat57

+0

@ rptmat57 sicher, ich habe die Controller-Methode Code –

Antwort

0

in WebSecurityConfigurerAdapter, müssen Sie Ihr Register benutzerdefinierte det hinzufügen ail Service:

auth.userDetailsService(customDetailService)

 @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth.jdbcAuthentication().usersByUsernameQuery(usersQuery).authoritiesByUsernameQuery(rolesQuery) 
       .dataSource(dataSource).passwordEncoder(bCryptPasswordEncoder); 
    } 
Verwandte Themen