2017-02-15 15 views
0

я, кажется, что-то здесь отсутствует фундаментальное:Spring Security: UserDetailsService работает только один раз

@SpringBootApplication 
public class Application { 
    User u = new User("USER", "PASSWORD",AuthorityUtils.createAuthorityList(
       "ROLE_USER", "ROLE_ADMINISTRATOR")); 
    @Bean 
    public UserDetailsService userDetailsService() { 
     // returning a new User object works fine for every request 
     return username -> new User("USER", "PASSWORD", 
      AuthorityUtils.createAuthorityList(
        "ROLE_USER", "ROLE_ADMINISTRATOR")); 
     // returning a previously created User object 
     // works only for the first request, 
     // subsequent requests get a 401 error 
     // return username -> u; 
    } 
    public static void main(String[] args) { 
     SpringApplication.run(Application.class, args); 
    } 
} 

Этой весной загрузки (v1.5.1) приложение, использующее spring-boot-starter-security зависимость знает только один пользователь, как сейчас. Кроме того, все его конечные точки должны быть доступны только для этого самого пользователя. Во всех рабочих примерах, которые я видел, UserDetailsService всегда возвращает новый объект типа User, как и в приведенном выше примере.

Но когда он возвращает ранее созданный объект (например, объект с именем u выше), проверяется только первый запрос. Зачем ?

+0

ли вы пытаетесь отлаживать? –

ответ

0

Хороший полный пример, с JPA, а также, можно найти here

Это просто пример. Пароль по-прежнему должен быть зашифрован/защищен.

Application.java

package demo; 

import java.util.Date; 
import java.util.List; 
import java.util.Map; 

import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 
import org.springframework.boot.autoconfigure.security.SecurityProperties; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.core.Ordered; 
import org.springframework.core.annotation.Order; 
import org.springframework.data.repository.CrudRepository; 
import org.springframework.security.access.annotation.Secured; 
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 
import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter; 
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.WebSecurityConfigurerAdapter; 
import org.springframework.security.core.GrantedAuthority; 
import org.springframework.security.core.authority.AuthorityUtils; 
import org.springframework.security.core.userdetails.UserDetails; 
import org.springframework.security.core.userdetails.UserDetailsService; 
import org.springframework.security.core.userdetails.UsernameNotFoundException; 
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; 
import org.springframework.stereotype.Controller; 
import org.springframework.stereotype.Repository; 
import org.springframework.stereotype.Service; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; 
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 

@Configuration 
@ComponentScan 
@EnableAutoConfiguration 
@EnableGlobalMethodSecurity(securedEnabled = true) 
public class Application extends WebMvcConfigurerAdapter { 

    @Controller 
    protected static class HomeController { 

     @RequestMapping("/") 
     @Secured("ROLE_ADMIN") 
     public String home(Map<String, Object> model) { 
      model.put("message", "Hello World"); 
      model.put("title", "Hello Home"); 
      model.put("date", new Date()); 
      return "home"; 
     } 

    } 

    public static void main(String[] args) { 
     SpringApplication.run(Application.class, args); 
    } 

    @Override 
    public void addViewControllers(ViewControllerRegistry registry) { 
     registry.addViewController("/login").setViewName("login"); 
     registry.addViewController("/access").setViewName("access"); 
    } 

    @Bean 
    public ApplicationSecurity applicationSecurity() { 
     return new ApplicationSecurity(); 
    } 

    @Order(Ordered.HIGHEST_PRECEDENCE) 
    @Configuration 
    protected static class AuthenticationSecurity extends 
      GlobalAuthenticationConfigurerAdapter { 

     @Autowired 
     private Users users; 

     @Override 
     public void init(AuthenticationManagerBuilder auth) throws Exception { 
      auth.userDetailsService(users); 
     } 
    } 

    @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) 
    protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter { 

     @Override 
     protected void configure(HttpSecurity http) throws Exception { 
      // @formatter:off 
      http.authorizeRequests().antMatchers("/login").permitAll().anyRequest() 
        .fullyAuthenticated().and().formLogin().loginPage("/login") 
        .failureUrl("/login?error").and().logout() 
        .logoutRequestMatcher(new AntPathRequestMatcher("/logout")).and() 
        .exceptionHandling().accessDeniedPage("/access?error"); 
      // @formatter:on 
     } 

    } 

} 

@Service 
class Users implements UserDetailsService { 

    private UserRepository repo; 

    @Autowired 
    public Users(UserRepository repo) { 
     this.repo = repo; 
    } 

    @Override 
    public UserDetails loadUserByUsername(String username) 
      throws UsernameNotFoundException { 
     User user = repo.findByName(username); 
     if (user == null) { 
      return null; 
     } 
     List<GrantedAuthority> auth = AuthorityUtils 
       .commaSeparatedStringToAuthorityList("ROLE_USER"); 
     if (username.equals("admin")) { 
      auth = AuthorityUtils 
        .commaSeparatedStringToAuthorityList("ROLE_ADMIN"); 
     } 
     String password = user.getPassword(); 
     return new org.springframework.security.core.userdetails.User(username, password, 
       auth); 
    } 

} 

@Repository 
interface UserRepository extends CrudRepository<User, Long> { 
    User findByName(String name); 
} 

@Entity 
class User { 
    @GeneratedValue 
    @Id 
    private Long id; 
    private String name; 
    private String password; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getPassword() { 
     return password; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 
} 
+0

Я вижу, что ваш пример работает, но он также создает новый объект User с 'return new org.springframework.security.core.userdetails.User (имя пользователя, пароль, auth);' поэтому мне все еще интересно узнать, почему мой пример который возвращает уже созданный объект, работает * только один раз * –

+0

Вы можете создать свою собственную реализацию для UserDetails http://stackoverflow.com/questions/26447739/how-to-create-custom-userdetail-object-in-spring- безопасность –