springboot+security restful权限控制官方推荐
Posted 双斜杠少年
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot+security restful权限控制官方推荐相关的知识,希望对你有一定的参考价值。
继前几篇博客将用户、角色、权限信息都存在数据,实现管理权限到请求方法级别。感觉那种实现方式比较鸡肋,不太实用。所以今天说一下,官方推荐的注解方式控制权限到请求方法级别的实现。
官方推荐的方法是将用户、角色信息存在数据库,而角色和权限的对应关系,通过注解的方式写死在controller上。
废话不多说,上代码;
本文代码是基于博客 springboot+mybatis+SpringSecurity 实现用户角色数据库管理(一)
的代码修改而来
1. 数据库设计
insert into SYS_USER (id,username, password) values (1,'admin', '$2a$10$YwbP2rm18bOWOrkJHybp5uTRHCpn5Rk8rGT6fogf0KdtNY7jzmebu');
insert into SYS_USER (id,username, password) values (2,'abel', '$2a$10$/h0hVDo3A78lEHhsIckGz.nfXGgUFx2yB4bfy6o15RZi8VlZqt.PK');
insert into SYS_ROLE(id,name) values(1,'ROLE_ADMIN');
insert into SYS_ROLE(id,name) values(2,'ROLE_USER');
2. 修改WebSecurityConfig 文件
此处使用了 BCryptPasswordEncoder 密码加密
使用了httpBasic 认证 : springSecurity 之 http Basic认证 (四)
package com.us.example.config;
import com.us.example.security.CustomUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
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.crypto.bcrypt.BCryptPasswordEncoder;
/**
* Created by yangyibo on 17/1/18.
*/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)// 控制权限注解
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
@Autowired
private CustomUserService customUserService;
@Autowired
protected void configure(AuthenticationManagerBuilder auth) throws Exception
auth.userDetailsService(customUserService).passwordEncoder(new BCryptPasswordEncoder());
@Override
protected void configure(HttpSecurity http) throws Exception
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/users/**")
.authenticated()
.antMatchers(HttpMethod.POST)
.authenticated()
.antMatchers(HttpMethod.PUT)
.authenticated()
.antMatchers(HttpMethod.DELETE)
.authenticated()
.antMatchers("/**")
.permitAll()
.and()
.sessionManagement()
.and()
.httpBasic();
3. 修改SysUser 类实现 UserDetails接口
package com.us.example.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.List;
/**
* Created by yangyibo on 17/1/17.
*/
public class SysUser implements UserDetails // implements UserDetails 用于登录时 @AuthenticationPrincipal 标签取值
private Integer id;
private String username;
@JsonIgnore
private String password;
private String rawPassword;
@JsonIgnore
private List<SysRole> roles;
private List<? extends GrantedAuthority> authorities;
public Integer getId()
return id;
public void setId(Integer id)
this.id = id;
public String getUsername()
return username;
public void setUsername(String username)
this.username = username;
public String getPassword()
return password;
public void setPassword(String password)
this.password = password;
public List<SysRole> getRoles()
return roles;
public void setRoles(List<SysRole> roles)
this.roles = roles;
public String getRawPassword()
return rawPassword;
public void setRawPassword(String rawPassword)
this.rawPassword = rawPassword;
@JsonIgnore
@Override
public boolean isAccountNonExpired()
return true;
@JsonIgnore
@Override
public boolean isAccountNonLocked()
return true;
@JsonIgnore
@Override
public boolean isCredentialsNonExpired()
return true;
@JsonIgnore
@Override
public boolean isEnabled()
return true;
@JsonIgnore
@Override
public Collection<? extends GrantedAuthority> getAuthorities()
return authorities;
public void setGrantedAuthorities(List<? extends GrantedAuthority> authorities)
this.authorities = authorities;
4. 修改 CustomUserService 类
package com.us.example.security;
import com.us.example.dao.UserDao;
import com.us.example.domain.SysRole;
import com.us.example.domain.SysUser;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
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 java.util.ArrayList;
import java.util.List;
/**
* Created by yangyibo on 17/1/18.
*/
@Service
public class CustomUserService implements UserDetailsService //自定义UserDetailsService 接口
@Autowired
UserDao userDao;
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(CustomUserService.class);
@Override
public UserDetails loadUserByUsername(String username) //重写loadUserByUsername 方法获得 userdetails 类型用户
SysUser user = userDao.findByUserName(username);
if(user == null)
throw new UsernameNotFoundException("用户名不存在");
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
//用于添加用户的权限。只要把用户权限添加到authorities 就万事大吉。
for(SysRole role:user.getRoles())
authorities.add(new SimpleGrantedAuthority(role.getName()));
logger.info("loadUserByUsername: " + user);
user.setGrantedAuthorities(authorities); //用于登录时 @AuthenticationPrincipal 标签取值
return user;
5. 添加登录controller
新建LoginController
package com.us.example.controller;
import com.us.example.domain.SysUser;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by yangyibo on 17/3/1.
*/
@RestController
public class LoginController
@RequestMapping(value = "/login")
@ResponseBody
public Object login(@AuthenticationPrincipal SysUser loginedUser, @RequestParam(name = "logout", required = false) String logout)
if (logout != null)
return null;
if (loginedUser != null)
return loginedUser;
return null;
6. 修改 HomeController 添加权限控制
package com.us.example.controller;
import com.us.example.domain.SysUser;
import com.us.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* Created by yangyibo on 17/1/18.
*/
@Controller
@RequestMapping("/users")
public class HomeController
@Autowired
UserService userService;
@RequestMapping(method = RequestMethod.GET)
@ResponseBody
public String getUsers()
return "getUsers";
@Secured("ROLE_ADMIN","ROLE_USER")//此方法只允许 ROLE_ADMIN 和ROLE_USER 角色 访问
@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public Object save(@RequestBody SysUser user)
return userService.create(user);
@Secured("ROLE_ADMIN")//此方法只允许 ROLE_ADMIN 角色访问
@RequestMapping(method = RequestMethod.PUT)
@ResponseBody
public String update()
return "updateUser";
@Secured("ROLE_ADMIN")//此方法只允许 ROLE_ADMIN 角色访问
@RequestMapping(method = RequestMethod.DELETE)
@ResponseBody
public String delete()
return "deleteUser";
7. 测试
使用admin 登录
关于登录方式请移步: springSecurity 之 http Basic认证 (四)
可以访问 /users 路径下的get、post、put、delete 四个请求方法
使用abel 登录
可以访问 /users 路径下的get、post 两个请求方法
访问 put、delete 方法会抛403 没有权限异常
本文源码:https://github.com/527515025/springBoot
以上是关于springboot+security restful权限控制官方推荐的主要内容,如果未能解决你的问题,请参考以下文章
直接使用security.basic.path无效|——springboot2.0以上的security的配置