通过配置文件配置:
spring.security.user.password=123
spring.security.user.name=javaboy
spring.security.user.roles=admin
通过配置类配置:
手工配置用户名密码:
写一个配置类,继承WebSecurityConfigurerAdapter接口,重写configure方法
密码需要加密
通过HttpSecurity配置:
配置HttpSecurity:
重写configure(HttpSecurity http)方法
.anyRequest().authenticated() => 剩下其他请求都是登录后才能访问
.loginProcessingUrl(“/doLogin”) 处理登录的接口
.loginPage(“/login”) 这个是登录页面,可以自己配登录页面
.usernameParameter(“…”) 修改请求路径的username参数名?
.passwordParameter(“…”) 修改请求路径的password参数名?
登录表单的配置: .formLogin()
.successHandler() 登录成功的处理,这个用于返回json
authentication表示登录成功的对象
用法:
.failureHandler() 登录失败的处理,用于返回json
用法:
注销配置:
多个HttpSecurity配置:
密码加密:
方法安全:
// 配置文件添加这个注解
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)
public class MultiHttpSecurityConfig {}
// 在需要添加权限的方法上,加上@PreAuthorize或者@Secured注解
@Service
public class MethodService {
@PreAuthorize("hasRole('admin')")
public String admin() {
return "hello admin";
}
@Secured("ROLE_user")
public String user() {
return "hello user";
}
@PreAuthorize("hasAnyRole('admin','user')")
public String hello() {
return "hello hello";
}
}
基于数据库使用spring security
如果需要从数据库加载用户,在定义用户实体类User时,要实现一个UserDetails接口,并重写七个方法
getUsername:返回用户名
isAccountNonExpired:账户是否未过期
isAccountNonLocked:账户是否没有被锁定
isCredentialsNonExpired:密码是否未过期
isEnabled:是否可用
getAuthorities:返回用户的所有角色
getPassword:返回密码
UserService执行登录的逻辑,也要实现UserDetailsService,实现loadUserByUsername方法
loadUserByUsername(String username):根据用户名查询用户,参数是用户名
@Service
public class UserService implements UserDetailsService {
@Autowired
UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userMapper.loadUserByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("用户不存在!");
}
user.setRoles(userMapper.getUserRolesById(user.getId()));
return user;
}
}
只用根据用户名查询用户,至于密码不用查,spring security会帮你比较。查到就返回,查不到就抛异常
角色继承关系:
在配置类写一个方法:
@Bean
RoleHierarchy roleHierarchy() {
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
String hierarchy = "ROLE_dba > ROLE_admin \n ROLE_admin > ROLE_user";
roleHierarchy.setHierarchy(hierarchy);
return roleHierarchy;
}
实现动态权限配置
角色有哪些权限=>用户有哪些角色=>进而确定用户能操作哪些资源
你要访问哪个资源(也是数据库里),需要查询数据库的角色
首先:
1、实现FilterInvocationSecurityMetadataSource接口,实现它的三个方法:
1.1、getAttributes:根据请求的地址分析,访问该地址需要哪些角色。
匹配上了返回角色,如果没匹配上返回一个默认的值
AntPathMatcher:路径匹配符
:pathMatcher.match(规则,请求地址)
2、根据用户,拿出来具有的角色,比较是否满足条件
实现AccessDecisionManager接口,实现它的方法
2.1、decide:
decide(Authentication authentication, Object o, Collection<ConfigAttribute> collection)
authentication:当前登录用户的信息
o:获取当前请求对象
collection:getAttributes的返回值,返回的是角色信息
OAuth2
OAuth2开发的标准,允许第三方访问在网站上存储的私密资源(图片,照片等)。
如:网易云登录,允许微信,QQ
资源所有者:
客户端:网易云音乐