在之前,对springsecurity进行了一个简单介绍,并且上手了一个简单demo。这里是链接,需要的可以去看一下 如何给用户分配权限?这篇文章主要为大家介绍一下,基于springSecurity对于角色和用户一些简单的权限判断。

角色判断:

首先必须去定义角色,且定义角色时,开头必须为ROLE_  这样子才能够被security识别为角色 ;

return new User(username,password, AuthorityUtils.commaSeparatedStringToAuthorityList("admin,normal,ROLE_abc")); //标准写法必须加role  定义角色

其次,当定义使用角色时,是严格区分大小写的 ,必须和定义的相同

.antMatchers("/main1.html").hasRole("abc") //单个角色
.antMatchers("/main1.html").hasAnyRole("abc","abC") //定义多个角色 

ip地址判断

在实际开发中,后台管理系统可能会用到ip地址判断,是这个ip地址访问才能通过 。也就是说 只能通过这个ip地址来对后台进行操作。

这里首先查询了我的电脑的ip,然后设置才行。

.antMatchers("/ip.html").hasIpAddress("192.168.153.1")

403页面配置

当权限达不到时,会报403错误。为了用户访问方便 这个页面可以自己配置来 。编写一个类去继承AccessDeniedHandler类,且重写hadle方法。

@Component
public class MyAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        response.setHeader("ContentType","application/json;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.write("{\"status\":\"error\",\"msg\":\"Insufficient permissions!\"}");
        writer.flush(); // 发出消息
        writer.close(); //关闭
    }
}

编写好类后,我们就可以去配置类中去进行引用。需要注意的是在类中@Component注解必须加上。

@Autowired
private MyAccessDeniedHandler myAccessDeniedHandler;

http.exceptionHandling()
      .accessDeniedHandler(myAccessDeniedHandler);

重新运行,发现权限不够 访问不了。这就是一个简单的处理,在开发中,应该会有一个对应的界面显示。

基于表达式的访问控制

前面介绍的用户登录权限判断等问题,看源码实际上都是调用access。

 public AuthorizationManagerRequestMatcherRegistry hasRole(String role) {
   return access(AuthorityAuthorizationManager.hasRole(role));
  }

...
     public AuthorizationManagerRequestMatcherRegistry hasRole(String role) {
   return access(AuthorityAuthorizationManager.hasRole(role));
  }

我们也可以直接使用access方法:作用基本相同

.antMatchers("/login.html","/404.html").access("permitAll()") 
.antMatchers("/login.html","/404.html ").permitAll()

如果说验证方法都是去调用access,呢能不能自己去定义一个access呢 ?

这里我们去写个判断用户权限,能否去访问某个页面 。

去定义接口和去写实现类,这里就不展示接口了。

@Service
public class MyserviceImpl implements Myservice{

    @Override
    public boolean hasPermission(HttpServletRequest httpServletRequest, Authentication authentication) {

        Object object = authentication.getPrincipal();  //获取主题
        if (object instanceof UserDetails){
            UserDetails userDetails = (UserDetails) object;
            Collection<? extends GrantedAuthority> authorities = userDetails.getAuthorities();  //拿到权限
//            判断权限是否包含url
            return authorities.contains(new SimpleGrantedAuthority(httpServletRequest.getRequestURI()));
        }
        return false;
    }
//配置类
.anyRequest().access("@myserviceImpl.hasPermission(httpServletRequest,authentication)");

基于注解的访问控制

在SpringSecurity中提供了一些访问控制的注解,这些都是默认不能用的,需要在启动类中进行开启才能使用。如果不开启则会报500

下面为大家介绍一下@secured,这个注解一般使用在Controller上

源码为:

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Secured {

 /**
  * Returns the list of security configuration attributes (e.g.&nbsp;ROLE_USER,
  * ROLE_ADMIN).
  * @return String[] The secure method attributes
  */
 String[] value();

}

首先在配置类中去启动基于注解的访问配置

@EnableGlobalMethodSecurity(securedEnabled = true)

在控制层去使用,需要注意的是 角色必须以ROLE_开头

    @Secured("ROLE_ABC")
    @RequestMapping("/toMain")
    public String toMain(){
        System.out.println("执行登录方法");
        return "redirect:main.html"; 
    }

当无权限访问时:

除@secured,还有其他注解@PostAuthorize:该注解使用不多,在方法执行后再进行权限验证。适合验证带有返回值的权限。如果方法没有返回值实际上等于开放权限控制;如果有返回值实际的结果是用户操作成功但是得不到响应。

@PreFilter:对集合类型的参数执行过滤,移除结果为false的元素。基于方法入参相关的表达式,对入参进行过滤。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐