内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

springsecurity中的權(quán)限控制是什么意思

本篇內(nèi)容主要講解“spring security中的權(quán)限控制是什么意思”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“spring security中的權(quán)限控制是什么意思”吧!

創(chuàng)新互聯(lián)公司主要從事網(wǎng)站制作、做網(wǎng)站、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)潁東,十多年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專(zhuān)業(yè),歡迎來(lái)電咨詢(xún)建站服務(wù):13518219792

當(dāng)我們?cè)贠Auth登陸后,獲取了登陸的令牌,使用該令牌,我們就有了訪(fǎng)問(wèn)一些受OAuth保護(hù)的接口的能力。具體可以看本人的這兩篇博客OAuth3.0用戶(hù)名,密碼登錄解析 OAuth3.0通過(guò)token獲取受保護(hù)資源的解析

但現(xiàn)在我們要區(qū)分這些登陸人員的具體分工,哪些接口歸哪些登陸人員可以訪(fǎng)問(wèn),這就要用到了spring security中的權(quán)限控制。

首先我們需要有一個(gè)權(quán)限的對(duì)象

/** * 權(quán)限標(biāo)識(shí) */@Datapublic class SysPermission implements Serializable {   private static final long serialVersionUID = 280565233032255804L;   private Long id; //權(quán)限id   private String permission; //具體的權(quán)限   private String name; //權(quán)限名稱(chēng)   private Date createTime;   private Date updateTime;}

對(duì)應(yīng)于數(shù)據(jù)庫(kù)中的權(quán)限表

spring security中的權(quán)限控制是什么意思

那么問(wèn)題來(lái)了,我們要對(duì)權(quán)限進(jìn)行管理需要什么樣的權(quán)限呢,當(dāng)然我們需要權(quán)限管理權(quán)限,這是在系統(tǒng)一開(kāi)始建立的時(shí)候保存進(jìn)數(shù)據(jù)庫(kù)的

spring security中的權(quán)限控制是什么意思

這四個(gè)權(quán)限并不是通過(guò)前端寫(xiě)入的。

現(xiàn)在我們需要通過(guò)前端接口增加其他的權(quán)限就需要使用到這四個(gè)權(quán)限之一。

在這里我們給出一些權(quán)限的增刪改查的mybatis dao

@Mapperpublic interface SysPermissionDao {   @Options(useGeneratedKeys = true, keyProperty = "id")   @Insert("insert into sys_permission(permission, name, createTime, updateTime) values(#{permission}, #{name}, #{createTime}, #{createTime})")   int save(SysPermission sysPermission);   @Update("update sys_permission t set t.name = #{name}, t.permission = #{permission}, t.updateTime = #{updateTime} where t.id = #{id}")   int update(SysPermission sysPermission);   @Delete("delete from sys_permission where id = #{id}")   int delete(Long id);   @Select("select * from sys_permission t where t.id = #{id}")
   SysPermission findById(Long id);   @Select("select * from sys_permission t where t.permission = #{permission}")
   SysPermission findByPermission(String permission);   int count(Map<String, Object> params);   List<SysPermission> findData(Map<String, Object> params);}

現(xiàn)在我們要在Controller中增加一個(gè)新的權(quán)限

/** * 管理后臺(tái)添加權(quán)限 * 
 * @param sysPermission * @return */@LogAnnotation(module = LogModule.ADD_PERMISSION)@PreAuthorize("hasAuthority('back:permission:save')")@PostMapping("/permissions")public SysPermission save(@RequestBody SysPermission sysPermission) {   if (StringUtils.isBlank(sysPermission.getPermission())) {      throw new IllegalArgumentException("權(quán)限標(biāo)識(shí)不能為空");   }   if (StringUtils.isBlank(sysPermission.getName())) {      throw new IllegalArgumentException("權(quán)限名不能為空");   }   sysPermissionService.save(sysPermission);   return sysPermission;}

我們可以看到這個(gè)標(biāo)簽@PreAuthorize("hasAuthority('back:permission:save')"),首先我們是通過(guò)access_token令牌訪(fǎng)問(wèn)的該接口,系統(tǒng)可以知道登陸的是哪一個(gè)用戶(hù),以此看看該用戶(hù)是否有back:permission:save的訪(fǎng)問(wèn)權(quán)限

我們來(lái)看看用戶(hù)角色

@Datapublic class SysRole implements Serializable {   private static final long serialVersionUID = -2054359538140713354L;   private Long id; //角色id   private String code; //角色編碼   private String name; //角色名稱(chēng)   private Date createTime;   private Date updateTime;}

對(duì)應(yīng)數(shù)據(jù)庫(kù)中的表結(jié)構(gòu)如下

spring security中的權(quán)限控制是什么意思

spring security中的權(quán)限控制是什么意思

并給定一個(gè)管理員角色

spring security中的權(quán)限控制是什么意思

該角色對(duì)應(yīng)于哪些權(quán)限,這里可以看到是所有權(quán)限

而我們的用戶(hù)是哪個(gè)角色呢

spring security中的權(quán)限控制是什么意思

我們可以看到這里有兩個(gè)用戶(hù),他們都屬于管理員角色

如果我們現(xiàn)在用其中的一個(gè)用戶(hù)登陸,并獲取該用戶(hù)的信息如下

{

"code"  :    200  ,

"data"  : {

"access_token"  :    "aaf4cd90-497e-4c33-adde-b580ab0f0c65"  ,

"user"  : {

"accountNonExpired"  :    true  ,

"accountNonLocked"  :    true  ,

"authorities"  : [

{

"authority"  :    "back:menu:set2role"

},

{

"authority"  :    "mail:update"

},

{

"authority"  :    "back:permission:delete"

},

{

"authority"  :    "role:permission:byroleid"

},

{

"authority"  :    "back:menu:save"

},

{

"authority"  :    "back:menu:query"

},

{

"authority"  :    "ip:black:query"

},

{

"authority"  :    "ip:black:save"

},

{

"authority"  :    "file:del"

},

{

"authority"  :    "ip:black:delete"

},

{

"authority"  :    "mail:query"

},

{

"authority"  :    "back:user:query"

},

{

"authority"  :    "back:role:permission:set"

},

{

"authority"  :    "sms:query"

},

{

"authority"  :    "back:role:query"

},

{

"authority"  :    "back:permission:query"

},

{

"authority"  :    "back:user:role:set"

},

{

"authority"  :    "back:role:save"

},

{

"authority"  :    "log:query"

},

{

"authority"  :    "file:query"

},

{

"authority"  :    "back:menu:update"

},

{

"authority"  :    "back:role:update"

},

{

"authority"  :    "back:role:delete"

},

{

"authority"  :    "back:user:password"

},

{

"authority"  :    "ROLE_SUPER_ADMIN"

},

{

"authority"  :    "back:menu:delete"

},

{

"authority"  :    "back:user:update"

},

{

"authority"  :    "menu:byroleid"

},

{

"authority"  :    "mail:save"

},

{

"authority"  :    "user:role:byuid"

},

{

"authority"  :    "back:permission:save"

},

{

"authority"  :    "back:permission:update"

}

],

"createTime"  :    "2018-01-17T16:56:59.000+0800"  ,

"credentialsNonExpired"  :    true  ,

"enabled"  :    true  ,

"headImgUrl"  :    ""  ,

"id"  :    1  ,

"nickname"  :    "測(cè)試1"  ,

"password"  :    "$2a$10$QpeXBJpWYetNwfWEHnkvLeK0jS0P9R6V8QqCj37zeNGroqYvdvW.C"  ,

"permissions"  : [

"back:menu:set2role"  ,

"mail:update"  ,

"back:permission:delete"  ,

"role:permission:byroleid"  ,

"back:menu:save"  ,

"back:menu:query"  ,

"ip:black:query"  ,

"ip:black:save"  ,

"file:del"  ,

"ip:black:delete"  ,

"mail:query"  ,

"back:user:query"  ,

"back:role:permission:set"  ,

"sms:query"  ,

"back:role:query"  ,

"back:permission:query"  ,

"back:user:role:set"  ,

"back:role:save"  ,

"log:query"  ,

"file:query"  ,

"back:menu:update"  ,

"back:role:update"  ,

"back:role:delete"  ,

"back:user:password"  ,

"back:menu:delete"  ,

"back:user:update"  ,

"menu:byroleid"  ,

"mail:save"  ,

"user:role:byuid"  ,

"back:permission:save"  ,

"back:permission:update"

],

"phone"  :    ""  ,

"sex"  :    1  ,

"sysRoles"  : [

{

"code"  :    "SUPER_ADMIN"  ,

"createTime"  :    "2018-01-19T20:32:16.000+0800"  ,

"id"  :    1  ,

"name"  :    "超級(jí)管理員"  ,

"updateTime"  :    "2018-01-19T20:32:18.000+0800"

}

],

"type"  :    "APP"  ,

"updateTime"  :    "2018-01-17T16:57:01.000+0800"  ,

"username"  :    "admin"

}

},

"msg"  :    "操作成功"

}

通過(guò)返回的信息我們可以看到他的權(quán)限,跟  @PreAuthorize(  "hasAuthority('back:permission:save')")比對(duì),我們知道登陸用戶(hù)擁有該權(quán)限??梢栽L(fǎng)問(wèn)該接口。

上面都是前菜,下面進(jìn)入正題。

我們來(lái)看一下  @PreAuthorize  標(biāo)簽的源碼,它位于org.springframework.security.access.prepost包下

/**
 * 用于指定將計(jì)算為的方法訪(fǎng)問(wèn)控制表達(dá)式的批注
 * 決定是否允許方法調(diào)用。
 * * @author Luke Taylor * @since 3.0 */@Target({ ElementType.METHOD, ElementType.TYPE })@Retention(RetentionPolicy.RUNTIME)@Inherited@Documentedpublic @interface PreAuthorize {   /**    * @return 在執(zhí)行這個(gè)受保護(hù)的方法前進(jìn)行Spring EL表達(dá)式的解析    */   String value();}

這里有一個(gè)Spring EL表達(dá)式都解析,我們來(lái)看一下什么是Spring EL表達(dá)式

public class SpringELTest {public static void main(String[] args) {
        ExpressionParser parser = new SpelExpressionParser();        //解析字符串,該字符串具有一段代碼的味道        Expression expression = parser.parseExpression("'Hello World'.bytes.length");        int length = (int)expression.getValue();        System.out.println(length);    }
}

這個(gè)"'Hello World'.bytes.length"就是一段Spring EL表達(dá)式,雖然是一段字符串,但它有一段代碼的含義,可以被解析執(zhí)行

運(yùn)行結(jié)果

11

那么很明顯"hasAuthority('back:permission:save')"就是一段Spring EL表達(dá)式,它是可以被執(zhí)行的。

要想使標(biāo)簽@PreAuthorize生效,我們需要設(shè)置一下OAuth的資源服務(wù)設(shè)置

/** * 資源服務(wù)配置 */@EnableResourceServer@EnableWebSecurity@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)public class ResourceServerConfig extends ResourceServerConfigurerAdapter {   @Override   public void configure(HttpSecurity http) throws Exception {
      http.csrf().disable().exceptionHandling()
            .authenticationEntryPoint(
                  (request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
            .and().authorizeRequests().antMatchers(PermitAllUrl.permitAllUrl("/users-anon/**", "/sys/login","/wechat/**")).permitAll()
            .anyRequest().authenticated().and().httpBasic();   }   @Override   public void configure(ResourceServerSecurityConfigurer resource) throws Exception {      //這里把自定義異常加進(jìn)去      resource.authenticationEntryPoint(new AuthExceptionEntryPoint())
            .accessDeniedHandler(new CustomAccessDeniedHandler());   }   @Bean   public BCryptPasswordEncoder bCryptPasswordEncoder() {      return new BCryptPasswordEncoder();   }

}

其中@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)就是打開(kāi)@PreAuthorize進(jìn)行攔截生效的標(biāo)簽,當(dāng)然一定要設(shè)置prePostEnabled = true。

既然"hasAuthority('back:permission:save')"是一段Spring EL表達(dá)式,那么hasAuthority()就一定是一個(gè)可以執(zhí)行的方法,該方法位于SecurityExpressionRoot類(lèi)下,該類(lèi)位于org.springframework.security.access.expression包中。

Spring Security可用表達(dá)式對(duì)象的基類(lèi)就是SecurityExpressionRoot,它支持很多的方法

表達(dá)式

描述

hasRole([role])

當(dāng)前用戶(hù)是否擁有指定角色。

hasAnyRole([role1,role2])

多個(gè)角色是一個(gè)以逗號(hào)進(jìn)行分隔的字符串。如果當(dāng)前用戶(hù)擁有指定角色中的任意一個(gè)則返回true。

hasAuthority([auth])

等同于hasRole

hasAnyAuthority([auth2,auth3])

等同于hasAnyRole

Principle

代表當(dāng)前用戶(hù)的principle對(duì)象

authentication

直接從SecurityContext獲取的當(dāng)前Authentication對(duì)象

permitAll

總是返回true,表示允許所有的

denyAll

總是返回false,表示拒絕所有的

isAnonymous()

當(dāng)前用戶(hù)是否是一個(gè)匿名用戶(hù)

isRememberMe()

表示當(dāng)前用戶(hù)是否是通過(guò)Remember-Me自動(dòng)登錄的

isAuthenticated()

表示當(dāng)前用戶(hù)是否已經(jīng)登錄認(rèn)證成功了。

isFullyAuthenticated()

如果當(dāng)前用戶(hù)既不是一個(gè)匿名用戶(hù),同時(shí)又不是通過(guò)Remember-Me自動(dòng)登錄的,則返回true。

我們具體看一下hasAuthority這個(gè)方法的實(shí)現(xiàn),只有當(dāng)這個(gè)方法返回的結(jié)果為true的時(shí)候,我們才能進(jìn)一步訪(fǎng)問(wèn)我們的接口代碼

這里面?zhèn)魅氲腶uthority為"back:permission:save"

public final boolean hasAuthority(String authority) {   return hasAnyAuthority(authority);}
public final boolean hasAnyAuthority(String... authorities) {   return hasAnyAuthorityName(null, authorities);}
private boolean hasAnyAuthorityName(String prefix, String... roles) {
   //獲取所有的用戶(hù)角色權(quán)限
   Set<String> roleSet = getAuthoritySet();   //由于我們這里傳入的roles只有"back:permission:save"
   //所以role即為"back:permission:save",prefix則為null   for (String role : roles) {
      //defaultedRole依然為"back:permission:save"  String defaultedRole = getRoleWithDefaultPrefix(prefix, role);
      //在權(quán)限集合中是否包含"back:permission:save"的該權(quán)限
      //根據(jù)我們之前登錄的返回信息,可以看到"authority": "back:permission:save"的存在
      //所以此處是可以通過(guò)權(quán)限驗(yàn)證的。  if (roleSet.contains(defaultedRole)) {         return true;      }
   }   return false;}
private Set<String> getAuthoritySet() {
   //Set<String> roles是SecurityExpressionRoot的屬性   //我們可以看到它是從一系列用戶(hù)認(rèn)證里面獲取到的權(quán)限集合   if (roles == null) {      roles = new HashSet<>();
      //authentication是SecurityExpressionRoot極為重要的一個(gè)屬性,它本身是一個(gè)接口
      //管理著用戶(hù)認(rèn)證信息的各個(gè)方法      Collection<? extends GrantedAuthority> userAuthorities = authentication            .getAuthorities();      if (roleHierarchy != null) {
         userAuthorities = roleHierarchy               .getReachableGrantedAuthorities(userAuthorities);      }
            roles = AuthorityUtils.authorityListToSet(userAuthorities);   }   return roles;}
private static String getRoleWithDefaultPrefix(String defaultRolePrefix, String role) {   if (role == null) {      return role;   }
   //由于defaultRolePrefix為null,所以此處返回的就是"back:permission:save"
   if (defaultRolePrefix == null || defaultRolePrefix.length() == 0) {      return role;   }   if (role.startsWith(defaultRolePrefix)) {      return role;   }   return defaultRolePrefix + role;}

我們可以看一下AuthorityUtils.authorityListToSet()方法

public static Set<String> authorityListToSet(
      Collection<? extends GrantedAuthority> userAuthorities) {
   Set<String> set = new HashSet<>(userAuthorities.size());   //很明顯這里是把認(rèn)證用戶(hù)的所有權(quán)限給轉(zhuǎn)化為Set集合   for (GrantedAuthority authority : userAuthorities) {
      set.add(authority.getAuthority());   }   return set;}

到此,相信大家對(duì)“spring security中的權(quán)限控制是什么意思”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢(xún),關(guān)注我們,繼續(xù)學(xué)習(xí)!

名稱(chēng)欄目:springsecurity中的權(quán)限控制是什么意思
瀏覽路徑:http://www.rwnh.cn/article28/ipcecp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作關(guān)鍵詞優(yōu)化、網(wǎng)站改版、標(biāo)簽優(yōu)化、商城網(wǎng)站網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

綿陽(yáng)服務(wù)器托管
安乡县| 溧阳市| 额济纳旗| 上饶市| 万源市| 德兴市| 喀喇沁旗| 西平县| 庆元县| 通渭县| 吐鲁番市| 衡水市| 涿鹿县| 修水县| 咸宁市| 乐昌市| 徐州市| 泰州市| 海兴县| 大兴区| 内黄县| 庆城县| 中超| 巫山县| 遂川县| 南投县| 大荔县| 隆昌县| 自贡市| 揭西县| 深州市| 兰西县| 井冈山市| 恭城| 永康市| 京山县| 凤山县| 高密市| 河南省| 墨竹工卡县| 南漳县|