我正在使用 Spring Boot 2.2.0 和 azure-active-directory-b2c-spring-boot-starter
2.2.0。我设法用它来保护 Thymeleaf 网页(按照他们的教程)。现在,我想要一个以相同方式保护的 REST API,因为实际应用程序将是一个对我的 Spring Boot 后端进行 REST 调用的移动应用程序。
我已经弄清楚如何使用密码授予流程获取 token :
POST https://<my-tenant-id>.b2clogin.com/<my-tenant-id.onmicrosoft.com/oauth2/v2.0/token?p=B2C_1_<my-custom-policy>
(以用户名和密码作为参数)
因此移动应用程序可以使用该调用。但是我应该如何配置我的 Spring Boot 应用程序以便使用 Authorization: Bearer <access-token>
API 调用有效吗?我需要哪些依赖项/启动器以及应该如何配置?
更新:
我尝试添加:
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.3.7.RELEASE</version>
</dependency>
与:
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class OAuth2ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("my-azure-b2c-test");
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/api/**")
.authenticated();
}
}
但是当我在 Spring Boot 应用程序上发出请求时,我收到带有“invalid_token”错误的 401。
最佳答案
一旦您了解了解决方案,就会发现它似乎非常简单。
首先,添加以下依赖项:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-resource-server</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
接下来指定spring.security.oauth2.resourceserver.jwt.jwk-set-uri
您的属性(property)application.properties
文件。
要了解该值,请执行 GET
(使用 cURL 或其他工具)https://<my-tenant-id>.b2clogin.com/<my-tenant-id>.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=B2C_1_<my-custom-policy>
这将返回一个带有 jwks_uri
的 JSON 正文值(value)。获取该值并将其放入您的 application.properties
中文件。
现在在项目中创建这个 Java 类:
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/api/**")
.authenticated()
.and()
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
}
}
如果你现在有这样的 Controller :
@RestController
public class ApiController {
@GetMapping("/api/test")
public String apiTest(@AuthenticationPrincipal Principal principal) {
return "test " + principal;
}
}
如果您对 api/test
执行 GET,您将看到主体不为空。正确的Authorization
header (其类型为 org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken
)
唯一遗憾的是校长没有权力,我还需要弄清楚原因。
关于java - 如何使用 Azure AD B2C 保护 Spring Boot REST API 的安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58628114/