探索如何通过跨平台小程序实现小游戏盒子的快速开发与灵活应对市场需求
491
2023-06-17
springsecurity轻松实现角色权限的示例代码
问题:
如何在springboot项目中使用springsecurity去实现角色权限管理呢?本文将尽可能简单的一步步实现对接口的角色权限管理。
项目框架:
sql:
user表:
CREATE TABLE `user` (
`Id` int NOT NULL AUTO_INCREMENT,
`UserName` varchar(255) NOT NULL,
`CreatedDT` datetime DEFAULT NULL,
`Age` int DEFAULT NULL,
`Gender` int DEFAULT NULL,
`Password` varchar(255) NOT NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
role表:
CREATE TABLE `role` (
`Id` int NOT NULL AUTO_INCREMENT,
`UserId` int DEFAULT NULL,
`Role` varchar(255) DEFAULT NULL,
`CreatedDT` datetime DEFAULT NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
maven:
在pom.xml中加入
model:
实体类User要实现springsecurity的基本接口UserDetails,UserDetails里继承了Serializable,不用担心序列化
@Data
public class User implements UserDetails {
public User() {
}
private static final long serialVersionUID = 1L;
private Integer id;
private String userName;
private Date createdDT;
private Integer age;
private Integer gender;
private String passWord;
private String role;
private List
public User(String userName, String passWord, List
this.userName = userName;
this.passWord = passWord;
this.authorities = authorities;
}
@Override
public Collection extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return this.passWord;
}
@Override
public String getUsername() {
return this.userName;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return troslqySTLue;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
实体类role:
@Data
public class Role implements Serializable {
private Integer id;
private String role;
private Date createdDT;
private Integer userId;
}
mapper:
@Mapper
public interface UserMapper{
User selectOneByNaoslqySTLme(User user);
}
service:
public interface UserService{
User selectOneByName(User user) throws ServiceException;
}
serviceImpl:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper mapper;
@Override
public User selectOneByName(User user) throws ServiceException {
return mapper.selectOneByName(user);
}
}
mapper.xml:
Id, UserName, CreatedDT, Age, Gender,Password
SELECT u.*,r.role FROM `user` u LEFT JOIN role r on u.Id = r.UserId
where u.UserName = #{userName,jdbcType=VARCHAR}
config:
首先实现UserDetailsService类。自定义获取用户信息和角色信息。
@Component
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserService userService;
@Autowired
private HttpServletRequest request;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 通过用户名从数据库获取用户信息
User user = userService.selectOneByName(new User(){
{
setUserName(username);
}
});
if (user == null) {
throw new UsernameNotFoundException("用户不存在");
}
HttpSession session = request.getSession();
session.setAttribute(session.getId(),user);
// 得到用户角色
String role = user.getRole();
// 角色集合
List
// 角色必须以`ROLE_`开头,数据库中没有,则在这里加
authorities.add(new SimpleGrantedAuthority("ROLE_" + role));
return new User(
user.getUsername(),
user.getPassword(),
authorities
);
}
}
自定义错误提示
@Component
public class MyAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
response.getWriter().println("{'code':'403','message':'没有访问权限'}");
response.getWriter().flush();
}
}
终于来到security的配置了
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService userDatailService;
@Autowired
private MyAccessDeniedHandler accessDeniedHandler;
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDatailService)
.passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers().frameOptions().disable()
.and()
.authorizeRequests()
.antMatchers("不限制访问的路径,如:'/user/*'").permitAll()
.antMatchers("用户拥有规定角色才允许访问的路径,如:'/user/delte'").hasRole("admin")
.antMatchers("规定ip才允许访问的路径,如:'/*'").hasIpAddress("192.168.1.1/24");
.anyRequest().authenticated() // 所有请求都需要验证
.and()
// 跳转自定义成功页
.formLogin().defaultSuccessUrl("/html/index.html")
.and()
.exceptionHandling()
//用户无权限访问链接,给出友好提示
.accessDeniedHandler(accessDeniedHandler)
.and()
.csrf().disable();// post请求要关闭csrf验证,不然访问报错;实际开发中要开启。
}
}
至此,springsecurity的角色权限管理就完成了,如果想要实现方法级的角色权限限制,可以在方法前加入 @PreAuthorize("hasRole('角色')")注解,多个角色可以使用hasAnyRole(),就可以限制拥有规定角色权限的用户才能访问了。
@PreAuthorize("hasRole('admin')")
@RequestMapping(value = "/delete")
public CommonResult delete(@RequestBody int id) {
int i = userService.delete(new User() {
{
setId(id);
}
});
return i > 0 ? processSuccess("删除成功") : processFailure("删除失败");
}
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~