2017-02-15 126 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-安全 –