问题描述
我正在使用带有 azure-active-directory-b2c-spring-boot-starter
2.2.0的Spring Boot 2.2.0.我设法用它来保护Thymeleaf网页(按照他们的教程).现在,我想拥有一种以相同方式得到保护的REST API,因为实际的应用程序将是对我的Spring Boot后端执行REST调用的移动应用程序.
I am using Spring Boot 2.2.0 with azure-active-directory-b2c-spring-boot-starter
2.2.0. I managed to secure a Thymeleaf web page with that (following their tutorial). Now, I want to have a REST API that is secured in the same way, as the actual application will be a mobile app that does REST calls to my Spring Boot backend.
我已经想出了如何使用以下方式通过密码授予流程获取令牌:
I already figured out how to get a token with the password grant flow using:
POST https://<my-tenant-id>.b2clogin.com/<my-tenant-id.onmicrosoft.com/oauth2/v2.0/token?p=B2C_1_<my-custom-policy>
(使用用户名和密码作为参数)
(with username and password as parameters)
因此,移动应用可以使用该呼叫.但是我应该如何配置Spring Boot应用程序,以便在API调用上使用 Authorization:Bearer< access-token>
起作用?我需要哪些依赖项/启动器以及应该如何配置?
So a mobile app could use that call. But how should I configure my Spring Boot app so that using Authorization: Bearer <access-token>
on API calls works? What dependencies/starters do I need and how should I configure things?
更新:
我尝试添加:
<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应用程序上执行请求时,出现401错误消息,提示"invalid_token".
But when I do a request on my Spring Boot app, I get a 401 with "invalid_token" error.
推荐答案
解决方案一经了解就非常简单.
Solution seems to be quite simple once you know it.
首先,添加以下依赖项:
First, add the following dependencies:
<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>
接下来,在 application.properties
文件中指定 spring.security.oauth2.resourceserver.jwt.jwk-set-uri
属性.
Next specify the spring.security.oauth2.resourceserver.jwt.jwk-set-uri
property in your application.properties
file.
要知道此值,请在 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正文.取该值并将其放在您的 application.properties
文件中.
This will return a JSON body with jwks_uri
value. Take that value and put it in your application.properties
file.
现在在项目中创建此Java类:
Now create this Java class in the project:
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);
}
}
如果您现在拥有这样的控制器:
If you now have controller like this:
@RestController
public class ApiController {
@GetMapping("/api/test")
public String apiTest(@AuthenticationPrincipal Principal principal) {
return "test " + principal;
}
}
如果您使用正确的 Authorization
标头(其类型为org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken
)
You will see that the principal is not-null if you do a GET on api/test
with a correct Authorization
header (and it is of type org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken
)
唯一不幸的是,校长没有权限,我仍然需要弄清楚原因.
The only thing that is unfortunate is that the Principal has no authorities, something I still need to figure out why.
这篇关于如何使用Azure AD B2C保护Spring Boot REST API?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!