spring security - 基于角色的访问

时间:2017-05-19 10:28:02

标签: spring spring-boot login spring-security

我已经为我的webapp实现了spring security。

我想配置基于角色的访问权限。只有具有“ROLE_ADMIN”角色的用户才能登录。

我添加了模型“Role”并在我的数据库中添加了一个表。 但是,具有“ROLE_USER”角色的用户仍然可以登录。

@Override
protected void configure(HttpSecurity http) {
    try {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/resources/**").hasRole("ROLE_ADMIN")
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
                .logout()
                .permitAll();
    } catch (Exception e) {
        e.printStackTrace();
    }

}

谢谢!

编辑:完成弹簧安全配置

@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = UserDetailsServiceImpl.class)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private UserDetailsService userDetailsService;

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

@Override
public void configure(WebSecurity web) {
    web.ignoring().antMatchers("/css/**", "/js/**");
}

@Override
protected void configure(HttpSecurity http) {
    try {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/resources/**").hasRole("ADMIN")
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
                .logout()
                .permitAll();
    } catch (Exception e) {
        e.printStackTrace();
    }

}

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

@Autowired
public void globalSecurityConfiguration(AuthenticationManagerBuilder auth) {
    try {
        auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

}

2 个答案:

答案 0 :(得分:1)

您是否正在延长WebMvcConfigurerAdapter?此外,hasRole将在提供的字符串前加上“ROLE _”

来自doc:

要求的角色(即USER,ADMIN等)。请注意,它不应以“ROLE_”开头,因为它会自动插入。

示例:

@SpringBootApplication
public class SampleWebSecureJdbcApplication extends WebMvcConfigurerAdapter {

    public static void main(String[] args) throws Exception {
        new SpringApplicationBuilder(SampleWebSecureJdbcApplication.class).run(args);
    }

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

        @Autowired
        private DataSource dataSource;

        @Override
        protected void configure(HttpSecurity http) throws Exception {
                http
                    .authorizeRequests()    
                    .antMatchers("/resources/**", "/signup", "/about").permitAll()    
                    .antMatchers("/admin/**").hasRole("ADMIN")  
                    .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
                    .anyRequest().authenticated()    
                    .and()
                    .formLogin().loginPage("/login").failureUrl("/login?error").permitAll()
                    .and()
                    .logout().permitAll();
        }

        @Override
        public void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.jdbcAuthentication().dataSource(this.dataSource);
        }

    }

}

答案 1 :(得分:0)

我已经实现了基于角色的访问,在此之后,登录admin用户将被定向到管理主页,普通用户将被重定向到用户主页。

下面是我的SecurityConfiguration类。

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private DataSource dataSource;


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

        final String sqlUserName = "select email, password, active from user where email=?";
        final String sqlAuthorities= "select u.email, r.role from user u inner join user_role ur on(u.user_id=ur.user_id) inner join role r on(ur.role_id=r.role_id) where u.email=?";

        auth.
                jdbcAuthentication()
                .usersByUsernameQuery(sqlUserName)
                .authoritiesByUsernameQuery(sqlAuthorities)
                .dataSource(dataSource)
                .passwordEncoder(bCryptPasswordEncoder);
    }

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

        http.   authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/login").permitAll()
                .antMatchers("/registration").permitAll()
                .antMatchers("/resources/**", "/static/**", "/static.css/**", "/js/**", "/static.images/**").permitAll()
                .antMatchers("/user").hasAuthority("USER")
                .antMatchers("/home").hasAuthority("ADMIN").anyRequest()
                .authenticated().and().csrf().disable().formLogin()
                .loginPage("/login").failureUrl("/login?error=true")
                .defaultSuccessUrl("/loginroute",true)
                .usernameParameter("email")
                .passwordParameter("password")
                .and().logout()
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .logoutSuccessUrl("/").and().exceptionHandling()
                .accessDeniedPage("/access-denied");
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web
                .ignoring()
                .antMatchers("/resources/**", "/static/**", "/static.css/**", "/js/**", "/static.images/**");
    }

}

.defaultSuccessUrl(“ / loginroute”,true)将重定向到/ loginroute控制器。下面是控制器方法。

@RequestMapping (value = "/loginroute",method = RequestMethod.GET)
    public String sample(){
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        User user = userService.findUserByEmail(auth.getName());
        String rolevalue = null;
        for (Role role : user.getRoles()) {
           rolevalue = role.getRole();
        }
        System.out.println(user.getRoles().contains("role"));
        if(rolevalue.equals("ADMIN"))
            return "redirect:home";
        else if(rolevalue.equals("USER"))
            return "redirect:user";
        return "User does not have permission";
    }

    @RequestMapping(value="/home", method = RequestMethod.GET)
    public ModelAndView home(){
        ModelAndView modelAndView = new ModelAndView();
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        User user = userService.findUserByEmail(auth.getName());
        modelAndView.addObject("userName", "Welcome " + user.getName() + " " + user.getLastName() + " (" + user.getEmail() + ")");
        modelAndView.addObject("adminMessage","Content Available Only for Users with Admin Role");
        modelAndView.setViewName("home");
        return modelAndView;
    }

    @RequestMapping(value="/user", method = RequestMethod.GET)
    public ModelAndView userhome(){
        ModelAndView modelAndView = new ModelAndView();
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        User user = userService.findUserByEmail(auth.getName());
        modelAndView.addObject("userName", "Welcome user: " + user.getName() + " " + user.getLastName() + " (" + user.getEmail() + ")");
        modelAndView.addObject("userMessage","Content Available Only for Users with User Role");
        modelAndView.setViewName("user");
        return modelAndView;
    }