springsecurity轻松实现角色权限的示例代码

网友投稿 491 2023-06-17

springsecurity轻松实现角色权限的示例代码

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中加入

org.projectlombok

lombok

true

org.springframework.boot

spring-boot-starter-security

cn.hutool

hutool-all

4.5.7

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 authorities;

public User(String userName, String passWord, List authorities) {

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 authorities = new ArrayList<>();

// 角色必须以`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小时内删除侵权内容。

上一篇:SpringBoot2线程池定义使用方法解析
下一篇:SpringBoot Shiro配置自定义密码加密器代码实例
相关文章

 发表评论

暂时没有评论,来抢沙发吧~