当用户以“ADMIN”角色而不是以“USER”角色登录时,访问被拒绝

Posted

技术标签:

【中文标题】当用户以“ADMIN”角色而不是以“USER”角色登录时,访问被拒绝【英文标题】:Access is denied when user login as 'ADMIN' role but not in 'USER' role 【发布时间】:2020-12-30 02:07:12 【问题描述】:

网络安全配置

@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter 

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private MyUserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth
            .userDetailsService(userDetailsService)
            .passwordEncoder(bCryptPasswordEncoder);
    

    @Override
    protected void configure(HttpSecurity http) throws Exception 

        String loginPage = "/login";
        String logoutPage = "/logout";

        http
            .authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers(loginPage).permitAll()
                //.antMatchers("/registration").permitAll()
                .antMatchers("/user/**").hasAnyAuthority("USER","ADMIN")
                .anyRequest().authenticated()
                .and()
            .csrf().disable()
            .formLogin()
                .loginPage(loginPage)
                .loginPage("/")
                .failureUrl("/login?error=true")
                .defaultSuccessUrl("/user")
                .usernameParameter("username")
                .passwordParameter("password")
                .and()
            .logout()
                .logoutRequestMatcher(new AntPathRequestMatcher(logoutPage))
                .logoutSuccessUrl(loginPage).and().exceptionHandling();
    

MyUserDetailsS​​ervice

@Service
public class MyUserDetailsService implements UserDetailsService 

    @Autowired
    private UserService userService;

    @Override
    @Transactional
    public UserDetails loadUserByUsername(String userName) 
        User user = userService.findUserByUserName(userName);
        List<GrantedAuthority> authorities = getUserAuthority(user.getRoles());
        return buildUserForAuthentication(user, authorities);
    

    private List<GrantedAuthority> getUserAuthority(Set<Role> userRoles) 
        Set<GrantedAuthority> roles = new HashSet<>();
        for (Role role : userRoles) 
            roles.add(new SimpleGrantedAuthority(role.getRole()));
        
        return new ArrayList<>(roles);
    

    private UserDetails buildUserForAuthentication(User user, List<GrantedAuthority> authorities) 
        return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getPassword(),
                user.getActive(), true, true, true, authorities);
    

型号

@Entity
@Table(name = "users")
public class User 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    private long id;
    
    @Column(name = "username")
    private String userName;
    
    @Column(name = "password")
    private String password;

    @Column(name = "active")
    private Boolean active;

    @ManyToMany(cascade = CascadeType.MERGE)
    @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set<Role> roles;

    // getters and setters 



@Entity
@Table(name = "roles")
public class Role 
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "role_id")

    private int id;
    @Column(name = "role")
    private String role;

    // getters and setters

我收到错误 Spring Boot 安全登录。我在管理员角色登录时遇到错误。但是当我登录用户角色时,它运行良好。我不明白为什么会这样?

当我尝试以管理员身份登录时,它会重定向我 http://localhost:8080/error 页面在正文中显示:

"timestamp":"2020-09-11T14:10:05.108+00:00","status":999,"error":"None","message":""

但是当尝试以用户身份登录时,它工作正常。

【问题讨论】:

你叫什么网址? 我打电话给http://localhost:8080/login 尝试将permitAll()添加到.formLogin() 我尝试添加 permitAll(),但在管理员登录时出现错误 【参考方案1】:

你可能搞砸了 antMatchers!

在你提到的代码中

.antMatchers("/user/**").hasAnyAuthority("USER","ADMIN")

这意味着用户和管理员都可以访问与“/user/**”匹配的 url,即。所有带有前缀“/user/”的url

如果您有一个带有“/admin/*”的管理员网址 " ,那么您也应该授予对 "/admin/**" 的访问权限!

那你得再添加一个antMatcher之类的

.antMatchers("/admin/**).hasRole("ADMIN")

这将只允许访问管理网址,即。带前缀“/admin/**”

【讨论】:

以上是关于当用户以“ADMIN”角色而不是以“USER”角色登录时,访问被拒绝的主要内容,如果未能解决你的问题,请参考以下文章

MVC 基于角色的路由

collect_select,我想在我的下拉菜单中选择仅将admin角色设为true的用户

基于用户角色的 Laravel voyager 策略

如何检查未登录用户是不是有角色?

OpenStack-9-用户,项目和角色的关系

laravel 5根据用户的角色在登录后重定向用户