2017-02-15 127 views
0

我似乎失去了一些东西在这里根本:春季安全:UserDetailsS​​ervice的作品只有一次

@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

我看到你的例子工作,但它也创建一个新的用户对象与'返回新的org.springframework.security.core.userdetails.User(用户名,密码,身份验证);'所以我仍然好奇为什么我的例子返回一个已经创建的对象只能工作* –

+0

你可以为UserDetails创建你自己的实现http://stackoverflow.com/questions/26447739/how-to-create-custom-userdetail-object-in-spring-安全 –