Spring Boot + JPA + Spring Security 实现用户权限数据库管理

 使用Spring Boot + JPA + SpringSecurity 实现用户权限数据库管理

开发工具    STS(Spring Tool Suite) spring boot 2.0.6

 添加依赖

Spring Boot + JPA + Spring Security 实现用户权限数据库管理_第1张图片

 依赖pom.xml


           
                 org.springframework.boot
                 spring-boot-starter-data-jpa
           
           
                 org.springframework.boot
                 spring-boot-starter-jdbc
           
           
                 org.springframework.boot
                 spring-boot-starter-security
           
           
                 org.springframework.boot
                 spring-boot-starter-thymeleaf
           
           
                 org.springframework.boot
                 spring-boot-starter-web
           
           
                 mysql
                 mysql-connector-java
                 runtime
           
           
                 org.springframework.security
                 spring-security-test
                 test
           
           
                 org.springframework.boot
                 spring-boot-devtools
                 true 
           
      

application.properties

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/dome2
spring.datasource.username=root
spring.datasource.password=123456
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update

在搭建使用spring security 的时候  我分成了两个大的步骤学习   、

第一步   【用户的登录】,

第二步 【 权限限制】。 

 

第一步    用户登录(验证帐号密码

 数据设计

     用户(user)  、角色 (role) 、  权限(authority )   用数据库存储权限 ,url 存储在权限表中,其中用户 、角色 多对多关系, 角色 、权限也是多对多关系

Spring Boot + JPA + Spring Security 实现用户权限数据库管理_第2张图片

 

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` bigint(20) NOT NULL,
  `email` varchar(50) DEFAULT NULL,
  `enabled` bit(1) DEFAULT NULL,
  `firstname` varchar(50) DEFAULT NULL,
  `lastpasswordresetdate` datetime DEFAULT NULL,
  `lastname` varchar(50) DEFAULT NULL,
  `password` varchar(100) DEFAULT NULL,
  `username` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `UK_sb8bbouer5wak8vyiiy4pf2bx` (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

INSERT INTO `user` VALUES (1,'[email protected]',b'1','admin',NULL,'admin','123','sjy'),(2,'[email protected]',b'1','user',NULL,'user','123','user'),(3,'[email protected]',b'0','user',NULL,'user','123','test');



DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(25) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

INSERT INTO `role` VALUES (1,'ROLE_ADMIN'),(2,'ROLE_USER'),(3,'ROLE_TEST');


DROP TABLE IF EXISTS `authority`;
CREATE TABLE `authority` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `pid` int(11) NOT NULL,
  `url` varchar(255) DEFAULT NULL,
  `description` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

INSERT INTO `authority` VALUES (1,'admin',0,'/index1','管理'),(2,'user',0,'/index2','用戶'),(3,'test',0,'/index3','測試');


DROP TABLE IF EXISTS `user_role`;
CREATE TABLE `user_role` (
  `user_id` bigint(20) NOT NULL,
  `role_id` bigint(20) NOT NULL,
  KEY `FKa68196081fvovjhkek5m97n3y` (`role_id`),
  KEY `FK859n2jvi8ivhui0rl0esws6o` (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;


INSERT INTO `user_role` VALUES (1,1),(2,2),(3,3),(1,2);

DROP TABLE IF EXISTS `role_auth`;
CREATE TABLE `role_auth` (
  `auth_id` bigint(20) NOT NULL,
  `role_id` bigint(20) NOT NULL,
  KEY `FKrcrl3r3y8xexlss4vuah9h5pj` (`role_id`),
  KEY `FKdclw9v91w4q8voap572llxar1` (`auth_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;


INSERT INTO `role_auth` VALUES (1,1),(2,3),(2,3),(2,2),(3,3);

         使用的JPA 注解的方式创建的实体,以及添加实体之间的关系,

user用户表

package com.sjy.bean;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;


import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;


@Entity
@Table(name = "USER")
public class User implements UserDetails {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    private Long id;

    @Column(name = "USERNAME", length = 50, unique = true)
    private String username;

    @Column(name = "PASSWORD", length = 100)
    private String password;

    @Column(name = "FIRSTNAME", length = 50)
    private String firstname;

    @Column(name = "LASTNAME", length = 50)
    private String lastname;

    @Column(name = "EMAIL", length = 50)
    private Boolean enabled;

    @Column(name = "LASTPASSWORDRESETDATE")
    @Temporal(TemporalType.TIMESTAMP)
    private Date lastPasswordResetDate;

    //急加载 会查询role表
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(
            name = "USER_ROlE",
            joinColumns = {@JoinColumn(name = "USER_ID", referencedColumnName = "ID")},
            inverseJoinColumns = {@JoinColumn(name = "ROLE_ID", referencedColumnName = "ID")})
    private List roles;

   //属性的get set 方法略················
      //实现UserDetails 重写的方法  
    @Override
    public Collection getAuthorities() {
        // TODO Auto-generated method stub
        List auths = new ArrayList<>();
        List roles = this.getRoles();
        for (Role role : roles) {
            for(Authority aurh:role.getAuthoritys())
            auths.add(new SimpleGrantedAuthority(aurh.getName()));
        }
        return auths;
    }

    @Override
    public boolean isAccountNonExpired() {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public boolean isEnabled() {
        // TODO Auto-generated method stub
        return true;
    }
}

role角色表、

package com.sjy.bean;

import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonIgnore;

@Entity
@Table(name = "role")
public class Role {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    private Long id;
    @Column(length = 25)
    private String name;
     //懒加载 不会查询role表
    @ManyToMany(mappedBy = "roles",fetch = FetchType.LAZY)
    private List users;
     //急加载 会查询role表
    @ManyToMany(mappedBy = "roles",fetch = FetchType.EAGER)
    private List Authoritys;

   //get  set方法略·········
}

authority 权限表

package com.sjy.bean;

import javax.persistence.*;


import java.util.List;

@Entity
@Table(name = "AUTHORITY")
public class Authority {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)//主键自动生成
    @Column(name="ID")
    private Long id;
    
    private String name;
    
    private String url;
    
    private int pid;
    
    private String description;

    @ManyToMany(fetch = FetchType.LAZY)//懒加载   快速查询 不会查询role表  
    @JoinTable(
            name = "ROlE_Auth",
            joinColumns = {@JoinColumn(name = "auth_ID", referencedColumnName = "ID")},
            inverseJoinColumns = {@JoinColumn(name = "ROLE_ID", referencedColumnName = "ID")})
    private List roles;
    
       //get set 略················
}

dao接口

package com.sjy.dao;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import com.sjy.bean.User;

public interface userdao extends JpaRepository {
    
    public User findByUsername(String name);
}

UserDetailsServiceImpl 

             此类 实现  UserDetailsService接口 重写LoadUserUsername方法。

首先在usernamePasswordAuthenticationFilter中来拦截登录请求,并调用AuthenticationManager。AuthenticationManager调用

Provider,provider调用userDetaisService来根据username获取真实的数据库信息。最终验证帐号密码的类是

org.springframework.security.authentication.dao.DaoAuthenticationProvider.。 

          注意的是这里只需要一个根据用户名查询出用户的方法即可,不需要通过用户名和密码去查询。

package com.sjy.security;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.security.core.SpringSecurityMessageSource;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.sjy.bean.User;
import com.sjy.dao.userdao;


@Service
public class UserDetailsServiceImpl implements UserDetailsService  {
    Logger logger = LoggerFactory.getLogger(UserDetailsServiceImpl.class);

    @Autowired
    private userdao userdao;

    
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException  {
        User user = userdao.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("用户不存在");
        }
        System.out.println(user.getAuthorities());
        return user;
    }

}

映射页面(spring MVC config  或者在controller层写映射页面)

package com.sjy.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer  {
     @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            registry.addViewController("/login1").setViewName("login");
            registry.addViewController("/index1").setViewName("index1");
            registry.addViewController("/index2").setViewName("index2");
            registry.addViewController("/index3").setViewName("index3");
            registry.addViewController("/myerror").setViewName("myerror");
            
        }
}

配置Spring Security

package com.sjy.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;

import com.sjy.security.MyPasswordEncoder;
import com.sjy.security.UserDetailsServiceImpl;

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter  {
    @Bean
    UserDetailsService customUserService() {
        return new UserDetailsServiceImpl();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
        .userDetailsService(customUserService()).passwordEncoder(new MyPasswordEncoder());
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
        .anyRequest().authenticated()
        .and().formLogin().loginPage("/login1")
        //设置默认登录成功跳转页面
        .defaultSuccessUrl("/main").failureUrl("/login1?error").permitAll()
        .and()
        .logout()
        //默认注销行为为logout,可以通过下面的方式来修改
        .logoutUrl("/custom-logout")
        //设置注销成功后跳转页面,默认是跳转到登录页面
        .logoutSuccessUrl("/login1")
        .permitAll()
        .and()
        .exceptionHandling()
        .accessDeniedPage("/myerror");//无权访问;
    }
}

MyPasswordEncoder

package com.sjy.security;
import  org.springframework.security.crypto.password.PasswordEncoder;
public class MyPasswordEncoder implements PasswordEncoder {
    @Override
    public String encode(CharSequence arg0) {
        return arg0.toString();
    }
    @Override
    public boolean matches(CharSequence arg0, String arg1) {
        return arg1.equals(arg0.toString());
    }
}

HomeController

package com.sjy.controller;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.sjy.bean.Role;
import com.sjy.bean.User;
import com.sjy.dao.authdao;

@Controller
public class HomeController {
    @Autowired
    private authdao authdao;
    
    @RequestMapping("/main")
    public String main(Model model) {
        User user =getUserDetails();
        Set set = new HashSet();
         List roles = user.getRoles();
         for (Role role : roles) {
             set.addAll(role.getAuthoritys());
        }System.out.println(set);
    model.addAttribute("authorities",set);
        
    return "index";
    }
    private  User getUserDetails() {
        SecurityContext ctx = SecurityContextHolder.getContext();   
        Authentication auth = ctx.getAuthentication();
        return (User)auth.getPrincipal();
    }
}

登录页面

login.html




    
    登录
    



已注销

有错误,请重试

使用账号密码登录

index.html



    
    后台登陆页面


  • 那些好的东西都是你的勒

    myerror.html

    
    
    
    后台登陆页面
    
    
          

    myerror.html

    無權訪問

    Spring Boot + JPA + Spring Security 实现用户权限数据库管理_第3张图片

    Spring Boot + JPA + Spring Security 实现用户权限数据库管理_第4张图片

               

                                                   ok  第一步的  完成登录验证

     

    第二步   权限限制

    获取所有权限

     

    MyInvocationSecurityMetadataSourceService    在项目加载的时候, 获取所有的权限,

    package com.sjy.security;
    
    
    import java.util.ArrayList;
    
    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.access.ConfigAttribute;
    import org.springframework.security.access.SecurityConfig;
    import org.springframework.security.web.FilterInvocation;
    import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
    import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
    import org.springframework.stereotype.Service;
    
    import com.sjy.bean.Authority;
    import com.sjy.dao.authdao;
    
    
    
    
    @Service
    public class MyInvocationSecurityMetadataSourceService implements
            FilterInvocationSecurityMetadataSource{
    
        @Autowired
        private authdao authdao;
        
        private HashMap> map=null;
        
        /*
         * 系统启动后,首次有用户访问,加载权限表中所有权限。以便拦截无权放访问的用户请求。
         *
         * wzh增加了注释描述。
         */
        public void loadResourceDefine(){
            map=new HashMap<>();
            Collection array;
            ConfigAttribute cfg;
            List permissions=authdao.findAll();
            for(Authority permission:permissions){
                array = new ArrayList<>();
                cfg=new SecurityConfig(permission.getName());
                //此处只添加了权限的名字,其实还可以添加更多权限的信息,例如请求方法到ConfigAttribute的集合中去。
                array.add(cfg);
                //用权限的getUrl()作为map的key,用ConfigAttribute的集合作为value
                map.put(permission.getUrl(), array);
            }
        }
        
        /*
         * 此方法是为了判定用户请求的url是否再权限表中,如果在权限表中,则返回给decide方法,
         * 用来判定用户是否有此权限。如果不在权限表中则放行。
         *
         * 方法的目的是:确定该请求是否需要进行访问权限的判断,对于需要判断权限的请求,返回resUrl,对于不需要
         * 进行权限判断的请求,返回Null
         */
         @Override
            public Collection getAttributes(Object object) throws IllegalArgumentException {
                if(map ==null) loadResourceDefine();
                HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
                AntPathRequestMatcher matcher;
                String resUrl;
                for(Iterator iter = map.keySet().iterator(); iter.hasNext(); ) {
                    resUrl = iter.next();
                    //当url里有?的时候  进行切割   
                    if(resUrl.indexOf("?")>-1){
                        resUrl=resUrl.substring(0,resUrl.indexOf("?"));
                    }
                    matcher = new AntPathRequestMatcher(resUrl);
                    if(matcher.matches(request)) {
                        return map.get(resUrl);
                    }
                }
                return null; //
            }
    
            @Override
            public Collection getAllConfigAttributes() {
                return null;
            }
    
            @Override
            public boolean supports(Class clazz) {
                return true;
            }
    }

    MyFilterSecurityInterceptor

    package com.sjy.security;
    
    import java.io.IOException;
    
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.access.SecurityMetadataSource;
    import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
    import org.springframework.security.access.intercept.InterceptorStatusToken;
    import org.springframework.security.web.FilterInvocation;
    import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
    import org.springframework.stereotype.Service;
    
    
    
    @Service
    public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter{
        
        @Autowired
        private FilterInvocationSecurityMetadataSource securityMetadataSource;
    
        @Autowired
        public void setMyAccessDecisionManager(MyAccessDecisionManager myAccessDecisionManager) {
            super.setAccessDecisionManager(myAccessDecisionManager);
        }
    
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
    
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    
            FilterInvocation fi = new FilterInvocation(request, response, chain);
            invoke(fi);
        }
    
        public void invoke(FilterInvocation fi) throws IOException, ServletException {
            //fi里面有一个被拦截的url
            //里面调用MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法获取fi对应的所有权限
            //再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够
            InterceptorStatusToken token = super.beforeInvocation(fi);
            try {
                //执行下一个拦截器
                fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
            } finally {
                super.afterInvocation(token, null);
            }
        }
    
    
        @Override
        public void destroy() {
    
        }
    
        @Override
        public Class getSecureObjectClass() {
            return FilterInvocation.class;
    
        }
    
        @Override
        public SecurityMetadataSource obtainSecurityMetadataSource() {
            return this.securityMetadataSource;
        }
    }

    MyAccessDecisionManager   权限的一个判断

    package com.sjy.security;
    
    import org.springframework.security.access.AccessDeniedException;
    import java.util.Collection;
    import java.util.Iterator;
    
    import org.springframework.security.access.AccessDecisionManager;
    import org.springframework.security.access.ConfigAttribute;
    import org.springframework.security.authentication.InsufficientAuthenticationException;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.stereotype.Service;
    
    
    @Service
    public class MyAccessDecisionManager implements AccessDecisionManager{
    
        //decide 方法是判定是否拥有权限的决策方法
        //authentication是UserDetailsServiceImpl中循环添加到GrantedAuthority 对象中的权限信息集合
        //object包含客户端发起的请求的request信息,可转换为 HttpServletRequest request=((FilterInvocation) object)
        //.getHttpRequest();
        //configAttributes 为MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法返回的结果,
        //此方法是为了判定用户请求的Url 是否在权限表中,如果在权限表中,则返回decide方法,用来判定用户是否由此权限,如果不在权限表中则放行。
    
        @Override
        public void decide(
                Authentication authentication,
                Object object,
                Collection configAttributes)
                        throws AccessDeniedException, InsufficientAuthenticationException {
    
            if(null== configAttributes || configAttributes.size() <=0) {
                return;
                //说明请求的系统中不存在指定的URL,返回执行security配置文件中其他项目。
            }
            ConfigAttribute c;
            String needRole;
            for(Iterator iter = configAttributes.iterator(); iter.hasNext(); ) {
                c = iter.next();
                needRole = c.getAttribute();
                for(GrantedAuthority ga : authentication.getAuthorities()) {
                    
                    
                    if(needRole.trim().equals(ga.getAuthority())) {
                        return;
                    }
                }
            }
            throw new AccessDeniedException(" 没有权限访问! ");
        }
    
    
    
        @Override
        public boolean supports(ConfigAttribute attribute) {
            return true;
        }
    
        @Override
        public boolean supports(Class clazz) {
            return true;
        }
    
    
    }

     

    添加 页面    测试权限使用  index1.html index2.html index3.html

    修改HomeController   获取所有的权限

    package com.sjy.controller;
    
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.context.SecurityContext;
    import org.springframework.security.core.context.SecurityContextHolder;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import com.sjy.bean.Role;
    import com.sjy.bean.User;
    import com.sjy.dao.authdao;
    
    @Controller
    public class HomeController {
        @Autowired
        private authdao authdao;
        
        @RequestMapping("/main")
        public String main(Model model) {
            /*User user =getUserDetails();
            Set set = new HashSet();
             List roles = user.getRoles();
             for (Role role : roles) {
                 set.addAll(role.getAuthoritys());
            }System.out.println(set);*/
            
        model.addAttribute("authorities",authdao.findAll());
            
        return "index";
        }
        private  User getUserDetails() {
            SecurityContext ctx = SecurityContextHolder.getContext();   
            Authentication auth = ctx.getAuthentication();
            return (User)auth.getPrincipal();
        }
    }

    使用sjy用户登录  他有管理  用户 权限的  但是没有  测试的权限 

      获取的所有权限

    当点击测试的时候就跳转到了  myerror.html

    Spring Boot + JPA + Spring Security 实现用户权限数据库管理_第5张图片

    点击管理

    Spring Boot + JPA + Spring Security 实现用户权限数据库管理_第6张图片

    点击用户

    Spring Boot + JPA + Spring Security 实现用户权限数据库管理_第7张图片

     

     

     

    借鉴  

    https://blog.csdn.net/u012373815/article/details/54632176

    https://blog.csdn.net/u012702547/article/details/54319508

     

    感谢感谢

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------更新  :  发现了问题   :

    1.当你登陆之后其实所有的接口都是可以请求的。 ()  在MyInvocationSecurityMetadataSourceService.java  getAttributes方法当你登陆之后  return null  是默认通过的    就是   只要是你数据库没有的接口权限都是给你默认通过的。   反映了    “防君子不妨小人”    将所有的controller的接口映射都放入了数据库。一些公用的接口给定一样的权限

    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    添加qq第三方登录功能2019/3

     

    你可能感兴趣的:(J)