Spring Security中使用注解进行用户授权

Posted 爱上口袋的天空

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Security中使用注解进行用户授权相关的知识,希望对你有一定的参考价值。

1、@Secured

功能:判断是否具有角色,另外需要注意的是这里匹配的字符串需要添加前缀“ROLE_”。

使用@EnableGlobalMethodSecurity(securedEnabled=true)开启该注解功能。

package com.kgf.security;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;

@EnableGlobalMethodSecurity(securedEnabled = true)
@MapperScan(value = "com.kgf.security.mapper")
@SpringBootApplication
public class SecurityApplication {

    public static void main(String[] args) {

        SpringApplication.run(SecurityApplication.class,args);

    }

}

在控制器方法上添加注解@Secured

package com.kgf.security.controller;

import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("test")
@RestController
public class TestController {


    @RequestMapping("hello")
    public String test(){
        return "hello security";
    }

    @RequestMapping("index")
    public String index(){
        return "hello index";
    }
    @RequestMapping("unauth")
    public String unauth(){
        return "unauth";
    }

    @GetMapping("update")
    @Secured({"ROLE_sale","ROLE_manager"})
    public String update() {
        return "hello update";
    }

}

设置数据库查询的角色:

package com.kgf.security.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kgf.security.mapper.UsersMapper;
import com.kgf.security.model.Users;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
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 javax.annotation.Resource;
import java.util.List;

/***
 * spring security查询用户的时候会自动到这个类中去查找
 */
@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {

    @Resource
    private UsersMapper usersMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        QueryWrapper<Users> usersQueryWrapper = new QueryWrapper<>();
        usersQueryWrapper.eq("username",username);
        Users users = usersMapper.selectOne(usersQueryWrapper);
        if (users==null){
            throw new UsernameNotFoundException("用户名不存在!");
        }
        //这里我们就不去查询数据库了,直接new一个对象
        List<GrantedAuthority> authorityList = AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_sale");
        return new User(username,users.getPassword(),authorityList);
    }
}

测试:

2、@PreAuthorize

功能:注解适合进入方法前的权限验证,@PreAuthorize可以将登录用户的roles/permissions参数传到方法中。

示例:
先开启注解功能:

package com.kgf.security;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;

@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
@MapperScan(value = "com.kgf.security.mapper")
@SpringBootApplication
public class SecurityApplication {

    public static void main(String[] args) {

        SpringApplication.run(SecurityApplication.class,args);

    }

}

控制器中加入注解:

 设置数据库查询的角色:

package com.kgf.security.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kgf.security.mapper.UsersMapper;
import com.kgf.security.model.Users;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
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 javax.annotation.Resource;
import java.util.List;

/***
 * spring security查询用户的时候会自动到这个类中去查找
 */
@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {

    @Resource
    private UsersMapper usersMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        QueryWrapper<Users> usersQueryWrapper = new QueryWrapper<>();
        usersQueryWrapper.eq("username",username);
        Users users = usersMapper.selectOne(usersQueryWrapper);
        if (users==null){
            throw new UsernameNotFoundException("用户名不存在!");
        }
        //这里我们就不去查询数据库了,直接new一个对象
        List<GrantedAuthority> authorityList = AuthorityUtils.commaSeparatedStringToAuthorityList("manager");
        return new User(username,users.getPassword(),authorityList);
    }
}

测试:

修改 数据库查询的角色:

 

 

3、@PostAuthorize

功能:在方法执行之后再进行权限验证,适合验证带有返回值的权限。

用法与上面相同。

4、@PostFilter

功能:权限验证之后对返回的数据进行过滤。

示例:
控制器中加入以下代码

 修改 数据库查询的角色:

 测试:

 

5、@PreFilter

功能:进入控制器之前对传入方法的数据进行过滤。

用法与上面相同。

以上是关于Spring Security中使用注解进行用户授权的主要内容,如果未能解决你的问题,请参考以下文章

如何在单元测试中针对 Spring Security 对用户进行身份验证

Spring Security 权限管理

Spring Security 权限管理

Spring Security应用开发(21)基于方法的授权使用@Secured注解

Spring Security 中的权限注解很神奇吗?

五 spring security 其他权限检验及自定义校验方法