【问题标题】:How to use AuthorizationServer in a SystemTest to create JWT tokens without Authentication如何在 SystemTest 中使用 AuthorizationServer 创建没有身份验证的 JWT 令牌
【发布时间】:2022-03-07 14:33:38
【问题描述】:

我有一个系统测试。这意味着,我启动所有应用程序并仅通过执行 REST 调用来访问它们。我还为每个测试创建一个新用户。

现在我必须为我的应用程序添加安全性。这将是“OpenId Connect”。目前没有任何实施。由于有很多教程,我认为实施将是“简单的”。但我不确定如何处理我的 SystemTest。

我认为一种解决方案可能是使用https://github.com/spring-projects/spring-authorization-server/releases/tag/0.2.0。另见https://www.baeldung.com/spring-security-oauth-auth-server#authServerImplementation

我的资源服务器将只有这个配置

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: http://auth-server:9000

我认为我的测试应该是这样的:

  1. 使用不安全的 Rest 调用创建用户(技术 API)。用户将被保存在数据库中
  2. 使用我从 1) 中知道的用户详细信息调用授权服务器。这会给我一个 JWT 令牌。
  3. 像客户端一样调用 REST API。在 Header 中添加 JWT 令牌。
  4. 这种情况由 Spring 自动处理:资源服务器调用授权服务器以获取证书(请参阅 issuer-uri)并验证 JWT。

问题:

  1. 您知道我的 SystemTest 的更好解决方案吗
  2. 你有什么想法如何实施 2)

更新:另一个想法: 也许在 SystemTest 中使用一个苗条的 OpenId Connect 客户端会很好。然后我只需要修改授权服务器来注册用户动态。我还必须确保用户不需要凭据,他必须被允许做事。

最好的问候 G

【问题讨论】:

    标签: spring jwt openid-connect spring-security-oauth2


    【解决方案1】:

    我能够解决我的问题 :-) 我创建了一个具有此控制器和其他类的应用程序。 我希望它可以帮助其他开发人员:-)

    import com.nimbusds.jose.JOSEException;
    import com.nimbusds.jose.jwk.RSAKey;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.annotation.PostConstruct;
    import java.lang.invoke.MethodHandles;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    
    @RestController
    @RequestMapping("/openid-connect/mock")
    public class OpenIdConnectMockController {
    
        static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
    
        private KeyPair rsaKeyPair;
        private RSAKey jwkRsaPublicKey;
    
        @PostConstruct
        public void generateKey() throws NoSuchAlgorithmException, JOSEException {
            this.rsaKeyPair = generateRsaKeyPair(2048);
            logger.info("generate key {}", this.rsaKeyPair.getPublic());
            RSAPublicKey rsaPublicKey = (RSAPublicKey) this.rsaKeyPair.getPublic();
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) this.rsaKeyPair.getPrivate();
            this.jwkRsaPublicKey = new RSAKey.Builder(rsaPublicKey).build();
            logger.info("jwkRsaPublicKey (JWK-Format) {}", this.jwkRsaPublicKey);
        }
    
        @GetMapping(path = "/keys", produces = "application/json")
        public String keys() {
            logger.info("Keys was called {}", this.jwkRsaPublicKey.toString());
            return "{\"keys\":[" + this.jwkRsaPublicKey.toString() + "]}";
        }
    
        @GetMapping(path = "/private-key", produces = "application/json")
        public byte[] getPrivateKey() throws JOSEException {
            RSAKey privateKey = new RSAKey.Builder((RSAPublicKey) this.rsaKeyPair.getPublic()).privateKey(this.rsaKeyPair.getPrivate()).build();
            return privateKey.toRSAPrivateKey().getEncoded();
        }
    
        private KeyPair generateRsaKeyPair(int keyLengthInt) throws NoSuchAlgorithmException {
            KeyPairGenerator keypairGenerator = KeyPairGenerator.getInstance("RSA");
            keypairGenerator.initialize(keyLengthInt, new SecureRandom());
            return keypairGenerator.generateKeyPair();
        }
    
    }
    
     public static Jwt jwtTokenClient(String userId) {
            byte[] privateKey = OpenIdConnectMockService.privateKey(openIdConnectMockWebClient);
            return JwtUtil.createJWT(privateKey, UUID.randomUUID().toString(), "MS-SystemTest-Issuer", userId);
        }
    
    import io.jsonwebtoken.JwtBuilder;
    import io.jsonwebtoken.Jwts;
    import io.jsonwebtoken.SignatureAlgorithm;
    
    import java.security.KeyFactory;
    import java.security.NoSuchAlgorithmException;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.spec.InvalidKeySpecException;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.util.Date;
    
    public class JwtUtil {
    
        public static final long SECOND_IN_MILLIS = 1000;
        public static final long MINUTE_IN_MILLIS = SECOND_IN_MILLIS * 60;
        public static final long HOUR_IN_MILLIS = MINUTE_IN_MILLIS * 60;
        public static final long DAY_IN_MILLIS = HOUR_IN_MILLIS * 24;
    
        private JwtUtil() {
        }
    
        public static Jwt createJWT(byte[] privateKey, String id, String issuer, String subject) {
            //The JWT signature algorithm we will be using to sign the token
            SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.RS256;
    
            long nowMillis = System.currentTimeMillis();
    
            //We will sign our JWT with our ApiKey secret
            PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(privateKey);
            KeyFactory rsaFact = null;
            try {
                rsaFact = KeyFactory.getInstance("RSA");
                RSAPrivateKey key = (RSAPrivateKey) rsaFact.generatePrivate(spec);
    
                JwtBuilder builder = Jwts.builder().setId(id)
                        .setIssuedAt(new Date(nowMillis))
                        .setSubject(subject)
                        .setIssuer(issuer)
                        .setExpiration(new Date(nowMillis + DAY_IN_MILLIS))
                        .signWith(signatureAlgorithm, key);
    
                //Builds the JWT and serializes it to a compact, URL-safe string
                return new Jwt(builder.compact());
            } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
                throw new IllegalStateException(e);
            }
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2019-05-22
      • 2019-10-25
      • 2021-10-12
      • 2019-08-30
      • 2012-12-09
      • 1970-01-01
      • 2020-08-27
      • 2020-11-22
      • 2017-10-22
      相关资源
      最近更新 更多