2017-05-16 2 views
-1

DaoAuthenticationProviderを使用して、スプリングセキュリティを使用して基本認証を行っています。私は私の要求を事前認証したいので、@PreAuthorize注釈を使用しています。問題は、Spring Securityが複数のロールと権限を区別しないように見えることです。たとえば、/usersにアクセスすると、ログイン画面にプロンプ​​トが表示されますが、どのユーザーにログインしても、表示されるすべてのユーザーのリストが表示されます。これは達成したいものではありません。私はユーザーリストへのアクセスをロール管理者に制限したいと思っています。ここでスプリングセキュリティはロールを区別しません

は私SecurityConfig次のとおりです。ここで

@Configuration 
@EnableGlobalMethodSecurity(securedEnabled = true) 
@RequiredArgsConstructor(onConstructor = @__({@Autowired})) 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Autowired 
    @Resource(name = "userRestClient") 
    UserService userService; 

    @Autowired 
    private AuthenticationProvider authenticationProvider; 

    @Autowired 
    @Qualifier("authenticationProvider") 
    public void setAuthenticationProvider(AuthenticationProvider authenticationProvider) { 
     this.authenticationProvider = authenticationProvider; 
    } 

    @Autowired 
    public void configureAuthManager(AuthenticationManagerBuilder authenticationManagerBuilder) { 
     authenticationManagerBuilder.authenticationProvider(authenticationProvider); 
    } 

    @Bean 
    public DaoAuthenticationProvider authenticationProvider() { 
     DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); 
     authProvider.setUserDetailsService(userService); 
     // authProvider.setPasswordEncoder(encoder()); 
     return authProvider; 
    } 

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

    @Override 
    protected void configure(HttpSecurity httpSecurity) throws Exception { 
     httpSecurity 
      .authorizeRequests() 
       .antMatchers("/", "/users", "/user").permitAll() 
       .anyRequest().authenticated() 
       .and() 
      .formLogin() 
       .loginPage("/login") 
       .permitAll() 
       .and() 
      .logout().permitAll(); 
     httpSecurity 
      .csrf().disable(); 
     httpSecurity 
      .headers() 
       .frameOptions().disable(); 
    } 

    @Bean 
    protected UserDetailsService userDetailsService() { 
     return super.userDetailsService(); 
    } 
} 

は私のコントローラである:

@Controller 
@Component 
public class UserWebController { 

    private final UserRestClient userService = new UserRestClient(); 

    @PreAuthorize("hasRole('ROLE_ADMIN')") 
    @RequestMapping(value = "/users", method = RequestMethod.GET) 
    @Produces(MediaType.APPLICATION_JSON) 
    public ResponseEntity<List<User>> getAllUsers() { 
     List<User> users = userService.findAllUsers().stream().map(UserMapper.INSTANCE::from).collect(Collectors.toList()); 
     return new ResponseEntity<List<User>>(users, HttpStatus.OK); 
    } 
} 

UserDetailsインタフェースの私の実装:

public class MyUser implements UserDetails { 

    private User user; 

    public MyUser(User user) { 
     this.user = user; 
    } 

    @Override 
    public Collection<? extends GrantedAuthority> getAuthorities() { 

     Set<GrantedAuthority> roles = new HashSet<>(); 
     roles.add(new Authority(user.getRole())); 
     return roles; 
    } 

    @Override 
    public String getPassword() { 
     return user.getPassword(); 
    } 

    @Override 
    public String getUsername() { 
     return user.getUsername(); 
    } 

    @Override 
    public boolean isAccountNonExpired() { 
     return true; 
    } 

    @Override 
    public boolean isAccountNonLocked() { 
     return true; 
    } 

    @Override 
    public boolean isCredentialsNonExpired() { 
     return true; 
    } 

    @Override 
    public boolean isEnabled() { 
     return true; 
    } 
} 

Userエンティティ:

@Table(name = "users") 
@AllArgsConstructor 
@Data 
@NoArgsConstructor 
@javax.persistence.Entity 
public class User extends Entity implements Serializable { 

    @Column(name = "username") 
    private String username; 

    @Column(name = "password") 
    private String password; 

    @Column(name = "role") 
    private String role; 
} 
+1

は、私は、ユーザーが正しいロールに認証された場合にのみ、OK応答を取得することです。したがって、私の場合、認証されたユーザーが管理者でない場合、私はユーザーのリストを取得したくありません。 – mka

+1

@dur申し訳ありませんが、私の最初の質問です。次回は改善を図ります。あなたの答えは解決策のようです、ありがとう! – mka

答えて

0

あなたはEnableGlobalMethodSecurity#prePostEnabled参照、@PreAuthorizeを有効にする必要があります。

は春のセキュリティの事前事後の注釈を有効にする必要があるかどうかを決定します。デフォルトはfalseです。

あなたの修正および簡略化された構成:事前認証注釈の私の理解@dur

@Configuration 
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) 
@RequiredArgsConstructor(onConstructor = @__({@Autowired})) 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Autowired 
    @Resource(name = "userRestClient") 
    UserService userService; 

    @Autowired 
    private AuthenticationProvider authenticationProvider; 

    @Autowired 
    @Qualifier("authenticationProvider") 
    public void setAuthenticationProvider(AuthenticationProvider authenticationProvider) { 
     this.authenticationProvider = authenticationProvider; 
    } 

    @Autowired 
    public void configureAuthManager(AuthenticationManagerBuilder authenticationManagerBuilder) { 
     authenticationManagerBuilder.authenticationProvider(authenticationProvider); 
    } 

    @Bean 
    public DaoAuthenticationProvider authenticationProvider() { 
     DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); 
     authProvider.setUserDetailsService(userService); 
     return authProvider; 
    } 

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

    @Override 
    protected void configure(HttpSecurity httpSecurity) throws Exception { 
     httpSecurity 
      .authorizeRequests() 
       .antMatchers("/", "/users", "/user").permitAll() 
       .anyRequest().authenticated() 
       .and() 
      .formLogin() 
       .loginPage("/login") 
       .permitAll() 
       .and() 
      .logout() 
       .permitAll() 
       .and() 
      .csrf() 
       .disable() 
       .and() 
      .headers() 
       .frameOptions().disable(); 
    } 

    @Bean 
    protected UserDetailsService userDetailsService() { 
     return super.userDetailsService(); 
    } 
} 
関連する問題