springsecurity-用户授权
springsecurity的第一道防线是 用户认证,即需要查看用户是否符合系统中合法的用户,而第二道防线呢就是我们的用户授权,即使用户认证通过了,如果对访问的URL没有相应的权限,也是访问不了。
如果我们想要给用户进行授权或者赋予某个角色,可参考下面的代码:
@Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { QueryWrapper<Users> wrapper = new QueryWrapper<>(); wrapper.eq("username", username); Users users = usersMapper.selectOne(wrapper); if(users == null){ throw new UsernameNotFoundException("用户不存在"); } List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("role","ROLE_r1"); return new User(users.getUsername(), new BCryptPasswordEncoder().encode(users.getPassword()),auths); } }
最主要就是AuthorityUtils.commaSeparatedStringToAuthorityList("role","ROLE_r1");
现在那如何给资源URL赋予权限呢,参考如下:
protected void configure(HttpSecurity http) throws Exception { http.formLogin() .loginPage("/login.html") //设置我们自己的登录页面的路径 .loginProcessingUrl("/user/login") //设置表单提交到的路径,这个路径必须和表单的一致,因为一致,springsecurity才处理 .defaultSuccessUrl("/user/index") //校验或认证成功后跳转的路径,也就是这个是真正的controller接口的路径 .and().authorizeRequests().antMatchers("/user/test","/login.html").permitAll() //允许指定的路径 不需要不认证;这个固定的写法 .antMatchers("/user/index").hasAuthority("role") //当要访问/user/index的用户,必须拥有role权限 .anyRequest().authenticated() //所有的请求都需要认证,除了上面指定过不需要认证的除外 .and().csrf().disable(); //关闭csrf功能 }
最重要的就是.antMatchers("/user/index").hasAuthority("role") 这行代码,他的意思是:访问/user/index的用户需要具有role权限;但代码是这样的:.antMatchers("/user/index").hasAuthority("role1",“role2”),也就是说用户必须要有role1,role2两个权限才能访问。
(一般用户是先认证 再 查看 是否对应的权限。有时候这里会出现一个问题,比如访问/user/index,那我们会重定向到/login.html,但是重定向的这个请求也会被拦截去认证,因此会出现死循环,因此一定要对登录页面进行放行,即不认证登录页面)
如果我们希望访问的资源URL只需要其中一个权限就能访问,那还有一个方法,如下:
.antMatchers("/user/index").hasAnyAuthority("role","role2")
只要拥有role或者role2其中一个权限即可。
除了赋予权限外,还能赋予角色。
给用户赋予角色,代码如下:
@Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { QueryWrapper<Users> wrapper = new QueryWrapper<>(); wrapper.eq("username", username); Users users = usersMapper.selectOne(wrapper); if(users == null){ throw new UsernameNotFoundException("用户不存在"); } List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("role","ROLE_sal"); return new User(users.getUsername(), new BCryptPasswordEncoder().encode(users.getPassword()),auths); } }
如果是赋予角色,那前缀必须是ROLE_ ,不然就不是角色,而是权限。
对应的,如果访问的资源URL需要某个或某些角色才能访问,也有两个方法,看方法名也能猜到:
.antMatchers("/user/index").hasRole("sal")
.antMatchers("/user/index").hasAnyRole("sal,doctor")
在赋予用户角色时需要加前缀ROLE_,但在资源URL这里就不需要加前缀。