Spring Security DB UserDetailsS​​ervice不考虑用户的角色 [英] Spring security db UserDetailsService doesn't take in account the roles of users

查看:74
本文介绍了Spring Security DB UserDetailsS​​ervice不考虑用户的角色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个玩具Web应用程序,我想在其中登录从数据库获取的用户.

I have a toy web app, in which I want to login the users taken from database.

它可以工作,但是,我可以使用USER角色登录,而我只应使用具有ADMIN角色的用户登录.

It works but, I can login with a USER role where I should only login with a user having the ADMIN role.

这是我的代码:

Servlet 3.0引导程序

Servlet 3.0 bootstraper

public class Bootstraper extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[]{JPAConfig.class, WebSecurityConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[]{MvcConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    @Override
    protected Filter[] getServletFilters() {
        return new Filter[]{new DelegatingFilterProxy("springSecurityFilterChain"), new OpenEntityManagerInViewFilter()};
    }
}

用户实体:

@Entity
@Table(name = "users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(unique = true)
    private String name;

    @Column
    private String password;

    @Column
    private boolean enabled;

    @OneToMany(mappedBy = "user", fetch = FetchType.EAGER)
    private Set<Role> roles = new HashSet<>();

    public User() {
    }

    public User(String name, String password, boolean enabled) {
        this.name = name;
        this.password = password;
        this.enabled = enabled;
    }

    public Long getId() {
        return id;
    }

    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;
    }

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public Set<Role> getRoles() {
        return roles;
    }

    public void setRoles(Set<Role> roles) {
        this.roles = roles;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                ", enabled=" + enabled +
                '}';
    }
}

角色实体:

@Entity
@Table(name = "roles")
public class Role {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column
    private String role;

    @JoinColumn(name = "u_id")
    @ManyToOne
    private User user;

    public Role() {
    }

    public Role(String role) {
        this.role = role;
    }

    public Long getId() {
        return id;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public String toString() {
        return "Role{" +
                "id=" + id +
                ", role='" + role + '\'' +
                ", user=" + user +
                '}';
    }
}

我的自定义用户详细信息服务:

My custome userdetailsservice:

@Service
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private UsersService usersService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = usersService.getUser(username);
        if (user != null) {
            List<GrantedAuthority> authorityList = user.getRoles().stream()
                    .map(role -> new SimpleGrantedAuthority(role.getRole()))
                    .collect(Collectors.toList());

            return new org.springframework.security.core.userdetails.User(username, user.getPassword(), user.isEnabled(), true, true, true, authorityList);
        }

        return null;
    }
}

我将角色保留在数据库中,作为字符串:USER,MODERATOR,ADMIN

I am keeping my roles in the db, as strings : USER, MODERATOR, ADMIN

我的Spring安全配置:

My Spring security config:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private static final Logger LOGGER = LoggerFactory.getLogger(WebSecurityConfig.class);

    @Autowired
    private MyUserDetailsService userDetailsService;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }

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

        http.authorizeRequests()
                .antMatchers("/resources/**").permitAll()
                .anyRequest().authenticated()
                .antMatchers("/**").access("hasRole('ROLE_ADMIN')")
                .and().formLogin()
                .loginPage("/login")
                .permitAll().and()
                .logout().permitAll();

        http.csrf().disable();
    }
}

问题是伙计们,我说过我希望每个用户都拥有ROLE_ADMIN,但我仍然能够使用仅具有USER角色的用户登录.我不明白为什么.

The problem is guys, that I said I want every user to have the ROLE_ADMIN but I am still able to login also with a user that has only the USER role. I don't understand why.

我已经进行调试,可以从数据库成功获取用户,一切都很好,但是我不知道Spring在哪里检查角色.

I have made debug, my user is fetched successfully from the db, all is fine,but I don't know where Spring is checking for roles.

此致

推荐答案

从配置中删除.anyRequest().authenticated(),因为如果您请求ROLE检查用户必须通过身份验证,则在通过安全过滤器进行检查时,它显然具有优先权

remove your .anyRequest().authenticated() from configuration since if you request ROLE checking user has to be authenticated it apparently takes precedence when checked by the security filter

这篇关于Spring Security DB UserDetailsS​​ervice不考虑用户的角色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆