• 在Spring Boot中使用Spring Security实现权限控制


    丢代码地址

    https://gitee.com/a247292980/spring-security

    再丢pom.xml

      <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.thymeleaf.extras</groupId>
                <artifactId>thymeleaf-extras-springsecurity4</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.40</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.44</version>
            </dependency>
    

     最后放个代码结构图

    开讲

    WebSecurityConfig

    spring sercurity的设置。

    要有一个实现了UserDetailsService的bean,我的是CustomUserService。

    之后,重写两个configure的方法。

        @Override
        protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
            authenticationManagerBuilder.userDetailsService(customUserService());
        }
    
        /**
         * 1.首先当我们要自定义Spring Security的时候我们需要继承自WebSecurityConfigurerAdapter来完成,相关配置重写对应 方法即可。
         * 2.我们在这里注册CustomUserService的Bean,然后通过重写configure方法添加我们自定义的认证方式。
         * 3.在configure(HttpSecurity http)方法中,我们设置了登录页面,而且登录页面任何人都可以访问,然后设置了登录失败地址,也设置了注销请求,注销请求也是任何人都可以访问的。
         * 4.permitAll表示该请求任何人都可以访问,.anyRequest().authenticated(),表示其他的请求都必须要有权限认证。
         * 5.这里我们可以通过匹配器来匹配路径,比如antMatchers方法,假设我要管理员才可以访问admin文件夹下的内容,我可以这样来写:.
         * antMatchers("/admin/**").hasRole("ROLE_ADMIN"),也
         * 可以设置admin文件夹下的文件可以有多个角色来访问,写法如下:
         * .antMatchers("/admin/**").hasAnyRole("ROLE_ADMIN","ROLE_USER")
         * 6.可以通过hasIpAddress来指定某一个ip可以访问该资源,假设只允许访问ip为210.210.210.210的请求获取admin下的资源,写法如下.a
         * ntMatchers("/admin/**").hasIpAddress("210.210.210.210")
         */
        @Override
        protected void configure(HttpSecurity httpSecurity) throws Exception {
            httpSecurity.authorizeRequests()
    //                留意代码顺序
    //                首页(不需要登陆就能访问的页面
                    .antMatchers("/index").permitAll()
                    .anyRequest().authenticated()
    //                需要登陆才能访问的页面
                    .and().formLogin().loginPage("/login").defaultSuccessUrl("/index").failureUrl("/login?error").permitAll()
                    .and().logout().logoutUrl("/logout").logoutSuccessUrl("/login").permitAll()
                    .and().rememberMe().tokenValiditySeconds(60 * 60 * 24 * 7).key("kkkkkkkk");
        }
    

     HomeController,BaseEntity,Msg,SysRole

    不用多说了,简单的mvc

    SysUser

    要实现UserDetails接口,重写getAuthorities方法。

    里面有个@ManyToMany,虽然代码不配置也行,但这是将两个表关联起来的逻辑。

    @Entity
    public class SysUser extends BaseEntity implements UserDetails {
        @Id
        @GeneratedValue
        private Long id;
        private String username;
        private String password;
        /**
         * CascadeType.REFRESH:级联刷新,当多个用户同时作操作一个实体,为了用户取到的数据是实时的,
         * 在用实体中的数据之前就可以调用一下refresh()方法!
         * FetchType.EAGER:急加载,立即从数据库中加载
         */
        @ManyToMany(cascade = {CascadeType.REFRESH}, fetch = FetchType.EAGER)
        private List<SysRole> roles;
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public Long getId() {
            return this.id;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        @Override
        public String getUsername() {
            return this.username;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        @Override
        public String getPassword() {
            return this.password;
        }
    
        public void setRoles(List<SysRole> roles) {
            this.roles = roles;
        }
    
        public List<SysRole> getRoles() {
            return this.roles;
        }
    
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            List<GrantedAuthority> grantedAuthorityList = new ArrayList<>();
            List<SysRole> sysRoleList = this.getRoles();
            for (SysRole sysRole : sysRoleList) {
                grantedAuthorityList.add(new SimpleGrantedAuthority(sysRole.getName()));
            }
            return grantedAuthorityList;
        }
    
    
        @Override
        public boolean isAccountNonExpired() {
            return true;
        }
    
        @Override
        public boolean isAccountNonLocked() {
            return true;
        }
    
        @Override
        public boolean isCredentialsNonExpired() {
            return true;
        }
    
        @Override
        public boolean isEnabled() {
            return true;
        }
    }
    

     SysUserRepository

    spring-jpa的简单应用

    CustomUserService

    实现loadUserByUsername的方法,就是传说中的认证方法了,为啥不叫authorize啊?这名字太low了吧。

    SpringSecurityApplication

    不懂这个的,没关系新建spring boot自带的。

  • 相关阅读:
    Oracle结构连接配置结构
    理解cookie和session机制
    Asp.net中网站级异常捕获
    C#字符串函数大全
    一个简单的C#多线程间同步的例子
    SQL中的存储过程存放位置
    类和结构的区别?
    SQL点滴9—使用with语句来写一个稍微复杂sql语句
    Asp.NET 的Session实现原理 转自21kaiyun.com
    Script to analyze table space usage
  • 原文地址:https://www.cnblogs.com/ydymz/p/8317484.html
Copyright © 2020-2023  润新知