springboot基于角色的权限认证

一、使用场景

springboot、springSecurity、mybatis  基于角色的权限控制

二、参考文献

https://liuyanzhao.com/7431.html

说明:网上查了一圈,只按照以上这篇博客实践成功,本文仅仅是自己实践的一些记录

三、坑

3.1

User 最好是implements UserDetails

public class User implements UserDetails {

3.2

User里角色对象要用Authority implements GrantedAuthority描述,不要用自定义的枚举或者字符串

private List<Authority> authoritys;
public class Authority implements GrantedAuthority {
    private String id;
    private String username;
    private String role;

3.3

SecurityConfig配置使用hasRole()时,不要在前面加.anyRequest().authenticated(),全用hasRole()即可

protected void configure(HttpSecurity http) throws Exception {
        http.formLogin().loginPage("/login").permitAll().failureUrl("/error").and().logout().logoutSuccessUrl("/login").permitAll().and().rememberMe().alwaysRemember(true)
                .and().authorizeRequests()
//                .anyRequest().authenticated()  这行不能加
                .antMatchers("/").hasRole("USER")
                .antMatchers("/manager/**").hasRole("ROOT")
                .antMatchers("/user/**").hasRole("USER")
                .and().csrf().disable();
    }

3.4

数据库里的角色要加前缀ROLE_  例如:ROLE_ROOT

而SecurityConfig配置里要写不带前缀的例如.antMatchers("/").hasRole("ROOT")

四、解决方案

4.1 环境

jdk 8、springboot 2.0.1.RELEASE、maven、mybatis

4.2 关键依赖

<!--security-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity4</artifactId>
            <version>3.0.2.RELEASE</version>
        </dependency>

4.3 实体类

User

package com.xp.entity;

import org.apache.ibatis.annotations.Many;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class User implements UserDetails, Serializable {

    private static final long serialVersionUID = 1054349578207608180L;  
    private String username;
   
    private String password;  
    
    private List<Authority> authoritys; 

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<SimpleGrantedAuthority> simpleAuthorities = new ArrayList<>();
        for(GrantedAuthority authority : this.authoritys){
            simpleAuthorities.add(new SimpleGrantedAuthority(authority.getAuthority()));
        }
        return simpleAuthorities;
    } 

}

Authority 角色

public class Authority implements GrantedAuthority {
    private String id;
    private String username;
    private String role;
}

UserMapper(基于mybits注解)

配置类

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)// 启用方法安全设置
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    @Autowired
    private DataSource dataSource;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Bean
    CustomUserService customUserService() {
        return new CustomUserService();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();      
    }

    @Bean
    public AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(customUserService());
        authenticationProvider.setPasswordEncoder(passwordEncoder); // 设置密码加密方式
        return authenticationProvider;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin().loginPage("/login").permitAll().failureUrl("/error").and().logout().logoutSuccessUrl("/login").permitAll().and().rememberMe().alwaysRemember(true)
                .and().authorizeRequests()
//                .anyRequest().authenticated()  这行不能加
                .antMatchers("/").hasRole("USER")
                .antMatchers("/manager/**").hasRole("ROOT")
                .antMatchers("/user/**").hasRole("USER")
                .and().csrf().disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserService());
        auth.authenticationProvider(authenticationProvider());
    }

}

猜你喜欢

转载自my.oschina.net/Cubicluo/blog/1817666