Keycloak 社交登录 Rest API 重定向您太​​多次

2024-02-28

我尝试保护我的 Spring Boot 应用程序服务器,我使用 keycloak 来保护它。我想使用谷歌身份验证创建社交登录。这是我的钥匙斗篷配置:

包 com.example.keycloaklearning.config;

import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;

@KeycloakConfiguration
class KeyCloakConfig extends KeycloakWebSecurityConfigurerAdapter {

    // Disable default role prefix ROLE_
    @Autowired
    public void configureGlobal(
            AuthenticationManagerBuilder auth) throws Exception {

        KeycloakAuthenticationProvider keycloakAuthenticationProvider
                = keycloakAuthenticationProvider();
        keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(
                new SimpleAuthorityMapper());
        auth.authenticationProvider(keycloakAuthenticationProvider);
    }

    // Use Spring Boot property files instead of default keycloak.json
    @Bean
    public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
        return new KeycloakSpringBootConfigResolver();
    }

    // Register authentication strategy for public or confidential applications
    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        return new RegisterSessionAuthenticationStrategy(
                new SessionRegistryImpl());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.authorizeRequests()
                .antMatchers("/test/unprotected-data").permitAll()
                .antMatchers("/test/generator").permitAll()
                .anyRequest().authenticated();
    }
}

还有我的控制器:

package com.example.keycloaklearning.controllers;

import lombok.extern.java.Log;
import org.keycloak.common.util.Base64Url;
import org.keycloak.common.util.KeycloakUriBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

@RequestMapping(value = "/test")
@RestController
@Log
public class TestUserController {


    private String authServerUrl = "http://localhost:8080/auth";
    private String realm = "keycloak-lerning-realm";
    private String clientId = "keycloak-lerning-server";

    @GetMapping(path = "/generator")
    public String brokerGenerator(HttpServletRequest httpServletRequest) throws ServletException {
        String provider = "google";
        String nonce = UUID.randomUUID().toString();
        MessageDigest md = null;

        try {
            md = MessageDigest.getInstance("SHA-256");
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }

        String input = nonce + clientId + provider;
        byte[] check = md.digest(input.getBytes(StandardCharsets.UTF_8));
        String hash = Base64Url.encode(check);
        httpServletRequest.getSession().setAttribute("hash", hash);

        String redirectUri = "http://localhost:8081/test/redirect";

        return KeycloakUriBuilder.fromUri(authServerUrl)
                .path("/realms/keycloak-lerning-realm/protocol/openid-connect/auth") // Url changed
                .queryParam("response_type", "code") // Autherization Code Flow
                .queryParam("scope", "openid") // Add additional scopes if needed
                .queryParam("kc_idp_hint", "google") // This should match IDP name registered in Keycloak
                .queryParam("nonce", nonce)
                .queryParam("hash", hash)
                .queryParam("client_id", clientId)
                .queryParam("redirect_uri", redirectUri).build(realm, provider).toString();
    }

    @GetMapping(value = "/unprotected-data")
    public String getName() {
        return "Hello, this api is not protected.";
    }

    @GetMapping(value = "/protected-data")
    public String getEmail() {
        return "Hello, this api is protected.";
    }

    @GetMapping(value = "/redirect")
    public String getRedirectMessage() {
        return "Redirect message.";
    }
}
  1. 我去 http://localhost:8081/test/unprotected-data 这很好用。

  2. 然后我去 http://localhost:8081/test/protected-data 该页面是安全的,我得到了 keycloak 登录页面,我不想使用它,我转到 http://localhost:8081/test/generator

  3. 当我访问 http://localhost:8081/test/generator 时 我得到的网址是这样的: http://localhost:8080/auth/realms/keycloak-lerning-realm/protocol/openid-connect/auth?response_type=code&scope=openid&kc_idp_hint=google&nonce=1d339be6-72b8-487f-8d18-a3b84a1663de&hash=4VZz9Xtk-VqRprnjW8sJC f95EH2dGYIsgkSGYxNtlxU&client_id=keycloak- lerning-server&redirect_uri=http%3A%2F%2Flocalhost%3A8081%2Ftest%2Fredirect

  4. 当我通过这个地址输入我的谷歌数据(电子邮件和密码)时,我收到错误:

此页面无法正常工作,localhost 已将您重定向了太多次。 尝试清除您的cookie。

ERR_TOO_MANY_REDIRECTS

在我的“网络”选项卡中,我看到许多这样的请求:

General:

Request URL: http://localhost:8081/sso/login?session_state=fc107364-ae64-4ab6-923d-d3e8abec6b0b&code=b0fb2c6f-93a0-45ee-bead-500202ef46b8.fc107364-ae64-4ab6-923d-d3e8abec6b0b.4b1cdc54-90bb-4c12-97d7-e04a72d98a49
Request Method: GET
Status Code: 302 
Remote Address: [::1]:8081
Referrer Policy: strict-origin-when-cross-origin

Response Headers:

Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: keep-alive
Content-Length: 0
Date: Sun, 24 Oct 2021 10:43:56 GMT
Expires: 0
Keep-Alive: timeout=60
Location: http://localhost:8081/sso/login?session_state=fc107364-ae64-4ab6-923d-d3e8abec6b0b&code=b0fb2c6f-93a0-45ee-bead-500202ef46b8.fc107364-ae64-4ab6-923d-d3e8abec6b0b.4b1cdc54-90bb-4c12-97d7-e04a72d98a49
Pragma: no-cache
Set-Cookie: OAuth_Token_Request_State=; Max-Age=0; Expires=Thu, 01-Jan-1970 00:00:10 GMT
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block

Request headers:

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: ru
Connection: keep-alive
Cookie: JSESSIONID=C6A7D049775893649E853257B1B8645F; OAuth_Token_Request_State=704778b2-b484-4102-beda-f95e18ddc759
Host: localhost:8081
sec-ch-ua: "Chromium";v="94", "Google Chrome";v="94", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Linux"
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: cross-site
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36

Query string parameters:

session_state: fc107364-ae64-4ab6-923d-d3e8abec6b0b
code: b0fb2c6f-93a0-45ee-bead-500202ef46b8.fc107364-ae64-4ab6-923d-d3e8abec6b0b.4b1cdc54-90bb-4c12-97d7-e04a72d98a49

我尝试清理我的 cookie 并打开新的隐身标签,但这不起作用。


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Keycloak 社交登录 Rest API 重定向您太​​多次 的相关文章

随机推荐