Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
azure AD B2C,java应用程序_Java_Spring Boot_Azure Ad B2c - Fatal编程技术网

azure AD B2C,java应用程序

azure AD B2C,java应用程序,java,spring-boot,azure-ad-b2c,Java,Spring Boot,Azure Ad B2c,我搜索了很多关于Azure AD B2C安全性对Spring boot、REST实现的支持的信息,但除了Azure AD应用程序或.net应用程序之外,什么都找不到 这是否意味着Azure AD B2C不支持java/spring启动应用程序 如果可能,是否有人尝试过,并让我知道需要从Azure AD web应用更改为Azure AD B2C web应用 期待您的支持 谢谢这展示了如何使用Azure AD B2C(Azure Active Directory)来保护Spring Boot web

我搜索了很多关于Azure AD B2C安全性对Spring boot、REST实现的支持的信息,但除了Azure AD应用程序或.net应用程序之外,什么都找不到

这是否意味着Azure AD B2C不支持java/spring启动应用程序

如果可能,是否有人尝试过,并让我知道需要从Azure AD web应用更改为Azure AD B2C web应用

期待您的支持

谢谢这展示了如何使用Azure AD B2C(Azure Active Directory)来保护Spring Boot web服务后端。您可以在GitHub存储库中找到完整的代码。看看这个文件,希望它会有帮助

是的:)

用于Spring授权服务器和资源服务器。我最近的实现是Resource Server(如果您只需要保护REST API,并且您的应用程序只使用令牌,其他前端应用程序负责登录重定向等,那么这是最好的),这是一个关于使用oAuth2的spring安全性的很好教程,您可以在上找到。 我基于教程的安全配置是:

    @Configuration
    @EnableResourceServer
    @EnableScheduling
    @RequiredArgsConstructor   
    public class SecurityResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Value("${b2c.client-id}")
    private String resourceId;

    private final KeyUtilHandler keyUtilHandler;

    @Primary
    @Bean
    public DefaultTokenServices customTokenServices() {
    DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        return defaultTokenServices;
    }

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {

        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setVerifierKey(keyUtilHandler.stringPublicKey());

        return converter;
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer configurer) {
        configurer.resourceId(resourceId);
        configurer.tokenServices(customTokenServices());
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {

        http
                .sessionManagement().sessionCreationPolicy(STATELESS)
                .and()
                .authorizeRequests()
                .anyRequest()
                .authenticated();

    }
}
如果您在token converter中提供资源id(azure客户端id)和验证器密钥(setVerifierKey),Spring将负责向链中添加一个过滤器,用于验证来自token的签名和基本声明。这都是关于安全配置的。另一件事是azure不提供令牌中的密钥,您可以通过密钥id(令牌中的“kid”)找到合适的公钥。Azure还提供nessecary值来编码密钥,它们可以在为每个b2c租户创建的端点的json对象中找到-

{您的租户名称}/discovery/v2.0/keys?p={您的登录注册策略}

例如:https://login.microsoftonline.com/fabrikamb2c.onmicrosoft.com/discovery/v2.0/keys?p=b2c_1_sign_in

{
  "keys": [
    {"kid":"X5eXk4xyojNFum1kl2Ytv8dlNP4-c57dO6QGTVBwaNk","nbf":1493763266,"use":"sig","kty":"RSA","e":"AQAB","n":"tVKUtcx_n9rt5afY_2WFNvU6PlFMggCatsZ3l4RjKxH0jgdLq6CScb0P3ZGXYbPzXvmmLiWZizpb-h0qup5jznOvOr-Dhw9908584BSgC83YacjWNqEK3urxhyE2jWjwRm2N95WGgb5mzE5XmZIvkvyXnn7X8dvgFPF5QwIngGsDG8LyHuJWlaDhr_EPLMW4wHvH0zZCuRMARIJmmqiMy3VD4ftq4nS5s8vJL0pVSrkuNojtokp84AtkADCDU_BUhrc2sIgfnvZ03koCQRoZmWiHu86SuJZYkDFstVTVSR0hiXudFlfQ2rOhPlpObmku68lXw-7V-P7jwrQRFfQVXw"}
  ]
}
您需要“n”和“e”值来编码客户端应用程序的有效密钥。有现成的库,但您可以编写自己的实现。我还使用rest模板获取json并提取值。根据microsoft文档,密钥可以随时更改,所以您可能需要计划方法

public class KeyUtilHandler {

    @Value("${b2c.key-url}")
    private String keyUrl;

    @Value("${b2c.sign-up-or-in-user-flow}")
    private String signUpOrInUserFlow;

    @Value("${b2c.tenant}")
    private String tenant;

    private String eValue;
    private String nValue;

    public String stringPublicKey(){

        setAzureKeys();

        byte[] modulusBytes = Base64.getUrlDecoder().decode(nValue);
        BigInteger modulusInt = new BigInteger(1, modulusBytes);

        byte[] exponentBytes = Base64.getUrlDecoder().decode(eValue);
        BigInteger exponentInt = new BigInteger(1, exponentBytes);

        KeyFactory keyFactory;

        RSAPublicKeySpec publicSpec = new RSAPublicKeySpec(modulusInt, exponentInt);

        String encodedStringKey = null;

        {
            try {
                keyFactory = KeyFactory.getInstance("RSA");

                RSAPublicKey publicKey = (RSAPublicKey) keyFactory.generatePublic(publicSpec);

                byte [] encodedKey = publicKey.getEncoded();

                encodedStringKey = Base64.getEncoder().encodeToString(encodedKey);

            } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
                e.printStackTrace();
            }
        }

        return String.format("-----BEGIN PUBLIC KEY-----%s-----END PUBLIC KEY-----"
                    , encodedStringKey);

    }

    private void setAzureKeys (){

        String resolvedKeyUrl = String.format(keyUrl, tenant, signUpOrInUserFlow);

        RestTemplate azureKeys = new RestTemplate();
        AzureKeySetDto result = azureKeys.getForObject(resolvedKeyUrl, AzureKeySetDto.class);
        if (Objects.isNull(result.getKeys())) {
            throw new UnableToGetResourceException();
        }
        Map<String, String> keyMap = result.getKeys().stream()
                .findFirst()
                .get();
        eValue = keyMap.get("e");
        nValue = keyMap.get("n");
    }

    @Scheduled(fixedRate = TWENTY_HOURS_IN_MILIS)
    private void renewKeys(){
            setAzureKeys();
    }
}
公共类KeyUtilHandler{
@值(${b2c.key url}”)
私有字符串keyUrl;
@值(${b2c.注册或在用户流中注册}”)
私有字符串signUpOrInUserFlow;
@值(${b2c.tenant})
私人承租人;
私有字符串求值;
私有字符串nValue;
公共字符串stringPublicKey(){
setAzureKeys();
字节[]ModulesBytes=Base64.getUrlDecoder().decode(nValue);
BigInteger modulusInt=新的BigInteger(1,modulusBytes);
byte[]exponentBytes=Base64.getUrlDecoder().decode(eValue);
BigInteger指数=新的BigInteger(1,指数字节);
钥匙厂钥匙厂;
RSAPublicKeySpec publicSpec=新的RSAPublicKeySpec(modulusInt,指数);
字符串encodedStringKey=null;
{
试一试{
keyFactory=keyFactory.getInstance(“RSA”);
RSAPublicKey publicKey=(RSAPublicKey)keyFactory.generatePublic(publicSpec);
字节[]encodedKey=publicKey.getEncoded();
encodedStringKey=Base64.getEncoder().encodeToString(encodedKey);
}捕获(NoSuchAlgorithmException | InvalidKeySpece异常){
e、 printStackTrace();
}
}
返回String.format(“----开始公钥------%s------结束公钥------”
,encodedStringKey);
}
私有void setAzureKeys(){
String resolvedKeyUrl=String.format(keyUrl、tenant、signUpOrInUserFlow);
RestTemplate azureKeys=新建RestTemplate();
AzureKeySetDto结果=azureKeys.getForObject(resolvedKeyUrl,AzureKeySetDto.class);
if(Objects.isNull(result.getKeys())){
抛出新的UnableToGetResourceException();
}
Map keyMap=result.getKeys().stream()
.findFirst()
.get();
eValue=keyMap.get(“e”);
nValue=keyMap.get(“n”);
}
@计划(固定日期=二十小时(百万分之一)
私有密钥(){
setAzureKeys();
}
}

谢谢,但使用Id\u令牌几乎是无处不在的。我想使用EasyAuth流。Blogpost似乎不再可用,但代码仍然在github上:它显示了如何获取公钥。但我需要私钥。那么有没有办法获取私钥呢?