溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

SpringCloud的spring-security怎么配置

發(fā)布時間:2021-12-29 09:39:41 來源:億速云 閱讀:180 作者:iii 欄目:軟件技術(shù)

這篇文章主要講解了“SpringCloud的spring-security怎么配置”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“SpringCloud的spring-security怎么配置”吧!

一、簡介

Web應(yīng)用的安全管理,主要包括兩個方面的內(nèi)容:身份認證、用戶授權(quán),此處使用spring-cloud-security來說明。

二、依賴管理

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<dependency>
   <groupId>org.thymeleaf.extras</groupId>
   <artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>

三、安全策略配置

Spring Security已經(jīng)大體實現(xiàn)了,我們這里只是需要一些配置與引用。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

package com.example.demo.config;

 

import com.example.demo.utils.security.CustomUserService;

import com.example.demo.utils.security.LoginSuccessHandler;

import com.example.demo.utils.security.MyFilterSecurityInterceptor;

import com.example.demo.utils.security.SecuritySettings;

import org.apache.commons.lang3.StringUtils;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;

import org.springframework.security.config.annotation.web.builders.WebSecurity;

import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

import org.springframework.security.core.userdetails.UserDetailsService;

import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;

import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;

 

/**

 * Security安全配置

 *

 * @Author: 我愛大金子

 * @Description: Security安全配置

 * @Date: Create in 15:20 2017/7/5

 */

@Configuration

@EnableWebSecurity

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

 

    @Autowired

    private CustomFilterSecurityInterceptor customFilterSecurityInterceptor;    // 權(quán)限管理過濾器

    @Autowired

    private SecuritySettings securitySettings;     // 自定義安全配置類

 

    /**注冊UserDetailsService的bean*/

    @Bean

    public UserDetailsService customUserService(){

        return new CustomUserService();

    }

 

    /**登錄認證*/

    @Override

    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.userDetailsService(customUserService()); //userDetailsService驗證

 

    }

 

    /***設(shè)置不攔截規(guī)則*/

    @Override

    public void configure(WebSecurity web) throws Exception {

        web.ignoring().antMatchers("/js/**""/css/**""/images/**""/druid/**");

    }

 

    /**安全策略配置*/

    @Override

    protected void configure(HttpSecurity http) throws Exception {

        // 設(shè)置游客可以訪問的URI

        if (StringUtils.isNotBlank(securitySettings.getPermitall())) {

            http.authorizeRequests().antMatchers(securitySettings.getPermitall().split(",")).permitAll();

        }

 

        http.authorizeRequests()

                .anyRequest().authenticated() //任何請求,登錄后可以訪問

                // 配置登錄URI、登錄失敗跳轉(zhuǎn)URI與登錄成功后默認跳轉(zhuǎn)URI

                .and().formLogin().loginPage("/login").failureUrl("/login?error").permitAll().defaultSuccessUrl("/"true).successHandler(loginSuccessHandler())

                // 注銷行為任意訪問

                .and().logout().permitAll()

                // 設(shè)置拒絕訪問的提示URI

                .and().exceptionHandling().accessDeniedPage("/login?illegal")

        ;

 

        http.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class);

    }

 

    /**登錄成功處理器*/

    private AuthenticationSuccessHandler loginSuccessHandler() {

        return new LoginSuccessHandler();

    }

}

說明:

 loginPage:設(shè)置一個實驗自定義的登錄URI

 loginSuccessHandler:設(shè)置自定義的登錄處理器

 permitAll:是允許訪問

 accessDeniedPage:配置拒絕訪問的提示URI

 antMatchers:對URI的配置

了解springcloud架構(gòu)可以加求求:三五三六二四七二五九

假設(shè)我要管理員才可以訪問admin文件夾下的內(nèi)容,如:.antMatchers("/admin/**").hasRole("ROLE_ADMIN"),

也可以設(shè)置admin文件夾下的文件可以有多個角色來訪問,如:.antMatchers("/admin/**").hasAnyRole("ROLE_ADMIN","ROLE_USER")

也可以通過hasIpAddress來指定某一個ip可以訪問該資源,寫法如下.antMatchers("/admin/**").hasIpAddress("210.210.210.210") 

3.1、自定義安全配置類 

為是更方便的使用springSecurity,我們自定義一個權(quán)限的配置類,如配置登錄的URI、游客訪問的URI等配置項

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

package com.example.demo.utils.security;

 

import org.springframework.boot.context.properties.ConfigurationProperties;

import org.springframework.context.annotation.Configuration;

 

/**

 * 自定義安全配置類

 *

 * @Author: 我愛大金子

 * @Description: 自定義安全配置類

 * @Date: Create in 9:45 2017/7/6

 */

@Configuration

@ConfigurationProperties(prefix = "securityConfig")

public class SecuritySettings {

    /**允許訪問的URL,多個用逗號分隔*/

    private String permitall;

 

    public String getPermitall() {

        return permitall;

    }

 

    public void setPermitall(String permitall) {

        this.permitall = permitall;

    }

}

3.2、登錄成功處理器

登錄成功后,如果需要對用戶的行為做一些記錄或者執(zhí)行其它操作,則可以使用登錄成功處理器。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

package com.example.demo.utils.security;

 

import com.example.demo.pojo.SysUser;

import org.springframework.security.core.Authentication;

import org.springframework.security.core.userdetails.User;

import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

 

/**

 * 登錄成功處理器

 *

 * @Author: 我愛大金子

 * @Description: 登錄成功處理器

 * @Date: Create in 11:35 2017/7/6

 */

public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {

    @Override

    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException {

        User userDetails = (User) authentication.getPrincipal();

        System.out.println("登錄用戶:username=" + userDetails.getUsername() + ", uri=" + request.getContextPath());

        super.onAuthenticationSuccess(request, response, authentication);

    }

}

3.3、springMVC 配置(訪問 /login 轉(zhuǎn)向 login.html 頁面)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

package com.example.demo.config;

 

import org.springframework.context.annotation.Configuration;

import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

 

/**

 * springMVC 配置(注冊訪問 /login 轉(zhuǎn)向 login.html 頁面)

 *

 * @Author: 我愛大金子

 * @Description: springMVC 配置(注冊訪問 /login 轉(zhuǎn)向 login.html 頁面)

 * @Date: Create in 16:24 2017/7/5

 */

@Configuration

public class WebMvcConfig extends WebMvcConfigurerAdapter {

 

    @Override

    public void addViewControllers(ViewControllerRegistry registry) {

        registry.addViewController("/login").setViewName("login");

    }

}

四、登錄認證

在安全策略配置代碼中有,主要看自定義的CustomUserService,此類實現(xiàn)了UserDetailsService接口,重寫了loadUserByUsername方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

package com.example.demo.utils.security;

 

import com.example.demo.dao.SysPermissionDao;

import com.example.demo.dao.SysUserDao;

import com.example.demo.pojo.SysPermission;

import org.springframework.security.core.userdetails.User;

import com.example.demo.pojo.SysUser;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.security.core.GrantedAuthority;

import org.springframework.security.core.authority.SimpleGrantedAuthority;

import org.springframework.security.core.userdetails.UserDetails;

import org.springframework.security.core.userdetails.UserDetailsService;

import org.springframework.security.core.userdetails.UsernameNotFoundException;

 

import java.util.ArrayList;

import java.util.List;

 

/**

 * 自定義UserDetailsService,將用戶權(quán)限交給springsecurity進行管控

 *

 * @Author: 我愛大金子

 * @Description: 將用戶權(quán)限交給Springsecurity進行管控

 * @Date: Create in 16:19 2017/7/5

 */

public class CustomUserService implements UserDetailsService {

    @Autowired

    private SysUserDao sysUserDao;

    @Autowired

    private SysPermissionDao sysPermissionDao;

 

    @Override

    public UserDetails loadUserByUsername(String username) {

        SysUser user = sysUserDao.findByUserName(username);

        if (user != null) {

            List<SysPermission> permissions = sysPermissionDao.findByAdminUserId(user.getId());

            List<GrantedAuthority> grantedAuthorities = new ArrayList <>();

            for (SysPermission permission : permissions) {

                if (permission != null && permission.getName()!=null) {

                    GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(permission.getName());

                    //1:此處將權(quán)限信息添加到 GrantedAuthority 對象中,在后面進行全權(quán)限驗證時會使用GrantedAuthority 對象。

                    grantedAuthorities.add(grantedAuthority);

                }

            }

            return new User(user.getUsername(), user.getPassword(), grantedAuthorities);

        else {

            throw new UsernameNotFoundException("admin: " + username + " do not exist!");

        }

    }

}

五、權(quán)限管理

在Security安全配置類中使用了權(quán)限管理過濾器CustomFilterSecurityInterceptor

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

package com.example.demo.utils.security;

 

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.security.access.SecurityMetadataSource;

import org.springframework.security.access.intercept.AbstractSecurityInterceptor;

import org.springframework.security.access.intercept.InterceptorStatusToken;

import org.springframework.security.web.FilterInvocation;

import org.springframework.stereotype.Service;

 

import java.io.IOException;

 

/**

 * 權(quán)限管理過濾器

 *

 * @Author: 我愛大金子

 * @Description: 權(quán)限管理過濾器

 * @Date: Create in 17:16 2017/7/5

 */

@Service

public class CustomFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {

    @Autowired

    private CustomFilterInvocationSecurityMetadataSource customFilterInvocationSecurityMetadataSource;  // 權(quán)限配置資源管理器

 

    /**權(quán)限管理決斷器*/

    @Autowired

    public void setMyAccessDecisionManager(CustomAccessDecisionManager customAccessDecisionManager) {

        super.setAccessDecisionManager(customAccessDecisionManager);

    }

  

    @Override

    public void init(FilterConfig filterConfig) throws ServletException {

 

    }

 

    @Override

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

 

        FilterInvocation fi = new FilterInvocation(request, response, chain);

        invoke(fi);

    }

  

    public void invoke(FilterInvocation fi) throws IOException, ServletException {

        //fi里面有一個被攔截的url

        //里面調(diào)用MyInvocationSecurityMetadataSource的getAttributes(Object object)這個方法獲取fi對應(yīng)的所有權(quán)限

        //再調(diào)用MyAccessDecisionManager的decide方法來校驗用戶的權(quán)限是否足夠

        InterceptorStatusToken token = super.beforeInvocation(fi);

        try {

            //執(zhí)行下一個攔截器

            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());

        finally {

            super.afterInvocation(token, null);

        }

    }

 

    @Override

    public void destroy() {

 

    }

 

    @Override

    public Class<?> getSecureObjectClass() {

        return FilterInvocation.class;

    }

 

    @Override

    public SecurityMetadataSource obtainSecurityMetadataSource() {

        return this.customFilterInvocationSecurityMetadataSource;

    }

}

說明:

 customFilterSecurityInterceptor:權(quán)限管理過濾器

 customAccessDecisionManager:權(quán)限管理決斷器

 customFilterInvocationSecurityMetadataSource:權(quán)限配置資源管理器

其中過濾器在系統(tǒng)啟動時開始工作,并同時導(dǎo)入權(quán)限配置資源管理器和權(quán)限管理決斷器,對用戶訪問的資源進行管理。權(quán)限管理決斷器對用戶訪問的資源與用戶擁有的角色權(quán)限進行對比,以此來判斷用戶是否對某個資源具有訪問權(quán)限。

5.1、權(quán)限管理過濾器

繼承與AbstractSecurityInterceptor,實時監(jiān)控用戶的行為,防止用戶訪問未被授權(quán)的資源。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

package com.example.demo.utils.security;

 

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

 

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.security.access.SecurityMetadataSource;

import org.springframework.security.access.intercept.AbstractSecurityInterceptor;

import org.springframework.security.access.intercept.InterceptorStatusToken;

import org.springframework.security.web.FilterInvocation;

import org.springframework.stereotype.Service;

 

import java.io.IOException;

 

/**

 * 權(quán)限管理過濾器

 *

 * @Author: 我愛大金子

 * @Description: 權(quán)限管理過濾器

 * @Date: Create in 17:16 2017/7/5

 */

@Service

public class CustomFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {

    Logger log = LoggerFactory.getLogger(CustomFilterSecurityInterceptor.class);

    @Autowired

    private CustomFilterInvocationSecurityMetadataSource customFilterInvocationSecurityMetadataSource;  // 權(quán)限配置資源管理器

 

    /**權(quán)限管理決斷器*/

    @Autowired

    public void setMyAccessDecisionManager(CustomAccessDecisionManager customAccessDecisionManager) {

        super.setAccessDecisionManager(customAccessDecisionManager);

    }

  

    @Override

    public void init(FilterConfig filterConfig) throws ServletException {

 

    }

 

    @Override

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

 

        FilterInvocation fi = new FilterInvocation(request, response, chain);

        log.info("【權(quán)限管理過濾器】請求URL:" + fi.getRequestUrl());

        invoke(fi);

    }

  

    public void invoke(FilterInvocation fi) throws IOException, ServletException {

        //fi里面有一個被攔截的url

        //里面調(diào)用CustomFilterInvocationSecurityMetadataSource的getAttributes(Object object)這個方法獲取fi對應(yīng)的所有權(quán)限

        //再調(diào)用CustomAccessDecisionManager的decide方法來校驗用戶的權(quán)限是否足夠

        InterceptorStatusToken token = super.beforeInvocation(fi);

        try {

            //執(zhí)行下一個攔截器

            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());

        catch(Exception e) {

            log.error("【權(quán)限管理過濾器】【異常】" + e.getMessage(), e);

        finally {

            super.afterInvocation(token, null);

        }

    }

 

    @Override

    public void destroy() {

 

    }

 

    @Override

    public Class<?> getSecureObjectClass() {

        return FilterInvocation.class;

    }

 

    @Override

    public SecurityMetadataSource obtainSecurityMetadataSource() {

        return this.customFilterInvocationSecurityMetadataSource;

    }

}

5.2、權(quán)限管理決斷器

權(quán)限管理的關(guān)鍵部分就是決斷器,它實現(xiàn)了AccessDecisionManager,重寫了decide方法,使用自定義的決斷器,在用戶訪問受保護的資源時,決斷器判斷用戶擁有的角色中是否對改資源具有訪問權(quán)限,如果沒有,則拒絕訪問

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

package com.example.demo.utils.security;

 

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.security.access.AccessDecisionManager;

import org.springframework.security.access.AccessDeniedException;

import org.springframework.security.access.ConfigAttribute;

import org.springframework.security.authentication.InsufficientAuthenticationException;

import org.springframework.security.core.Authentication;

import org.springframework.security.core.GrantedAuthority;

import org.springframework.stereotype.Service;

 

import java.util.Collection;

import java.util.Iterator;

 

/**

 * 權(quán)限管理決斷器

 *

 * @Author: 我愛大金子

 * @Description: 權(quán)限管理決斷器

 * @Date: Create in 17:15 2017/7/5

 */

@Service

public class CustomAccessDecisionManager implements AccessDecisionManager {

    Logger log = LoggerFactory.getLogger(CustomAccessDecisionManager.class);

     

    // decide 方法是判定是否擁有權(quán)限的決策方法,

    //authentication 是釋CustomUserService中循環(huán)添加到 GrantedAuthority 對象中的權(quán)限信息集合.

    //object 包含客戶端發(fā)起的請求的requset信息,可轉(zhuǎn)換為 HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();

    //configAttributes 為MyInvocationSecurityMetadataSource的getAttributes(Object object)這個方法返回的結(jié)果,此方法是為了判定用戶請求的url 是否在權(quán)限表中,如果在權(quán)限表中,則返回給 decide 方法,用來判定用戶是否有此權(quán)限。如果不在權(quán)限表中則放行。

    @Override

    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {

 

        if(null== configAttributes || configAttributes.size() <=0) {

            return;

        }

        ConfigAttribute c;

        String needRole;

        for(Iterator<ConfigAttribute> iter = configAttributes.iterator(); iter.hasNext(); ) {

            c = iter.next();

            needRole = c.getAttribute();

            for(GrantedAuthority ga : authentication.getAuthorities()) {//authentication 為在注釋1 中循環(huán)添加到 GrantedAuthority 對象中的權(quán)限信息集合

                if(needRole.trim().equals(ga.getAuthority())) {

                    return;

                }

            }

            log.info("【權(quán)限管理決斷器】需要role:" + needRole);

        }

        throw new AccessDeniedException("Access is denied");

    }

 

    @Override

    public boolean supports(ConfigAttribute attribute) {

        return true;

    }

 

    @Override

    public boolean supports(Class<?> clazz) {

        return true;

    }

}

5.3、權(quán)限配置資源管理器

權(quán)限配置資源管理器實現(xiàn)了FilterInvocationSecurityMetadataSource,在啟動時就去加載了所有的權(quán)限列表,權(quán)限配置資源管理器為決斷器實時提供支持,判斷用戶訪問的資源是否在受保護的范圍之內(nèi)。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

package com.example.demo.utils.security;

 

import com.example.demo.dao.SysPermissionDao;

import com.example.demo.pojo.SysPermission;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.security.access.ConfigAttribute;

import org.springframework.security.access.SecurityConfig;

import org.springframework.security.web.FilterInvocation;

import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;

import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import org.springframework.stereotype.Service;

 

import javax.servlet.http.HttpServletRequest;

import java.util.*;

 

/**

 * 權(quán)限配置資源管理器

 *

 * @Author: 我愛大金子

 * @Description: 權(quán)限配置資源管理器

 * @Date: Create in 17:17 2017/7/5

 */

@Service

public class CustomFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    @Autowired

    private SysPermissionDao sysPermissionDao;

 

    private HashMap<String, Collection<ConfigAttribute>> map =null;

 

    /**

     * 加載權(quán)限表中所有權(quán)限

     */

    public void loadResourceDefine(){

        map = new HashMap<>();

        Collection<ConfigAttribute> array;

        ConfigAttribute cfg;

        List<SysPermission> permissions = sysPermissionDao.findAll();

        for(SysPermission permission : permissions) {

            array = new ArrayList<>();

            cfg = new SecurityConfig(permission.getName());

            //此處只添加了用戶的名字,其實還可以添加更多權(quán)限的信息,例如請求方法到ConfigAttribute的集合中去。此處添加的信息將會作為MyAccessDecisionManager類的decide的第三個參數(shù)。

            array.add(cfg);

            //用權(quán)限的getUrl() 作為map的key,用ConfigAttribute的集合作為 value,

            map.put(permission.getUrl(), array);

        }

    }

 

    //此方法是為了判定用戶請求的url 是否在權(quán)限表中,如果在權(quán)限表中,則返回給 decide 方法,用來判定用戶是否有此權(quán)限。如果不在權(quán)限表中則放行。

    @Override

    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {

        if(map ==null) loadResourceDefine();

        //object 中包含用戶請求的request 信息

        HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();

        AntPathRequestMatcher matcher;

        String resUrl;

        for(Iterator<String> iter = map.keySet().iterator(); iter.hasNext(); ) {

            resUrl = iter.next();

            matcher = new AntPathRequestMatcher(resUrl);

            if(matcher.matches(request)) {

                return map.get(resUrl);

            }

        }

        return null;

    }

 

    @Override

    public Collection<ConfigAttribute> getAllConfigAttributes() {

        return null;

    }

 

    @Override

    public boolean supports(Class<?> clazz) {

        return true;

    }

}

六、根據(jù)權(quán)限設(shè)置連接

對于權(quán)限管理,我們可能希望,在一個用戶訪問的界面中,不是等到用戶點擊了超鏈接之后,才來判斷用戶有沒有這個權(quán)限,而是按照用戶擁有的權(quán)限來顯示超鏈接。這樣的設(shè)計對于用戶體驗來說,會更友好。

6.1、方法1:使用sec標簽(thymeleaf)

在html標簽中引入的Spring Security的標簽:

1

xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"

sec:authentication="name":取當(dāng)前登錄用戶的用戶名

1

<title sec:authentication="name"></title>

sec:authorize="hasRole('ROLE_ADMIN'):表示當(dāng)前用戶是否擁有角色ROLE_ADMIN

1

<li sec:authorize="hasRole('ROLE_ADMIN')"><a th:href="@{/admin}"> admin </a></li>

sec:authorize="hasAuthority('admin')":表示當(dāng)前用戶是否擁有權(quán)限admin

1

<li sec:authorize="hasAuthority('admin')"><a th:href="@{/admin}"> admin </a></li>

6.2、方法二:代碼

在控制層用代碼獲取是否有權(quán)限,然后將標識放入內(nèi)容中,頁面獲取處理

七、其它代碼

7.1、controller

IndexController.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

package com.example.demo.controller;

 

import com.example.demo.domain.Msg;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;

 

/**

 * 描述

 *

 * @Author: 我愛大金子

 * @Description: 描述

 * @Date: Create in 15:25 2017/7/5

 */

@Controller

public class IndexController {

    /**系統(tǒng)首頁*/

    @RequestMapping("/")

    public String index(Model model){

        Msg msg =  new Msg("測試標題","測試內(nèi)容","歡迎來到HOME頁面,您擁有index權(quán)限");

        model.addAttribute("msg", msg);

        return "home";

    }

 

    /**系統(tǒng)首頁2*/

    @RequestMapping("/index2")

    public String index2(Model model){

        Msg msg =  new Msg("測試標題2","測試內(nèi)容2","歡迎來到HOME頁面,您擁有home權(quán)限");

        model.addAttribute("msg", msg);

        return "home";

    }

 

    @RequestMapping("/admin")

    @ResponseBody

    public String hello(){

        return "hello admin";

    }

 

    @RequestMapping("/yk")

    @ResponseBody

    public String hello2(){

        return "hello yk";

    }

}

7.2、dao

SysUserDao.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

package com.example.demo.dao;

 

import com.example.demo.pojo.SysUser;

import org.apache.ibatis.annotations.Mapper;

 

/**

 * 系統(tǒng)用戶dao

 *

 * @Author: 我愛大金子

 * @Description: 系統(tǒng)用戶dao

 * @Date: Create in 16:15 2017/7/5

 */

@Mapper

public interface SysUserDao {

    public SysUser findByUserName(String username);

}

SysPermissionDao.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

package com.example.demo.dao;

 

import com.example.demo.pojo.SysPermission;

import org.apache.ibatis.annotations.Mapper;

 

import java.util.List;

 

/**

 * 系統(tǒng)權(quán)限dao

 *

 * @Author: 我愛大金子

 * @Description: 描述

 * @Date: Create in 17:05 2017/7/5

 */

@Mapper

public interface SysPermissionDao {

    List<SysPermission> findAll();

    List<SysPermission> findByAdminUserId(Long userId);

}

7.3、domain

Msg.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

package com.example.demo.domain;

 

/**

 * 描述

 *

 * @Author: 我愛大金子

 * @Description: 描述

 * @Date: Create in 16:14 2017/7/5

 */

public class Msg {

    private String title;

    private String content;

    private String etraInfo;

    public Msg(String title, String content, String etraInfo) {

        super();

        this.title = title;

        this.content = content;

        this.etraInfo = etraInfo;

    }

    public String getTitle() {

        return title;

    }

    public void setTitle(String title) {

        this.title = title;

    }

    public String getContent() {

        return content;

    }

    public void setContent(String content) {

        this.content = content;

    }

    public String getEtraInfo() {

        return etraInfo;

    }

    public void setEtraInfo(String etraInfo) {

        this.etraInfo = etraInfo;

    }

}

7.4、pojo

SysUser.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

package com.example.demo.pojo;

 

import java.util.List;

 

/**

 * 系統(tǒng)用戶

 *

 * @Author: 我愛大金子

 * @Description: 系統(tǒng)用戶

 * @Date: Create in 16:12 2017/7/5

 */

public class SysUser {

    private Long id;

    private String username;

    private String password;

 

    private List<SysRole> roles;

 

    public Long getId() {

        return id;

    }

 

    public void setId(Long id) {

        this.id = id;

    }

 

    public String getUsername() {

        return username;

    }

 

    public void setUsername(String username) {

        this.username = username;

    }

 

    public String getPassword() {

        return password;

    }

 

    public void setPassword(String password) {

        this.password = password;

    }

 

    public List<SysRole> getRoles() {

        return roles;

    }

 

    public void setRoles(List<SysRole> roles) {

        this.roles = roles;

    }

}

SysRole.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

package com.example.demo.pojo;

 

/**

 * 系統(tǒng)角色

 *

 * @Author: 我愛大金子

 * @Description: 系統(tǒng)角色

 * @Date: Create in 16:13 2017/7/5

 */

public class SysRole {

    private Long id;

    private String name;

 

    public Long getId() {

        return id;

    }

 

    public void setId(Long id) {

        this.id = id;

    }

 

    public String getName() {

        return name;

    }

 

    public void setName(String name) {

        this.name = name;

    }

}

SysPermission.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

package com.example.demo.pojo;

 

/**

 * 系統(tǒng)權(quán)限

 *

 * @Author: 我愛大金子

 * @Description: 系統(tǒng)權(quán)限

 * @Date: Create in 17:04 2017/7/5

 */

public class SysPermission {

    private Long id;

    //權(quán)限名稱

    private String name;

 

    //權(quán)限描述

    private String descritpion;

 

    //授權(quán)鏈接

    private String url;

 

    //父節(jié)點id

    private int pid;

 

    public Long getId() {

        return id;

    }

 

    public void setId(Long id) {

        this.id = id;

    }

 

    public String getName() {

        return name;

    }

 

    public void setName(String name) {

        this.name = name;

    }

 

    public String getDescritpion() {

        return descritpion;

    }

 

    public void setDescritpion(String descritpion) {

        this.descritpion = descritpion;

    }

 

    public String getUrl() {

        return url;

    }

 

    public void setUrl(String url) {

        this.url = url;

    }

 

    public int getPid() {

        return pid;

    }

 

    public void setPid(int pid) {

        this.pid = pid;

    }

}

7.5、mapperXX.xml

SysUserDao.xml

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >

<mapper namespace="com.example.demo.dao.SysUserDao" >

    <resultMap id="userMap" type="SysUser">

        <id property="id" column="ID"/>

        <result property="username" column="username"/>

        <result property="password" column="PASSWORD"/>

        <collection property="roles" ofType="SysRole">

            <result column="name" property="name"/>

        </collection>

    </resultMap>

    <select id="findByUserName" parameterType="String" resultMap="userMap">

        select u.*

        ,r.name

        from sys_user u

        LEFT JOIN sys_user_role sru on u.id= sru.sys_user_id

        LEFT JOIN sys_role r on sru.sys_role_id=r.id

        where username= #{username}

    </select>

</mapper>

SysPermissionDao.xml

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >

<mapper namespace="com.example.demo.dao.SysPermissionDao" >

    <select id="findAll"  resultType="SysPermission">

        SELECT * from sys_permission ;

    </select>

 

    <select id="findByAdminUserId" parameterType="java.lang.Long" resultType="SysPermission">

 

      SELECT

        p.*

      FROM sys_user u

      LEFT JOIN sys_user_role sru ON u.id= sru.sys_user_id

      LEFT JOIN sys_role r ON sru.sys_role_id=r.id

      LEFT JOIN sys_role_permission spr ON spr.sys_role_id=r.id

      LEFT JOIN Sys_permission p ON p.id =spr.sys_permission_id

      WHERE u.id=#{userId}

 </select>

</mapper>

7.6、html

login.html

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org">

<head>

    <meta content="text/html;charset=UTF-8"/>

    <title>登錄頁面</title>

    <link rel="stylesheet" th:href="@{css/bootstrap.min.css}"/>

    <style type="text/css">

        body {

            padding-top: 50px;

        }

        .starter-template {

            padding: 40px 15px;

            text-align: center;

        }

    </style>

</head>

<body>

 

<nav class="navbar navbar-inverse navbar-fixed-top">

    <div class="container">

        <div class="navbar-header">

            <a class="navbar-brand" href="#">Spring Security演示</a>

        </div>

        <div id="navbar" class="collapse navbar-collapse">

            <ul class="nav navbar-nav">

                <li><a th:href="@{/}"> 首頁 </a></li>

 

            </ul>

        </div><!--/.nav-collapse -->

    </div>

</nav>

<div class="container">

 

    <div class="starter-template">

        <p th:if="${param.logout}" class="bg-warning">已成功注銷</p><!-- 1 -->

        <p th:if="${param.illegal}" class="bg-warning">無權(quán)訪問,請切換賬號登錄</p><!-- 1 -->

        <p th:if="${param.error}" class="bg-danger">用戶名或密碼錯誤</p<!-- 2 -->

        <h3>使用賬號密碼登錄</h3>

        <form name="form" th:action="@{/login}" action="/login" method="POST"<!-- 3 -->

            <div class="form-group">

                <label for="username">賬號</label>

                <input type="text" class="form-control" name="username" value="" placeholder="賬號" />

            </div>

            <div class="form-group">

                <label for="password">密碼</label>

                <input type="password" class="form-control" name="password" placeholder="密碼" />

            </div>

            <input type="submit" id="login" value="Login" class="btn btn-primary" />

        </form>

    </div>

</div>

</body>

</html>

home.html

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org"

      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">

<head>

    <meta content="text/html;charset=UTF-8"/>

    <title sec:authentication="name"></title>

    <link rel="stylesheet" th:href="@{css/bootstrap.min.css}" />

    <style type="text/css">

        body {

            padding-top: 50px;

        }

        .starter-template {

            padding: 40px 15px;

            text-align: center;

        }

    </style>

</head>

<body>

<nav class="navbar navbar-inverse navbar-fixed-top">

    <div class="container">

        <div class="navbar-header">

            <a class="navbar-brand" href="#">Spring Security演示</a>

        </div>

        <div id="navbar" class="collapse navbar-collapse">

            <ul class="nav navbar-nav">

                <li><a th:href="@{/}"> 首頁 </a></li>

                <li sec:authorize="hasAuthority('admin')"><a th:href="@{/admin}"> admin </a></li>

            </ul>

        </div><!--/.nav-collapse -->

    </div>

</nav>

  

<div class="container">

 

    <div class="starter-template">

        <h2 th:text="${msg.title}"></h2>

 

        <p class="bg-primary" th:text="${msg.content}"></p>

 

        <div>

            <p class="bg-info" th:text="${msg.etraInfo}"></p>

        </div>

        <form th:action="@{/logout}" method="post">

            <input type="submit" class="btn btn-primary" value="注銷"/>

        </form>

    </div>

 

</div>

  

</body>

</html>

感謝各位的閱讀,以上就是“SpringCloud的spring-security怎么配置”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對SpringCloud的spring-security怎么配置這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI