久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Spring Boot 訪問安全之認證和鑒權詳解

 新用戶604881da 2021-11-09
目錄

·        攔截器

·        認證

·        鑒權

在web應用中有大量場景需要對用戶進行安全校,,一般人的做法就是硬編碼的方式直接埋到到業(yè)務代碼中,,但可曾想過這樣做法會導致代碼不夠簡潔(大量重復代碼),、有個性化時難維護(每個業(yè)務邏輯訪問控制策略都不相同甚至差異很大),、容易發(fā)生安全泄露(有些業(yè)務可能不需要當前登錄信息,,但被訪問的數(shù)據(jù)可能是敏感數(shù)據(jù)由于遺忘而沒有受到保護),。

為了更安全,、更方便的進行訪問安全控制,,我們可以想到的就是使用springmvc的攔截器(HandlerInterceptor),,但其實更推薦使用更為成熟的spring security來完成認證和鑒權。

攔截器

攔截器HandlerInterceptor確實可以幫我們完成登錄攔截,、或是權限校驗,、或是防重復提交等需求。其實基于它也可以實現(xiàn)基于url或方法級的安全控制,。

如果你對spring mvc的請求處理流程相對的了解,,它的原理容易理解,具體可以參閱我之前的分享,。

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

85

86

87

88

89

90

91

92

93

94

public interface HandlerInterceptor {

    /**

     * Intercept the execution of a handler. Called after HandlerMapping determined

     * an appropriate handler object, but before HandlerAdapter invokes the handler.

     *

     * 在業(yè)務處理器處理請求之前被調用,。預處理,可以進行編碼,、安全控制,、權限校驗等處理

     *

     * handler:controller內的方法,,可以通過HandlerMethod method= ((HandlerMethod)handler);獲取到@RequestMapping

     */

    boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

    /**

     * Intercept the execution of a handler. Called after HandlerAdapter actually

     * invoked the handler, but before the DispatcherServlet renders the view.

     *

     * 在業(yè)務處理器處理請求執(zhí)行完成后,生成視圖之前執(zhí)行,。后處理(調用了Service并返回ModelAndView,,但未進行頁面渲染),有機會修改ModelAndView

     */

    void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception;

    /**

     * Callback after completion of request processing, that is, after rendering

     * the view. Will be called on any outcome of handler execution, thus allows

     * for proper resource cleanup.

     *

     * 在DispatcherServlet完全處理完請求后被調用,,可用于清理資源等,。返回處理(已經渲染了頁面)

     *

     */

    void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception;

}

//你可以基于有些url進行攔截

@Configuration

public class UserSecurityInterceptor extends WebMvcConfigurerAdapter {

    @Override

    public void addInterceptors(InterceptorRegistry registry) {

        String[] securityUrls = new String[]{"/**"};

        String[] excludeUrls = new String[]{"/**/esb/**", "/**/dictionary/**"};

        registry.addInterceptor(userLoginInterceptor()).excludePathPatterns(excludeUrls).addPathPatterns(securityUrls);

        super.addInterceptors(registry);

    }

    /** fixed: url中包含// 報錯

     * org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL was not normalized.

     * @return

     */

    @Bean

    public HttpFirewall allowUrlEncodedSlashHttpFirewall() {

        DefaultHttpFirewall firewall = new DefaultHttpFirewall();

        firewall.setAllowUrlEncodedSlash(true);

        return firewall;

    }

    @Bean

    public AuthInterceptor userLoginInterceptor() {

        return new AuthInterceptor();

    }

    public class AuthInterceptor implements HandlerInterceptor {

        public Logger logger = LoggerFactory.getLogger(AuthInterceptor.class);

        @Autowired

        private ApplicationContext applicationContext;

        public AuthInterceptor() {

        }

        @Override

        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

            LoginUserInfo user = null;

            try {

                user = (LoginUserInfo) SSOUserUtils.getCurrentLoginUser();

            } catch (Exception e) {

                logger.error("從SSO登錄信息中獲取用戶信息失敗,! 詳細錯誤信息:%s", e);

                throw new ServletException("從SSO登錄信息中獲取用戶信息失?。?quot;, e);

            }

            String[] profiles = applicationContext.getEnvironment().getActiveProfiles();

            if (!Arrays.isNullOrEmpty(profiles)) {

                if ("dev".equals(profiles[0])) {

                    return true;

                }

            }

            if (user == null || UserUtils.ANONYMOUS_ROLE_ID.equals(user.getRoleId())) {

                throw new ServletException("獲取登錄用戶信息失??!");

            }

            return true;

        }

        @Override

        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

        }

        @Override

        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        }

    }

}

認證

確認一個訪問請求發(fā)起的時候背后的用戶是誰,,他的用戶信息是怎樣的,。在spring security 里面認證支持很多種方式,最簡單的就是用戶名密碼,,還有LDAP,、OpenID、CAS等等,。

而在我們的系統(tǒng)里面,,用戶信息需要通過kxtx-sso模塊進行獲取。通過sso認證比較簡單,,就是要確認用戶是否通過會員系統(tǒng)登錄,,并把登錄信息包裝成授權對象放到SecurityContext中,通過一個filter來完成:

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

@Data

@EqualsAndHashCode(callSuper = false)

public class SsoAuthentication extends AbstractAuthenticationToken {

    private static final long serialVersionUID = -1799455508626725119L;

    private LoginUserInfo user;

    public SsoAuthentication(LoginUserInfo user) {

        super(null);

        this.user = user;

    }

    @Override

    public Object getCredentials() {

        return "kxsso";

    }

    @Override

    public Object getPrincipal() {

        return user;

    }

    @Override

    public String getName() {

        return user.getName();

    }

}

public class SsoAuthenticationProcessingFilter extends OncePerRequestFilter {

    @Override

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)

            throws ServletException, IOException {

        LoginUserInfo user = (LoginUserInfo) SSOUserUtils.getCurrentLoginUser();

        SsoAuthentication auth = new SsoAuthentication(user );

        SecurityContextHolder.getContext().setAuthentication(auth);

        filterChain.doFilter(request, response);

    }

}

@Component

public class SsoAuthenticationProvider implements AuthenticationProvider {

    @Value("${env}")

    String env;

    @Override

    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        LoginUserInfo loginUserInfo = (LoginUserInfo) authentication.getPrincipal();

        /*

         * DEV環(huán)境允許匿名用戶訪問,,方便調試,,其他環(huán)境必須登錄。

         */

        if (!UserUtils.ANONYMOUS_ROLE_ID.equals(loginUserInfo.getRoleId()) || "dev".equals(env)) {

            authentication.setAuthenticated(true);

        } else {

            throw new BadCredentialsException("請登錄");

        }

        return authentication;

    }

    @Override

    public boolean supports(Class<?> authentication) {

        return SsoAuthentication.class.equals(authentication);

    }

}

@Configuration

@EnableWebSecurity

@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    protected void configure(HttpSecurity http) throws Exception {

        // 關閉session

        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and();

        // 允許訪問所有URL,,通過方法保護的形式來限制訪問,。

        http.authorizeRequests().anyRequest().permitAll();

        // 注冊sso filter

        http.addFilterBefore(ssoAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class);

    }

    @Bean

    SsoAuthenticationProcessingFilter ssoAuthenticationProcessingFilter() {

        return new SsoAuthenticationProcessingFilter();

    }

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,,謹防詐騙,。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報,。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約