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

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

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

 添加依赖

 依赖pom.xml

<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-jdbc</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-web</artifactId>
           </dependency>
           <dependency>
                 <groupId>mysql</groupId>
                 <artifactId>mysql-connector-java</artifactId>
                 <scope>runtime</scope>
           </dependency>
           <dependency>
                 <groupId>org.springframework.security</groupId>
                 <artifactId>spring-security-test</artifactId>
                 <scope>test</scope>
           </dependency>
           <dependency>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-devtools</artifactId>
                 <optional>true</optional> <!-- 这个需要为 true 热部署才有效  当修改后台文件保存的时候  自动重启项目-->
           </dependency>
      </dependencies>

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 存储在权限表中,其中用户 、角色 多对多关系, 角色 、权限也是多对多关系

 

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,'admin@admin.com',b'1','admin',NULL,'admin','123','sjy'),(2,'enabled@user.com',b'1','user',NULL,'user','123','user'),(3,'disabled@user.com',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<Role> roles;

   //属性的get set 方法略················
      //实现UserDetails 重写的方法  
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        // TODO Auto-generated method stub
        List<GrantedAuthority> auths = new ArrayList<>();
        List<Role> 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<User> users;
     //急加载 会查询role表
    @ManyToMany(mappedBy = "roles",fetch = FetchType.EAGER)
    private List<Authority> 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<Role> 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<User, Long> {
    
    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<Role> 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

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>登录</title>
    <style type="text/css">
        body {
            padding-top: 50px;
        }
        .starter-template {
            padding: 40px 15px;
            text-align: center;
        }
    </style>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
    <div class="container">
        <div class="navbar-header">
            <a class="navbar-brand" href="#">Spring Security演示</a>
        </div>
        <div id="navbar" class="collapse navbar-collapse">
            <ul class="nav navbar-nav">
                <li><a th:href="@{/}">首页</a></li>
                <li><a th:href="@{http://www.baidu.com}">百度</a></li>
            </ul>
        </div>
    </div>
</nav>
<div class="container">
    <div class="starter-template">
        <p th:if="${param.logout}" class="bg-warning">已注销</p>
        <p th:if="${param.error}" class="bg-danger">有错误,请重试</p>
        <h2>使用账号密码登录</h2>
        <form  th:action="@{/login1}" method="post">
            <div class="form-group">
                <label for="username">账号</label>
                <input type="text"  name="username" value="sjy"  placeholder="账号"/>
            </div>
            <div class="form-group">
                <label for="password">密码</label>
                <input type="password" name="password"  placeholder="密码"/>
            </div>
            <input type="submit" value="登陆"/>
        </form>
        <form th:action="@{/custom-logout}" method="post">
        <input type="submit" value="退出">
        </form>
    </div>
</div>
</body>
</html>

index.html

<html >
<head>
    <meta charset="utf-8">
    <title>后台登陆页面</title>
</head>
<body >
<li th:each="authority:${authorities}"  class="tpl-left-nav-item">
<a th:href="${authority.url}"  th:text="${authority.description}"></a>
</li>
          <h3>那些好的东西都是你的勒</h3>
          <form th:action="@{/custom-logout}" method="post">
        <input type="submit" value="退出">
        </form>
</body>
</html>
    

myerror.html

<html>
<head>
<meta charset="utf-8">
<title>后台登陆页面</title>
</head>
<body>
      <h1>myerror.html</h1>
      <h3>無權訪問</h3>
      <form th:action="@{/custom-logout}" method="post">
           <input type="submit" value="退出">
      </form>
</body>
</html>

           

                                               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<String , Collection<ConfigAttribute>> map=null;
    
    /*
     * 系统启动后,首次有用户访问,加载权限表中所有权限。以便拦截无权放访问的用户请求。
     *
     * wzh增加了注释描述。
     */
    public void loadResourceDefine(){
        map=new HashMap<>();
        Collection<ConfigAttribute> array;
        ConfigAttribute cfg;
        List<Authority> 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<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
            if(map ==null) loadResourceDefine();
            HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
            AntPathRequestMatcher matcher;
            String resUrl;
            for(Iterator<String> 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<ConfigAttribute> 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<ConfigAttribute> configAttributes)
                    throws AccessDeniedException, InsufficientAuthenticationException {

        if(null== configAttributes || configAttributes.size() <=0) {
            return;
            //说明请求的系统中不存在指定的URL,返回执行security配置文件中其他项目。
        }
        ConfigAttribute c;
        String needRole;
        for(Iterator<ConfigAttribute> 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<Role> 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

点击管理

点击用户

 

 

地址

https://gitee.com/shijingyangman/Spring-Security

借鉴  

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

 

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值