我搜索了很多有关Spring Boot支持,使用Azure AD B2C Security进行REST实现的支持,但找不到任何东西(Azure AD应用程序或.net应用程序除外)。
这是否意味着Azure AD B2C不支持Java / Spring Boot应用程序?
如果可能,是否有人尝试过,让我知道需要从Azure AD Web应用程序更改为Azure AD B2C Webb APP。
期待您的支持。
谢谢
答案 0 :(得分:1)
它是:)
用于Spring Authorization Server和Resource Server。我最近的实现是Resource Server(最好的方法是只需要保护REST API,并且您的应用仅使用令牌,其他前端应用则负责登录重定向等),这是一本关于oAuth2的春季安全性的很好的教程,您可以在{ {3}}。 我基于教程的安全配置是:
@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();
}
}
如果您在令牌转换器中提供资源ID(Azure客户端ID)和验证者密钥(setVerifierKey)-Spring将负责在链中添加一个过滤器,以验证令牌的签名和基本声明。多数民众赞成在安全配置。另一件事是azure不提供令牌中的密钥,您可以通过密钥id(令牌中的“ kid”)找到正确的公钥。 Azure还提供了必要的值来对密钥进行编码,可以在为每个b2c租户创建的终结点的json对象中找到它们-
baeldung {您的租户名称} /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();
}
}
答案 1 :(得分:0)
此tutorial显示了如何使用Azure AD B2C(Azure Active Directory)保护Spring Boot Web服务后端。您可以在GitHub存储库中找到完整的代码。看看这个文档,希望对您有帮助!