SpringSecurity開啟注解權限


1.@EnableGlobalMethodSecurity 注解介紹

Spring Security默認是在配置類中使用URL進行攔截,禁用使用注解,想要開啟注解使用則需要在配置類上加上 如下注解@EnableGlobalMethodSecurity

注解源碼如下,共支持 prePostEnabled, securedEnabled,jsr250Enabled,proxyTargetClass 四種參數;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({GlobalMethodSecuritySelector.class})
@EnableGlobalAuthentication
@Configuration
public @interface EnableGlobalMethodSecurity {
    boolean prePostEnabled() default false;

    boolean securedEnabled() default false;

    boolean jsr250Enabled() default false;

    boolean proxyTargetClass() default false;

    AdviceMode mode() default AdviceMode.PROXY;

    int order() default 2147483647;
}

在Spring Security 2.0 開始 支持 JSR-250 注釋 以及框架的原始@Secured注釋;

2.@Secured注解使用方式

需要在配置類加上 @EnableGlobalMethodSecurity(securedEnabled = true) 表明使用 @Secured 注解;

配置示例如下

/**
 * @Author lsc
 * <p> </p>
 */
@EnableWebSecurity// 開啟springSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


     //.....略



}

注解使用示例如下,該注解只能使用在方法上面

    @GetMapping("test/seu")
    @Secured("ROLE_USER")
    public String testSecurity() {
        return "需要USER權限";
    }

測試結果如下

@Secured 源碼如下

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Secured {
    String[] value();
}

該注解可以使用多個角色進行控制

@Secured({"ROLE_USER","ROLE_ADMIN"})

3.JSR-250注解

JSR-250 注釋 使用需要在配置類上加上 @EnableGlobalMethodSecurity(jsr250Enabled = true) ; 配置示例如下:

@EnableWebSecurity// 開啟springSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
	  //.....略
}
  • @RolesAllowed 允許的角色;
  • @PermitAll 允許任何人訪問
  • @DenyAll 拒絕任何人訪問

使用方式如下;

@RolesAllowed({"USER","ADMIN"}) 表示 只有 USER, ADMIN 角色權限才可以訪問;

	@GetMapping("test/allow")
    @RolesAllowed({"USER","ADMIN"})
    public String testAllow() {
        return "需要權限";
    }

    @GetMapping("test/perm")
    @PermitAll
    public String testPerm() {
        return "允許";
    }

    @GetMapping("test/deny")
    @DenyAll
    public String testDeny() {
        return "拒絕";
    }

4.prePostEnabled 規范

prePostEnabled 沒有 原生的spring注解功能強大,所以其使用需要借助spring的EL表達式;

需要在配置類上加上 @EnableGlobalMethodSecurity(prePostEnabled = true) 注解

配置示例

@EnableWebSecurity// 開啟springSecurity
//@EnableGlobalMethodSecurity(securedEnabled = true)
//@EnableGlobalMethodSecurity(jsr250Enabled = true)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
	//.....略
}

主要注解如下

  • @PreAuthorize --方法之前驗證授權
  • @PostAuthorize --授權方法之后被執行
  • @PostFilter --在方法執行之后執行,用於過濾集合;
  • @PreFilter --在方法執行之前執行,用於過濾集合;

注解使用方式

    @GetMapping("api/admin")
    @PreAuthorize("hasRole('ADMIN')")
    public String authAdmin() {
        return "需要ADMIN權限";
    }

    @GetMapping("api/test")
    @PreAuthorize("isAnonymous()")
    public String authUser() {
        return "匿名用戶訪問";
    }

以及 hasAuthority 使用方式如下

@PreAuthorize("hasAuthority('ROLE_ADMIN')")

使用EL表達式判定方式如下

	@GetMapping("api/has")
    @PreAuthorize("#sysUser.username == 'admin' ")
    public String hasPerm(SysUser sysUser) {
        return "EL測試";
    }

還可以使用 @P 注解獲取參數

 	@GetMapping("api/sys")
    @PreAuthorize("#c.username == authentication.principal ")
    public String hasPerm2(@P("c")SysUser sysUser) {
        return "EL測試";
    }

如果是Spring Data的@Param注解

@PreAuthorize("#n == authentication.principal")
public String hasPerm2(@Param("n")SysUser sysUser) {
        return "EL測試";
 }

5 權限被拒絕處理器

如果當用戶訪問自身不具有的權限接口時,springSecurity 會將異常信息傳遞給 AccessDeniedHandler ;我們只需要實現它即可;示例如下

/**
 * @author lsc
 * <p> 權限不足處理 </p>
 */
@Component
public class DenyHandler implements AccessDeniedHandler {

    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
        // 設置響應頭
        httpServletResponse.setContentType("application/json;charset=utf-8");
        // 返回值
        ResultPage result = ResultPage.error(CodeMsg.PERM_ERROR);
        httpServletResponse.getWriter().write(JSON.toJSONString(result));
    }
}

6 常見內置表達式

表達 描述
hasRole([role]) 如果當前主體具有指定角色,則返回true。默認情況下,如果提供的角色不以“ROLE_”開頭,則會添加該角色。這可以通過修改DefaultWebSecurityExpressionHandler上的defaultRolePrefix來自定義。
hasAnyRole([role1,role2]) 如果當前主體具有任何提供的角色(以逗號分隔的字符串列表給出),則返回true。默認情況下,如果提供的角色不以“ROLE_”開頭,則會添加該角色。這可以通過修改DefaultWebSecurityExpressionHandler上的defaultRolePrefix來自定義。
hasAuthority([authority]) 如果當前主體具有指定的權限,則返回true
hasAnyAuthority([authority1,authority2]) 如果當前主體具有任何提供的權限(以逗號分隔的字符串列表給出),則返回true
principal 允許直接訪問代表當前用戶的主體對象
authentication 允許直接訪問從SecurityContext獲取的當前Authentication對象
permitAll 始終評估為true
denyAll 始終評估為false
isAnonymous() 如果當前主體是匿名用戶,則返回true
isRememberMe() 如果當前主體是remember-me用戶,則返回true
isAuthenticated() 如果用戶不是匿名用戶,則返回true
isFullyAuthenticated() 如果用戶不是匿名用戶或記住我用戶,則返回true
hasPermission(Object target, Object permission) 如果用戶有權訪問給定權限的提供目標,則返回true。例如,hasPermission(domainObject, 'read')
hasPermission(Object targetId, String targetType, Object permission) 如果用戶有權訪問給定權限的提供目標,則返回true。例如,hasPermission(1, 'com.example.domain.Message', 'read')

本套教程

源碼地址: 關注公眾號知識追尋者,后台回復:springSecurity 獲取


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM