springboot11-security02FromDB 权限管理(用户信息和角色信息保存在数据库)

<h4>场景</h4>

 

<h4>代码</h4>

springboot+springsecurity+mysql(jpa)实现:

1.pom依赖:

 1 <!-- security -->
 2         <dependency>
 3             <groupId>org.springframework.boot</groupId>
 4             <artifactId>spring-boot-starter-security</artifactId>
 5         </dependency>
 6         <dependency>
 7             <groupId>org.springframework.boot</groupId>
 8             <artifactId>spring-boot-starter-thymeleaf</artifactId>
 9         </dependency>
10 
11         <!--jpa-->
12         <dependency>
13             <groupId>org.springframework.boot</groupId>
14             <artifactId>spring-boot-starter-data-jpa</artifactId>
15         </dependency>
16         <!--mysql-->
17         <dependency>
18             <groupId>mysql</groupId>
19             <artifactId>mysql-connector-java</artifactId>
20         </dependency>
View Code

2.application配置:

 1 spring.thymeleaf.prefix=classpath:/page/
 2 
 3 #mysql连接地址
 4 spring.datasource.url=jdbc:mysql://localhost:3307/springboot_test
 5 #mysql用户名和密码
 6 spring.datasource.username=root
 7 spring.datasource.password=root
 8 #driver驱动
 9 spring.datasource.driver-class-name=com.mysql.jdbc.Driver
10 #show sql
11 spring.jpa.show-sql=true
12 # Hibernate ddl auto (create, create-drop, update)
13 #### hibernate的ddl-auto=update配置表名,数据库的表和列会自动创建(根据Java实体)
14 spring.jpa.hibernate.ddl-auto=update
15 # 方言
16 spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
View Code

3.连接数据库:db->bean->dao->service

public interface UserDao extends JpaRepository<User, Long>{

    User findByUserName(String userName);
    User findByUserNameAndPassword(String userName, String password);
}
@Service
public class UserService {
    @Autowired
    private UserDao userDao;

    public User findById(Long id){
        return userDao.findOne(id);
    }

    public User findByUserName(String userName){
        return userDao.findByUserName(userName);
    }

    public User login(String userName, String password){
        return userDao.findByUserNameAndPassword(userName, password);
    }

    public List<User> userList(){
        return userDao.findAll();
    }
}

实体类User

@Entity
@Table(name = "user")
public class User implements UserDetails {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String userName;
    private String password;
    private String pwdBak;
    private String role;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<SimpleGrantedAuthority> auths = new ArrayList<>();
        auths.add(new SimpleGrantedAuthority(this.getRole()));
        return auths;
    }

    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return this.userName;
    }

    @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 setPassword(String password) {
        this.password = password;
    }

    public String getPwdBak() {
        return pwdBak;
    }

    public void setPwdBak(String pwdBak) {
        this.pwdBak = pwdBak;
    }

    public String getRole() {
        return role;
    }

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

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

4.websecurity配置:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)//开启进入Controller之前,检验权限。这个注解配置后,Controller中的@PreAuthorize("hasAnyAuthority('ADMIN')")才会生效
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
    @SuppressWarnings("SpringJavaAutowiringInspection")
    @Autowired
    private MyUDService myUDService;
    @Bean
    @Override
    protected AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

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

        httpSecurity.authorizeRequests()
                .antMatchers("/", "/login", "/err/*").permitAll() //无需验证权限
                .anyRequest().authenticated() //其他地址的访问均需验证权限
                .and().formLogin().loginPage("/login").defaultSuccessUrl("/home").permitAll()//指定登录页是"/login" //登录成功后默认跳转到"/home"
                .and().logout().logoutSuccessUrl("/login").permitAll(); //退出登录后的默认url是"/login"
    }

    /**
     * 全局配置
     * @param builder
     * @throws Exception
     */
    @Autowired
    public void configure(AuthenticationManagerBuilder builder) throws Exception {
        builder
                .userDetailsService(myUDService)
                .passwordEncoder(this.passwordEncoder());
    }

    /**
     * 设置用户密码的加密方式:MD5加密
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        PasswordEncoder pe = new PasswordEncoder() {//自定义密码加密方式
            //加密
            @Override
            public String encode(CharSequence charSequence) {
                return MD5Util.encode((String)charSequence);
            }

            //校验密码
            @Override
            public boolean matches(CharSequence charSequence, String s) {
                return MD5Util.encode((String)charSequence).equals(s);
            }
        };
        return pe;
    }
}
View Code

5.用户权限查询类UserDetailsService:

@Component
public class MyUDService implements UserDetailsService {

    @Autowired
    private UserService userService;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        User user = userService.findByUserName(s);
        if(user == null) {
            throw new UsernameNotFoundException("UserName " + s + " not found");
        }

        System.out.println("用户" + s + ":" + user);
        return user;
    }
}
View Code

6.启动类:

@SpringBootApplication
public class Start02App {

    public static void main(String[] args) {
        SpringApplication.run(Start02App.class, args);
    }

    /**
     * 自定义异常页
     */
    @Bean
    public EmbeddedServletContainerCustomizer containerCustomizer() {
        return new EmbeddedServletContainerCustomizer(){
            @Override
            public void customize(ConfigurableEmbeddedServletContainer container) {
                container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/error/404"));
                container.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500"));
                container.addErrorPages(new ErrorPage(java.lang.Throwable.class,"/error/500"));
                container.addErrorPages(new ErrorPage(HttpStatus.FORBIDDEN,"/error/403"));
            }
        };
    }
}
View Code

7.页面

8.往数据库插入数据(单元测试):

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Start02App.class)
public class UserServiceTest {

    @Autowired
    private UserDao userDao;
    @Autowired
    private UserService userService;

    private ObjectMapper objectMapper = new ObjectMapper();

    @Test
    public void testAll() throws JsonProcessingException {

        this.saveUser();
        this.list();

    }

    private void saveUser() throws JsonProcessingException {
        User admin = new User();
        admin.setUserName("admin");
        admin.setPassword(MD5Util.encode("admin"));
        admin.setPwdBak("admin");
        admin.setRole("ADMIN");
        User adminSave = userDao.save(admin);
        for(int i=0;i<=5;i++) {
            System.out.println("admin save--->:" + objectMapper.writeValueAsString(adminSave));
            User user = new User();
            user.setUserName("test"+i);
            user.setPassword(MD5Util.encode("user" + i));
            user.setPwdBak("user" + i);
            user.setRole("USER");
            User userSave = userDao.save(user);
            System.out.println("user save--->:" + objectMapper.writeValueAsString(userSave));
        }
    }

    private void list() throws JsonProcessingException {
        List<User> userList = userService.userList();
        System.out.println("用户列表:" + objectMapper.writeValueAsString(userList));
    }

}
View Code

查看数据库:

 

<h4>效果</h4>

 

启动app类,访问:http://localhost:8080/

测试:

先点击“去主页”或“查看用户列表”,要求输入用户名密码:

使用admin登录,跳转到主页:

返回后,点击去“用户列表”,跳转到403,提示没有权限:

注销后使用普通用户登录,可以跳转到用户列表页面:

测试500页面:

 

测试404页面:

 项目地址:https://github.com/yangzhenlong/mySpringBootDemo/tree/master/springboot11-auth/springboot11-security02FromDB

posted @ 2017-05-24 16:20  艺言弈行  阅读(416)  评论(0编辑  收藏  举报