簡體   English   中英

spring security - 基於角色的訪問

[英]spring security - role based access

我已經為我的 webapp 實現了 spring 安全。

我想配置基於角色的訪問。 只有具有“ROLE_ADMIN”角色的用戶才能登錄。

我添加了模型“角色”並在我的數據庫中添加了一個表。 但是,具有“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();
    }
}

}

你在擴展WebMvcConfigurerAdapter嗎? 此外,hasRole 會將提供的字符串前綴為“ROLE_”

來自文檔:

需要的角色(即用戶、管理員等)。 請注意,它不應以“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);
        }

    }

}

我已經實現了一個基於角色的訪問,登錄后管理員用戶將被定向到管理員主頁,普通用戶將被重定向到用戶主頁。

下面是我的 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;
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM