【Spring-Security】Re06 自定義Access & 注解權限分配


一、基於ACCESS方法處理的實現:

我們之前使用的任何放行規則的方法,本質上還是調用access方法執行的

這也意味之我們可以直接使用access方法去方向,只需要注入不同的字符串即可

自定義Access實現:

業務層自定義接口:

package cn.zeal4j.service;

import org.springframework.security.core.Authentication;

import javax.servlet.http.HttpServletRequest;

/**
 * @author Administrator
 * @file IntelliJ IDEA Spring-Security-Tutorial
 * @create 2020 09 28 20:17
 */
public interface CustomService {
    Boolean hasPermission(HttpServletRequest httpServletRequest, Authentication authentication);
}

實現類:

package cn.zeal4j.service;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import javax.servlet.http.HttpServletRequest;
import java.util.Collection;

/**
 * @author Administrator
 * @file IntelliJ IDEA Spring-Security-Tutorial
 * @create 2020 09 28 20:20
 */
public class CustomServiceImpl implements CustomService{
    @Override
    public Boolean hasPermission(HttpServletRequest httpServletRequest, Authentication authentication) {
        // 用戶信息對象
        Object principal = authentication.getPrincipal();
        
        if (principal instanceof UserDetails) {
            
            UserDetails userDetails = (UserDetails) principal;

            Collection<? extends GrantedAuthority> authorities = userDetails.getAuthorities();

            return authorities.contains(new SimpleGrantedAuthority(httpServletRequest.getRequestURI()));
        }
        return false;
    }
}

Access配置:

package cn.zeal4j.configuration;

import cn.zeal4j.handler.CustomAccessDeniedHandler;
import cn.zeal4j.handler.FarsAuthenticationFailureHandler;
import cn.zeal4j.handler.FarsAuthenticationSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandler;

/**
 * @author Administrator
 * @file IntelliJ IDEA Spring-Security-Tutorial
 * @create 2020 09 27 21:55
 */
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private AccessDeniedHandler accessDeniedHandler;

    @Bean
    public PasswordEncoder getPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.formLogin(). // 設置登陸行為方式為表單登陸
                // 登陸請求參數設置
                usernameParameter("username").
                passwordParameter("password").
                loginPage("/login.html"). // 設置登陸頁面URL路徑
                loginProcessingUrl("/login.action"). // 設置表單提交URL路徑
                // successForwardUrl("/main.page"). // 設置認證成功跳轉URL路徑 POST請求
                successHandler(new FarsAuthenticationSuccessHandler("https://www.acfun.cn/")). // 使用自定義的重定向登陸
                // failureForwardUrl("/error.page");  // 設置認證失敗跳轉URL路徑 POST請求
                failureHandler(new FarsAuthenticationFailureHandler("/error.html")); // 跨域處理,不需要跳轉了

        httpSecurity.authorizeRequests().
                regexMatchers(HttpMethod.POST, "正則表達式").permitAll(). // 還可以對符合正則表達式的請求方式進行要求,這個屬性使用來制定請求的方式
                antMatchers("/**/*.js", "/**/*.css", "/**/images/*.*").permitAll(). // 靜態資源放行
                antMatchers("/login.html").permitAll(). // 登陸頁面允許任意訪問
                antMatchers("/error.html").permitAll(). // 失敗跳轉后重定向的頁面也需要被允許訪問
                antMatchers("/admin.page").hasAnyAuthority("admin").
                /*antMatchers("/vip-01.page").hasAnyAuthority("vip-01").*/
                antMatchers("/vip-01.page").hasRole("vip-01").
                antMatchers("/ip.page").hasIpAddress("192.168.43.180").
                // mvcMatchers("/main.page").servletPath("/xxx").permitAll(). // mvcMatchers資源放行匹配
                // antMatchers("/xxx/main.page").permitAll(). // 或者多寫MSP的前綴
                anyRequest().authenticated(). // 其他請求均需要被授權訪問
                anyRequest().access("@customServiceImpl.hasPermission(httpServletRequest, authentication)"); // 自定義Access配置 // CSRF攻擊攔截關閉
        httpSecurity.csrf().disable();

        httpSecurity.exceptionHandling().accessDeniedHandler(accessDeniedHandler);

    }
}

這個授權邏輯只允許賦予了對應的接口地址和的才能訪問,像默認訪問的index頁面就會報錯

二、@Secured注解:

package org.springframework.security.access.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

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

該注解可以標記的位置,方法和類上面

可以聲名的值是一個字符串數組

官方的解釋:

用於聲名角色權限控制,判斷訪問此方法是否具備注解中的角色,參數值必須以ROLE_開頭

具體使用:

二、@PreAuthorize & @PostAuthorize:

@PreAuthorize 用於在方法或者類之前先判斷權限,參數和access方法相同

@PostAuthorize 恰恰相反,在方法和類執行之后判斷 

使用這些注解需要在啟動類中打上@EnableGlobalMethodSecurity

內部字符串會被讀取到,和在配置類中設置是差不多的

當然和配置類不同的是,該注解允許方法注入大寫的角色權限前綴,例如ROLE_vip-01

 


免責聲明!

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



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