第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Spring Boot - 需要 api 密鑰和 x509,但不適用于所有端點

Spring Boot - 需要 api 密鑰和 x509,但不適用于所有端點

慕斯709654 2023-07-19 10:53:02
Java 11、Spring 啟動 2.1.3、Spring 5.1.5我有一個 Spring Boot 項目,其中某些端點由 API 密鑰保護。目前使用以下代碼效果很好:@Component("securityConfig")@ConfigurationProperties("project.security")@EnableWebSecurity@Order(1)public class SecurityJavaConfig extends WebSecurityConfigurerAdapter {? ? private static final Logger LOG = LoggerFactory.getLogger(SecurityJavaConfig.class);? ? private static final String API_KEY_HEADER = "x-api-key";? ? private String apiKey;? ? @Override? ? protected void configure(HttpSecurity httpSecurity) throws Exception {? ? ? ? APIKeyFilter filter = new APIKeyFilter(API_KEY_HEADER);? ? ? ? filter.setAuthenticationManager(authentication -> {? ? ? ? ? ? String apiKey = (String) authentication.getPrincipal();? ? ? ? ? ? if (this.apiKey != null && !this.apiKey.isEmpty() && this.apiKey.equals(apiKey)) {? ? ? ? ? ? ? ? authentication.setAuthenticated(true);? ? ? ? ? ? ? ? return authentication;? ? ? ? ? ? } else {? ? ? ? ? ? ? ? throw new BadCredentialsException("Access Denied.");? ? ? ? ? ? }? ? ? ? });? ? ? ? httpSecurity? ? ? ? ? ? .antMatcher("/v1/**")? ? ? ? ? ? .csrf()? ? ? ? ? ? .disable()? ? ? ? ? ? .sessionManagement()? ? ? ? ? ? .sessionCreationPolicy(SessionCreationPolicy.STATELESS)? ? ? ? ? ? .and()? ? ? ? ? ? .addFilter(filter)? ? ? ? ? ? .authorizeRequests()? ? ? ? ? ? .anyRequest()? ? ? ? ? ? .authenticated();? ? }}這成功地需要一個包含 API 密鑰的標(biāo)頭,但僅適用于以下端點:/v1/...我有一個新的要求,需要證書進行身份驗證。我按照以下指南在我的項目中進行了 X.509 身份驗證設(shè)置:禿頂?shù)蠀^(qū)以代碼為中心但是,我遇到了一些問題:證書始終是必需的,而不僅僅是/v1/*端點API 密鑰過濾器不再起作用
查看完整描述

2 回答

?
一只名叫tom的貓

TA貢獻1906條經(jīng)驗 獲得超3個贊

在您的要求中,由于沒有角色(不同的客戶端具有不同的訪問級別),因此不需要 UserDetailService。
APIKeyFilter 足以與 X509 和 API 密鑰配合使用。

考慮APIKeyFilter擴展X509AuthenticationFilter,如果存在沒有有效證書的請求,則過濾器鏈將被破壞,并且將發(fā)送403/的錯誤響應(yīng)。 如果證書有效,則過濾器鏈繼續(xù)并進行身份驗證。而驗證我們所擁有的只有來自身份驗證對象的兩個方法 - - 。其中主題是 (EMAIL=, CN=, OU=, O=, L=, ST=, C=) (APIKeyFilter 應(yīng)配置為返回主體和憑證對象) 您可以使用主體(您的 API 密鑰)來驗證 api 密鑰由客戶發(fā)送。您 可以使用憑據(jù)(證書主題)作為增強功能來單獨識別每個客戶端,如果需要,您可以為不同的客戶端授予不同的權(quán)限。Forbidden

getPrincipal()header:"x-api-key"
getCredential()certificate subject


回顧您的要求
1. API V1 - 僅當(dāng)證書和 API 密鑰有效時才可訪問。
2. 其他API - 無限制


查看完整回答
反對 回復(fù) 2023-07-19
?
繁星淼淼

TA貢獻1775條經(jīng)驗 獲得超11個贊

public class APIKeyFilter extends X509AuthenticationFilter

{

    private String principalRequestHeader;


    public APIKeyFilter(String principalRequestHeader) 

    {

        this.principalRequestHeader = principalRequestHeader;

    }


    @Override

    protected Object getPreAuthenticatedPrincipal(HttpServletRequest request)

    {

        return request.getHeader(principalRequestHeader);

    }


    @Override

    protected Object getPreAuthenticatedCredentials(HttpServletRequest request)

    {

        X509Certificate[] certs = (X509Certificate[]) request

                .getAttribute("javax.servlet.request.X509Certificate");


        if(certs.length > 0)

        {

            return certs[0].getSubjectDN();

        }


        return super.getPreAuthenticatedCredentials(request);

    }

}

@Configuration

@EnableWebSecurity

public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {


    private static final String API_KEY_HEADER = "x-api-key";


    private String apiKey = "SomeKey1234567890";


    @Override

    protected void configure(HttpSecurity http) throws Exception 

    {

        APIKeyFilter filter = new APIKeyFilter(API_KEY_HEADER);

        filter.setAuthenticationManager(authentication -> {

            if(authentication.getPrincipal() == null) // required if you configure http

            {

                throw new BadCredentialsException("Access Denied.");

            }

            String apiKey = (String) authentication.getPrincipal();

            if (authentication.getPrincipal() != null && this.apiKey.equals(apiKey)) 

            {

                authentication.setAuthenticated(true);

                return authentication;

            }

            else

            {

                throw new BadCredentialsException("Access Denied.");

            }

        });


        http.antMatcher("/v1/**")

                .csrf().disable()

                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)

            .and()

                .addFilter(filter)

                .authorizeRequests()

                .anyRequest()

                .authenticated();

    }


    @Bean

    public PasswordEncoder passwordEncoder() 

    {

        return new BCryptPasswordEncoder();

    }

}

驗證 API 響應(yīng)

https - 用于數(shù)據(jù)加密(服務(wù)器向客戶端發(fā)送的 ssl 證書)

X509 - 用于客戶端識別(使用服務(wù)器 ssl 證書生成的 ssl 證書,但不同客戶端不同)

API key - 用于安全檢查的共享密鑰。


出于驗證目的,假設(shè)您有 3 個版本,如下所示


@RestController

public class HelloController

{

    @RequestMapping(path = "/v1/hello")

    public String helloV1()

    {

        return "HELLO Version 1";

    }


    @RequestMapping(path = "/v0.9/hello")

    public String helloV0Dot9()

    {

        return "HELLO Version 0.9";

    }


    @RequestMapping(path = "/v0.8/hello")

    public String helloV0Dot8()

    {

        return "HELLO Version 0.8";

    }

}

下面給出不同情況下的響應(yīng)。

CASE 1.a 版本 1,標(biāo)頭中包含有效的 X509 和 API 密鑰


curl -ik --cert pavel.crt --key myPrivateKey.pem -H "x-api-key:SomeKey1234567890" "https://localhost:8443/v1/hello"

回復(fù)


HTTP/1.1 200

HELLO Version 1

CASE 1.b 版本 1 僅適用于 X509(無 API 密鑰)

curl -ik --cert pavel.crt --key myPrivateKey.pem "https://localhost:8443/v1/hello"

回復(fù)


HTTP/1.1 403

{"timestamp":"2019-09-13T11:53:29.269+0000","status":403,"error":"Forbidden","message":"Access Denied","path":"/v1/hello"}

注意:

在您的情況下,有兩種類型的證書

i。帶有 X509 的客戶端證書

ii:如果客戶端不包含證書,則將使用服務(wù)器中使用的數(shù)據(jù)交換證書,即不帶 X509 的證書

2. 版本 X 不帶 X509,標(biāo)頭中不帶 API 密鑰。


curl "https://localhost:8443/v0.9/hello"

如果服務(wù)器證書是自簽名證書(沒有 CA 即證書頒發(fā)機構(gòu),證書無效)


curl performs SSL certificate verification by default, using a "bundle"

 of Certificate Authority (CA) public keys (CA certs). If the default

 bundle file isn't adequate, you can specify an alternate file

 using the --cacert option.

If this HTTPS server uses a certificate signed by a CA represented in

 the bundle, the certificate verification probably failed due to a

 problem with the certificate (it might be expired, or the name might

 not match the domain name in the URL).

If you'd like to turn off curl's verification of the certificate, use

 the -k (or --insecure) option.

如果服務(wù)器 SSL 證書有效(CA 認證)則

curl "https://localhost:8443/v0.9/hello"

你好版本0.9


curl "https://localhost:8443/v0.8/hello"

你好版本0.8


注意:如果您在開發(fā)環(huán)境中沒有 CA 認證的 SSL 證書,請測試 Hack

使用服務(wù)器證書(.crt)和serverPrivateKey(.pem 文件)以及請求,如下所示


curl -ik --cert server.crt --key serverPrivateKey.pem "https://localhost:8443/v0.9/hello"

這也可以在 Mozilla 中進行驗證(對于自簽名證書),并且可以在 google chrome 中進行相同的驗證(如果 CA 認證的 SSL)

給出的屏幕截圖,在第一次訪問期間

http://img1.sycdn.imooc.com//64b7504b00014c1c06530428.jpg

添加服務(wù)器發(fā)送的證書后。

http://img1.sycdn.imooc.com//64b7505600014dcc05190133.jpg


查看完整回答
反對 回復(fù) 2023-07-19
  • 2 回答
  • 0 關(guān)注
  • 230 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號