1. 默认数据库认证和授权
1.1 资源准备1.2 资源授权的配置1.3 基于内存的多用户支持1.4 认证和授权
1.4.1 数据库准备1.4.2 编码 2. 自定义数据库模型的认证与授权
2.1 实现UserDetails2.2 数据库以及表准备2.3 实现UserDetailsService2.4 启动程序测试
1. 默认数据库认证和授权 1.1 资源准备首先准备三个不同权限的接口
@GetMapping("/admin/test")
@ResponseBody
public String adminTest() {
return "admin test";
}
@GetMapping("/user/test")
@ResponseBody
public String userTest() {
return "user test";
}
@GetMapping("/web/test")
@ResponseBody
public String webTest() {
return "web test";
}
假设在/admin/test/下的内容是系统后台管理相关的 API,在/web/test下的内容是面向客户端公开访 问的API,在/user/test/下的内容是用户操作自身数据相关的API;显然,/admin/test必须拥有管理员权限才能进行操作,而/user/test必须在用户登录后才能进行操作。
1.2 资源授权的配置
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Slf4j
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/test
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Slf4j
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/test
public class SecurityUser implements UserDetails {
private Integer id;
private String username;
private String password;
private boolean enable;
private List authorityList;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
public List getAuthorityList() {
return authorityList;
}
public void setAuthorityList(List authorityList) {
this.authorityList = authorityList;
}
@Override
public Collection extends GrantedAuthority> getAuthorities() {
return authorityList;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return enable;
}
}
实现UserDetails定义的几个方法:
◎ isAccountNonExpired、isAccountNonLocked 和 isCredentialsNonExpired 暂且用不到,统一返回 true,否则Spring Security会认为账号异常。
◎ isEnabled对应enable字段,将其代入即可。
◎ getAuthorities方法本身对应的是roles字段,但由于结构不一致,所以此处新建一个,并在后续 进行填充。
package com.demo.springSecurityFirstDemo.security;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.demo.springSecurityFirstDemo.model.UserModel;
import com.demo.springSecurityFirstDemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
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;
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserService userService;
@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
System.out.println(userName);
QueryWrapper qw = new QueryWrapper<>();
qw.eq("user_name", userName);
UserModel userModel = userService.getOne(qw);
if (userModel == null) {
throw new UsernameNotFoundException("user not exist!");
}
SecurityUser securityUser = new SecurityUser();
securityUser.setId(userModel.getId());
securityUser.setUsername(userModel.getUserName());
securityUser.setPassword(userModel.getPassword());
securityUser.setAuthorityList(AuthorityUtils.commaSeparatedStringToAuthorityList(userModel.getRoles()));
securityUser.setEnable(userModel.getIsDeleted() == 0);
return securityUser;
}
}
其中AuthorityUtils.commaSeparatedStringToAuthorityList(userModel.getRoles()) 是将逗号拼接的权限字符串,比如:ROLE_USER,ROLE_ADMIN。
SimpleGrantedAuthority是GrantedAuthority的一个实现类。Spring Security的权限几乎是用 SimpleGrantedAuthority生成的,只要注意每种角色对应一个GrantedAuthority即可。另外,一定要在自 己的UserDetailsService实现类上加入@Service注解,以便被Spring Security自动发现。
[WebSecurityConfig.java](http://WebSecurityConfig.java) 完整代码
package com.demo.springSecurityFirstDemo.security;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Slf4j
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/test/**").hasRole("ADMIN")
.antMatchers("/user/test/**").hasRole("USER")
.antMatchers("/web/test/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin();
}
}
2.4 启动程序测试
登录数据库保存的账号密码用户名:user密码:1权限role_user
返回配置的成功页面
然后依次访问不同权限的接口
访问/admin/test
访问/user/test
登录数据库保存的账号密码用户名:admin密码:1权限为role_admin和role_user
访问/admin/test和/user/test/正常。
如果登录不存在的用户测试结果如图。
JVM内存泄漏和内存溢出的原因
JVM常用监控工具解释以及使用
Redis 常见面试题(一)
ClickHouse之MaterializeMySQL引擎(十)
三种实现分布式锁的实现与区别
线程池的理解以及使用
号外!号外!
最近面试BAT,整理一份面试资料,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。想获取吗?如果你想提升自己,并且想和优秀的人一起进步,感兴趣的朋友,可以在扫码关注下方公众号。资料在公众号里静静的躺着呢。。。
喜欢就收藏认同就点赞支持就关注疑问就评论
一键四连,你的offer也四连
————————————————————————————————————————————————————————————————
本文作者:Java技术债务
原文链接:https://www.cuizb.top/myblog/article/1648393808
版权声明: 本博客所有文章除特别声明外,均采用 CC BY 3.0 CN协议进行许可。转载请署名作者且注明文章出处。



