springboot使用springsecurity进行自定义权限路径配置

使用场景

用户访问不同路径需要不同的权限。

1.实现用户对应权限

package com.mt.config;

import com.mt.service.impl.AuthPathServiceImpl;
import com.mt.service.impl.UserDetailsServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import java.util.Map;

/**
 * 项目安全访问权限配置
 */

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    private final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
    @Autowired
    private UserDetailsServiceImpl userDetailsService;
    @Autowired
    private AuthPathServiceImpl authPathService;

	//swagger地址不被拦截配置
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring()
                .antMatchers("/swagger-ui.html")
                .antMatchers("/v2/**")
                .antMatchers("/swagger-resources/**");
    }
	//自定义权限加载
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        logger.info("自定义权限配置加载..");
        //获取对应权限的正则匹配值 例如:/admin/\w*
        Map<String,String> regex = authPathService.getRoleAuthPath();
http
                .authorizeRequests().regexMatchers(regex.get("4")==null?"":regex.get("4")).hasAnyRole("USER","ADMIN","COMMON","ROOT")
                .and()
                .authorizeRequests().regexMatchers(regex.get("3")==null?"":regex.get("3")).hasAnyRole("USER","ADMIN","ROOT")
                .and()
                .authorizeRequests().regexMatchers(regex.get("2")==null?"":regex.get("2")).hasAnyRole("ADMIN","ROOT")
                .and()
                .authorizeRequests().regexMatchers(regex.get("1")==null?"":regex.get("1")).hasRole("ROOT")
                .and()
                .authorizeRequests()
                .antMatchers("/").permitAll()
                .and()
                .httpBasic()
                .and()
                .logout()
                .permitAll();
                http.csrf().disable(); //取消csrf防护
    }
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        //basic auth 基本权限认证,也可注释
        auth
            .inMemoryAuthentication()
            .passwordEncoder(new BCryptPasswordEncoder()).withUser("admin").password(new BCryptPasswordEncoder().encode("admin")).roles("ADMIN")
            .and()
            .passwordEncoder(new BCryptPasswordEncoder()).withUser("user").password(new BCryptPasswordEncoder().encode("user")).roles("USER")
            .and()
            .passwordEncoder(new BCryptPasswordEncoder()).withUser("common").password(new BCryptPasswordEncoder().encode("common")).roles("COMMON");


        // 数据库账号密码认证
        // 密码需要设置编码器
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        auth.userDetailsService(userDetailsService).passwordEncoder(encoder);
    }
}

package com.mt.service.impl;

import com.mt.bean.Authority;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户权限识别与认证
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Autowired
    private UserServiceImpl userService;
    @Autowired
    private AuthorityServiceImpl authorityService;
    /**
 	* 通过业务方法获取用户权限信息
 	*/
    @Override
    public UserDetails loadUserByUsername(String id) throws UsernameNotFoundException {
        //获取用户信息
        com.mt.bean.User user=userService.userGetByPhone(id);
        //获取用户权限
        List<Authority> authorities = authorityService.getCustomerAuthority(String.valueOf(user.getUserId()));
        // 对用户权限进行封装
        List<SimpleGrantedAuthority> list = authorities.stream()
                .map(authority -> new SimpleGrantedAuthority(authority.getAuthority()))
                .collect(Collectors.toList());
        // 返回封装的UserDetails用户详情类
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        return new User(String.valueOf(user.getUserId()), encoder.encode(user.getUserPwd()), list);
    }
}

用户权限表

package com.mt.bean;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import javax.persistence.Table;
/**
 * 用户权限
 */
@Data
@Accessors(chain=true)
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Table(name = "authority_user")
public class AuthorityUser {
        private String id;
        private Integer userId;
        private String authorityId ;
        private String valid;
}

权限角色表

package com.mt.bean;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import javax.persistence.Table;

/**
 * 权限角色表
 */
@Data
@Accessors(chain=true)
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Table(name = "authority")
public class Authority {
    private String id;
    private String authority ;
    private String valid;
}
package com.mt.bean;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.springframework.data.annotation.Id;

import javax.persistence.Table;
import java.io.Serializable;

/**
 * 用户表
 */
@Data
@Accessors(chain=true)
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Table(name="user")
public class User implements Serializable {

	private Integer userId;
	private String userName;
	private String userPhone;
	private int userAge;
	private String userSex;
	private String userPwd;
}
package com.mt.service.impl;

import com.mt.bean.Authority;
import com.mt.bean.AuthorityUser;
import com.mt.mapper.AuthorityMapper;
import com.mt.mapper.AuthorityUserMapper;
import com.mt.service.AuthorityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 权限用户
 */
@Service
public class AuthorityServiceImpl implements AuthorityService {
    @Autowired
    private AuthorityMapper authorityMapper;
    @Autowired
    private AuthorityUserMapper authorityUserMapper;
    @Override
    public List<Authority> getCustomerAuthority(String id) {
        List<AuthorityUser> authUerRole = authorityUserMapper.getAuthUserRole(id);
        List<Authority> authorities=new ArrayList<>();
        authUerRole.forEach(authorityUser -> {
            List<Authority> customerAuthority = authorityMapper.getCustomerAuthority(authorityUser.getAuthorityId());
            authorities.addAll(customerAuthority);
        });
        return authorities;

    }
}

2.实现不同的路径需要不同权限

权限路径表

package com.mt.bean;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import javax.persistence.Table;
import java.io.Serializable;

/**
 * 权限路径表
 */
@Data
@Accessors(chain=true)
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Table(name="auth_path")
public class AuthPath {
    private Integer id;
    private String authPath;
    private String valid;
    private String authorityId;
}
package com.mt.service.impl;

import com.mt.bean.AuthPath;
import com.mt.mapper.AuthPathMapper;
import com.mt.service.AuthPathService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 权限处理
 */
@Service
public class AuthPathServiceImpl implements AuthPathService {
    @Autowired
    private AuthPathMapper authPathMapper;
    @Override
    public Map<String,String> getRoleAuthPath() {
        //获取所有权限路径,将其安装权限类型分组,再根据key排序
        List<AuthPath> authPaths = authPathMapper.selectAll();
        //过滤出生效的数据
        authPaths=authPaths.stream().filter(authPath -> "0".equals(authPath.getValid())).collect(Collectors.toList());
        //将其按照id成map
        Map<String, List<AuthPath>> authPathMap = authPaths.stream().collect(Collectors.groupingBy(AuthPath::getAuthorityId));
        Map<String, List<AuthPath>> result = new LinkedHashMap<>(authPathMap.size());
        //将其按照id排序
        authPathMap.entrySet().stream().sorted(Map.Entry.comparingByKey()).forEachOrdered(e -> result.put(e.getKey(), e.getValue()));
        //将获取到的多个组合成一个正则,加上()即可
        Map<String,String> stringBuilderMap= new HashMap<>();
        result.forEach((k,v)->{
            StringBuilder str = new StringBuilder();
            for (AuthPath authPath : v) {
                if(!"".equals(str.toString())){
                    str.append("|");
                }
                str.append("(").append(authPath.getAuthPath()).append(")");
            }
            stringBuilderMap.put(k,str.toString());
        });
        return stringBuilderMap;
    }
}

3.实现用户登录刷新权限

	@Autowired
    private SecurityAuthUtil securityAuthUtil;
    
	@ApiOperation("用户登录")
    @PostMapping("/login")
    public User userLogin(HttpServletRequest request,String phone, String password, HttpSession session,HttpServletResponse response) throws Exception {
        User user = userService.userLogin(phone, password);
        if (user != null) {        
            //在session中存放security context,方便同一个session中控制用户的其他操作
            session.setAttribute("SPRING_SECURITY_CONTEXT",securityAuthUtil.auth(request,user.getUserPhone()));
            session.setAttribute("user", user);
            LOGGER.info(user.getUserName() + "登录成功.." + "账号:" + user.getUserPhone() + " 密码:" + user.getUserPwd());
        }
        return user;
    }
package com.mt.util;

import com.mt.service.impl.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 *
 * 登录权限管理工具
 */
@Component
public class SecurityAuthUtil {
    @Autowired
    private UserDetailsServiceImpl userDetailsService;
    public Object auth(HttpServletRequest request,String id){
        //根据用户名username加载userDetails
        UserDetails userDetails = this.userDetailsService.loadUserByUsername(id);
        //根据userDetails构建新的Authentication,这里使用了
        //PreAuthenticatedAuthenticationToken当然可以用其他token,如UsernamePasswordAuthenticationToken
        PreAuthenticatedAuthenticationToken authentication =
                new PreAuthenticatedAuthenticationToken(userDetails, userDetails.getPassword(),userDetails.getAuthorities());
        //设置authentication中details
                authentication.setDetails(new WebAuthenticationDetails(request));
        //存放authentication到SecurityContextHolder
        SecurityContextHolder.getContext().setAuthentication(authentication);
        return SecurityContextHolder.getContext();
    }
    public void cancelAuth(){
        SecurityContextHolder.clearContext();
    }
}

4.用户登出删除权限

	@Autowired
    private SecurityAuthUtil securityAuthUtil;
    
 	@ApiOperation("用户登出")
    @GetMapping("/loginOut")
    public int userLoginOut(HttpSession session) {
        User user = (User) session.getAttribute("user");
        if (session.getAttribute("user") != null) {
            session.removeAttribute("user");
            session.invalidate();
            securityAuthUtil.cancelAuth();
            LOGGER.info(user.getUserName()+"登出成功..");
            return 1;
        } else {
            return 0;
        }
    }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot中集成Spring Security后,可以通过以下步骤使用Spring Security进行鉴权: 1. 添加依赖:在pom.xml文件中添加Spring Security的依赖。 ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> ``` 2. 创建配置类:创建一个继承自`WebSecurityConfigurerAdapter`的配置类,并重写`configure`方法。 ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/public/**").permitAll() .anyRequest().authenticated() .and() .formLogin() .and() .logout().permitAll(); } } ``` 上述配置中的`http.authorizeRequests()`用于配置URL的访问权限,`.antMatchers("/public/**").permitAll()`表示`/public/`路径下的所有资源允许无需身份认证即可访问,`.anyRequest().authenticated()`表示其他路径需要进行身份认证后才能访问。`.formLogin()`用于启用默认的登录表单,`.logout().permitAll()`用于启用默认的退出登录功能。 3. 配置用户信息:可以在配置类中通过重写`configure`方法,设置一个内存中的用户存储,或者自定义用户认证逻辑。 ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user") .password("{noop}password") .roles("USER"); } // 其他配置... } ``` 上述配置中的`auth.inMemoryAuthentication()`用于创建一个基于内存的用户存储,`.withUser("user").password("{noop}password").roles("USER")`表示创建一个用户名为"user",密码为"password",角色为"USER"的用户。`{noop}`表示使用明文密码进行匹配,这里仅作示例,实际生产环境中应使用加密后的密码。 以上是使用Spring Security进行鉴权的基本步骤,具体的配置还可以根据实际需求进行调整和扩展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值