美文网首页
Spring boot security 入门

Spring boot security 入门

作者: ikonan | 来源:发表于2018-04-18 10:04 被阅读88次

    security 介绍

    Spring Security是能够为J2EE项目提供综合性的安全访问控制解决方案的安全框架。它依赖于Servlet过滤器。这些过滤器拦截进入请求,并且在应用程序处理该请求之前进行某些安全处理。

    build.gradle 依赖文件

    buildscript {
        ext {
            springBootVersion = '2.0.1.RELEASE'
        }
        repositories {
            maven {
                url 'http://maven.aliyun.com/nexus/content/groups/public'
            }
        }
        dependencies {
            classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        }
    }
    
    apply plugin: 'java'
    apply plugin: 'eclipse'
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'
    
    group = 'com.example'
    version = '0.0.1-SNAPSHOT'
    sourceCompatibility = 1.8
    
    repositories {
        maven {
            url 'http://maven.aliyun.com/nexus/content/groups/public'
        }
    }
    
    dependencies {
        compile('org.springframework.boot:spring-boot-starter')
        compile('org.springframework.boot:spring-boot-starter-data-jpa')
        compile('org.springframework.boot:spring-boot-starter-security')
        compile('mysql:mysql-connector-java:6.0.5')
    
        testCompile('org.springframework.boot:spring-boot-starter-test')
    }
    

    application.properties

    server.port=8080
    debug=true
    
    # DataSource
    spring.datasource.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC 
    spring.datasource.username=root
    spring.datasource.password=root
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    
    # JPA
    spring.jpa.show-sql=true
    spring.jpa.hibernate.ddl-auto=update
    

    定义角色实体

    @Entity
    public class SysRole {
        @Id
        @GeneratedValue
        private Long id;
        private String name;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    

    定义用户POJO

    我们在定义用户的时候需要实现UserDetails接口,这样我们的用户实体即为Spring Security所使用的用户,定义好用户之后,我们还要配置用户和角色之间的多对多关系,正常情况下,角色和权限是两回事,所以我们还需要重写getAuthorities方法,将用户的角色和权限关联起来

    @Entity
    public class SysUser implements UserDetails {
        @Id
        @GeneratedValue
        private Long id;
        private String username;
        private String password;
    
        @ManyToMany(cascade = {CascadeType.REFRESH},fetch = FetchType.EAGER)
        private List<SysRole> roles;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public List<SysRole> getRoles() {
            return roles;
        }
    
        public void setRoles(List<SysRole> roles) {
            this.roles = roles;
        }
    
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            List<GrantedAuthority> auths = new ArrayList<>();
            List<SysRole> roles = this.getRoles();
            for (SysRole role : roles) {
                auths.add(new SimpleGrantedAuthority(role.getName()));
            }
            return auths;
        }
    
        @Override
        public String getPassword() {
            return this.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;
        }
    }
    

    预设数据

    我们先在表中定义好几个角色和用户,方便我们后边做测试用

    insert  into `sys_role`(`id`,`name`) values (1,'ROLE_ADMIN'),(2,'ROLE_USER');
    insert  into `sys_user`(`id`,`password`,`username`) values (1,'root','root'),(2,'sang','sang');
    insert  into `sys_user_roles`(`sys_user_id`,`roles_id`) values (1,1),(2,2);
    

    创建数据访问接口

    public interface SysUserRepository extends JpaRepository<SysUser, Long> {
        SysUser findByUsername(String username);
    }
    

    自定义UserDetailsService

    public class CustomUserService implements UserDetailsService {
        @Autowired
        SysUserRepository userRepository;
        @Override
        public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
            SysUser user = userRepository.findByUsername(s);
            if (user == null) {
                throw new UsernameNotFoundException("用户名不存在");
            }
            System.out.println("s:"+s);
            System.out.println("username:"+user.getUsername()+";password:"+user.getPassword());
            return user;
        }
    }
    

    首先这里我们需要重写UserDetailsService接口,然后实现该接口中的loadUserByUsername方法,通过该方法查询到对应的用户,这里之所以要实现UserDetailsService接口,是因为在Spring Security中我们配置相关参数需要UserDetailsService类型的数据

    配置Spring Security

    @Configuration
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Bean
        UserDetailsService customUserService() {
            return new CustomUserService();
        }
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(customUserService());
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    .anyRequest().authenticated()
                    .and().formLogin().loginPage("/login").failureUrl("/login?error").permitAll().and()
                    .logout().permitAll();
        }
    }
    
    • 首先当我们要自定义Spring Security的时候我们需要继承自WebSecurityConfigurerAdapter来完成,相关配置重写对应 方法即可。
    • 我们在这里注册CustomUserService的Bean,然后通过重写configure方法添加我们自定义的认证方式。
    • 在configure(HttpSecurity http)方法中,我们设置了登录页面,而且登录页面任何人都可以访问,然后设置了登录失败地址,也设置了注销请求,注销请求也是任何人都可以访问的。
    • permitAll表示该请求任何人都可以访问,.anyRequest().authenticated(),表示其他的请求都必须要有权限认证。
    • 这里我们可以通过匹配器来匹配路径,比如antMatchers方法,假设我要管理员才可以访问admin文件夹下的内容,我可以这样来写:.antMatchers("/admin/").hasRole("ROLE_ADMIN"),也可以设置admin文件夹下的文件可以有多个角色来访问,写法如下:.antMatchers("/admin/").hasAnyRole("ROLE_ADMIN","ROLE_USER")
      6.可以通过hasIpAddress来指定某一个ip可以访问该资源,假设只允许访问ip为210.210.210.210的请求获取admin下的资源,写法如下 .antMatchers("/admin/**").hasIpAddress("210.210.210.210")
    image.png

    相关文章

      网友评论

          本文标题:Spring boot security 入门

          本文链接:https://www.haomeiwen.com/subject/kutvkftx.html