SpringSecurity configure()方法配置问题

时间:2018-11-11 17:23:58

标签: spring spring-boot spring-security

我已经开发了REST api,其中的方法通过SpringSecurity进行保护。

GITHUB LINK -> Project

它正在工作,但没有达到预期的

SpringSecurity.config
---------------------------

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter{

    @Autowired
    private UserDetailsService userDetailService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.userDetailsService(userDetailService).passwordEncoder(encode());


    }


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


        http
            .csrf().disable();
        http

            .authorizeRequests()
            .antMatchers("/user/**")
            .authenticated()
            .anyRequest()
            .hasAnyRole("USER","ADMIN")
            .and()
            .authorizeRequests()
            .antMatchers("/admin/**")
            .authenticated()
            .anyRequest()
            .hasRole("ADMIN")
            .and()
            .formLogin()
            .permitAll();

        /*http
            .authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasAnyRole("USER","ADMIN")
            .anyRequest()
            .authenticated()
            .and()
            .formLogin()
            .permitAll();*/

    }

    @Bean
    public BCryptPasswordEncoder encode() {
        return new BCryptPasswordEncoder();
    }

}

AdminController
----------------------

@RestController
@RequestMapping("/admin")
public class AdminController {

    @Autowired
    private UserRepo userRepo;
    @Autowired
    private BCryptPasswordEncoder encoder;

    @PostMapping("/add")
    @PreAuthorize("hasRole('ADMIN')")
    public String addUser(@RequestBody User user) {
        String encodedPwd= encoder.encode(user.getPassword());
        user.setPassword(encodedPwd);
        userRepo.save(user);
        return "user added sucessfully...";
    }

    @GetMapping("/demo")
    @PreAuthorize("hasRole('ADMIN')")
    public String getDemo() {
        return "Hi";
    }

}

CustomController
-------------------------

@RestController
@RequestMapping("/user")
public class CustomController {

    @GetMapping("/access")
    @PreAuthorize("hasAnyRole('USER','ADMIN')")
    public String showUser() {

        return "Url Security Provided";
    }
}

CustomUserDetailService
-----------------------------

@Service
public class CustomUserDetailService implements UserDetailsService {

    @Autowired
    private UserRepo userRepo;

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

        User user= userRepo.findByUsername(username);
        CustomUserDetails userDetails= null;

        if(user!= null) {
            userDetails= new CustomUserDetails();
            userDetails.setUser(user);
        }else {
            throw new UsernameNotFoundException("User Not Found");
        }
        return userDetails;
    }

}

CustomUserDetail
-----------------

@Getter
@Setter
public class CustomUserDetails implements UserDetails {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private User user;


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

        /*return user.getRoles().stream()
            .map(role->new SimpleGrantedAuthority("ROLE_"+ role))
            .collect(Collectors.toList());*/
        return user.getRoles().stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role))
        .collect(Collectors.toList());
    }

    @Override
    public String getPassword() {
        // TODO Auto-generated method stub
        return user.getPassword();
    }

    @Override
    public String getUsername() {
        // TODO Auto-generated method stub
        return user.getUsername();
    }

    @Override
    public boolean isAccountNonExpired() {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public boolean isEnabled() {
        // TODO Auto-generated method stub
        return true;
    }

    public CustomUserDetails() {
        super();
        // TODO Auto-generated constructor stub
    }

}

用户
----------

@Entity
@Getter
@Setter
@NoArgsConstructor
public class User {

    @Id
    @GenericGenerator(name="gen",strategy="increment")
    @GeneratedValue(generator="gen")
    private int user_id;
    private String username;
    private String password;
    private String email;
    @OneToMany(cascade= CascadeType.ALL, fetch= FetchType.EAGER)
    @JoinTable(name="user_roles",
                    joinColumns= @JoinColumn(referencedColumnName= "user_id"), 
                    inverseJoinColumns= @JoinColumn(referencedColumnName="role_id"))
    private Set<Roles> roles;

}

问题是: 通过上述设置,我可以访问USER而不是ADMIN的URL

  如果我在评论

http
            /*.authorizeRequests()
            .antMatchers("/user/**")
            .authenticated()
            .anyRequest()
            .hasRole("USER")
            .and()*/
            .authorizeRequests()
            .antMatchers("/admin/**")
            .authenticated()
            .anyRequest()
            .hasRole("ADMIN")
            .and()
            .formLogin()
            .permitAll();

然后,我可以访问用于 ADMIN URL ,但是我缺少用于 USER < / strong>

类似地,如果我要评论 admin / ,那么可以访问 USER 部分。就像Ordering首先出现在哪个url中一样,它认识到,第二个只是在浏览器中给403而不是控制台中的任何内容。

类似于Order的东西,首先可以访问

在哪里我做错了。

如果我不评论@EnableGlobalSecurity@PreAuthorize,则无法访问用于 ADMIN 的任何 URL > USER 只是403,所以我不会错过@EnableGlobalSecurity@PreAuthorize,因为这些都是用于保护REST API方法的

1 个答案:

答案 0 :(得分:0)

只需为您的管理员角色添加所有页面的权限即可。这样,您可以确保管理员可以访问他想要的任何页面。

http
            /*.authorizeRequests()
            .antMatchers("/user/**")
            .authenticated()
            .anyRequest()
            .hasRole("USER")
            .and()*/
            .authorizeRequests()
            .antMatchers("/admin/**")
            .hasRole("ADMIN")
            .antMatchers("/user/**")
            .hasAnyRole("ADMIN", "USER")
            .and()
            .formLogin()
            .permitAll();