![](/img/trans.png)
[英]Spring security 4 @PreAuthorize(“hasRole()”) not working
[英]Spring Security and Azure AD PreAuthorize hasRole is not working
我正在閱讀有關如何使用 Spring Boot Starter for Azure Active Directory 來保護我的 Spring MVC 應用程序的 Microsoft Docs 教程。 我正在嘗試保護我網站的管理區域。 我在 controller 方法上有一個 @PreAuthorize 注釋,我只希望管理員組中的用戶可以訪問該方法。 我能夠獲得登錄提示,但在成功登錄后,我得到了 controller 方法的 403。 當我刪除 @PreAuthorize 注釋時,我可以登錄並訪問該方法就好了。
這是 controller 方法:
@Controller
public class PostController {
...
@PreAuthorize("hasRole('admin')")
@RequestMapping(path = "/admin/post", method = RequestMethod.GET)
public String getPost(@ModelAttribute("post") Post post, Model model) {
List<Tag> tags = tagService.getAll();
model.addAttribute("tags", tags);
return "post";
}
...
這是 WebSecurityConfig.java:
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").authenticated()
.and()
.oauth2Login()
.userInfoEndpoint()
.oidcUserService(oidcUserService);
}
}
這是application.properties:
# Azure AD
# Specifies your Active Directory ID:
azure.activedirectory.tenant-id=<my-ad-tenant-id>
# Specifies your App Registration's Application ID:
spring.security.oauth2.client.registration.azure.client-id=<my-app-registration-app-id>
# Specifies your App Registration's secret key:
spring.security.oauth2.client.registration.azure.client-secret=<my-client-secret>
# Specifies the list of Active Directory groups to use for authorization:
azure.activedirectory.activeDirectoryGroups=admin
這是應用程序注冊清單:
{
"id": "<id>",
"acceptMappedClaims": null,
"accessTokenAcceptedVersion": null,
"addIns": [],
"allowPublicClient": null,
"appId": "<app-id>",
"appRoles": [],
"oauth2AllowUrlPathMatching": false,
"createdDateTime": "2020-04-10T23:37:26Z",
"groupMembershipClaims": null,
"identifierUris": [],
"informationalUrls": {
"termsOfService": null,
"support": null,
"privacy": null,
"marketing": null
},
"keyCredentials": [],
"knownClientApplications": [],
"logoUrl": null,
"logoutUrl": null,
"name": "test",
"oauth2AllowIdTokenImplicitFlow": true,
"oauth2AllowImplicitFlow": true,
"oauth2Permissions": [],
"oauth2RequirePostResponse": false,
"optionalClaims": null,
"orgRestrictions": [],
"parentalControlSettings": {
"countriesBlockedForMinors": [],
"legalAgeGroupRule": "Allow"
},
"passwordCredentials": [
{
"customKeyIdentifier": null,
"endDate": "2299-12-31T05:00:00Z",
"keyId": "<key-id>",
"startDate": "2020-04-10T23:39:47.917Z",
"value": null,
"createdOn": "2020-04-10T23:39:48.4572747Z",
"hint": "SVb",
"displayName": "test key"
}
],
"preAuthorizedApplications": [],
"publisherDomain": "test.onmicrosoft.com",
"replyUrlsWithType": [
{
"url": "http://localhost:8080/login/oauth2/code/azure",
"type": "Web"
}
],
"requiredResourceAccess": [
{
"resourceAppId": "<resource-app-id>",
"resourceAccess": [
{
"id": "<resource-access-id>",
"type": "Scope"
}
]
}
],
"samlMetadataUrl": null,
"signInUrl": null,
"signInAudience": "AzureADMyOrg",
"tags": [],
"tokenEncryptionKeyId": null
}
這是 Azure 中的組:
我正在登錄的用戶是該組的成員。 根據文檔,只有未經授權的用戶才會收到 403。我嘗試將 hasRole() 參數更改為“ROLE_admin”,但這不起作用。 我還嘗試在 WebSecurityConfig.java 中配置 hasRole("admin") ,如下所示:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").authenticated()
.antMatchers("/admin/**").hasRole("admin")
.and()
.oauth2Login()
.userInfoEndpoint()
.oidcUserService(oidcUserService);
}
但這也不起作用。 我已經在這里待了幾天,但是當我登錄的用戶在管理員組中時,我無法弄清楚為什么我會收到 403。
編輯
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
</parent>
<groupId>me.test</groupId>
<artifactId>test-me</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<name>test.me</name>
<properties>
<java.version>1.8</java.version>
<azure.version>2.2.0</azure.version>
</properties>
<dependencies>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-active-directory-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-storage-blob</artifactId>
<version>12.5.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-spring-boot-bom</artifactId>
<version>${azure.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>ROOT</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
您可以在 GitHub 中查看Microsoft Spring Boot / Azure AD 示例。
根據我的研究,如果我們想使用圖 API 檢索用戶的組成員身份,這需要注冊的應用程序具有Direcory.AccessAsUser.All
權限。 更多詳細信息,請參閱文檔和文檔。
例如
# Azure AD
# Specifies your Active Directory ID:
azure.activedirectory.tenant-id=<my-ad-tenant-id>
# Specifies your App Registration's Application ID:
spring.security.oauth2.client.registration.azure.client-id=<my-app-registration-app-id>
# Specifies your App Registration's secret key:
spring.security.oauth2.client.registration.azure.client-secret=<my-client-secret>
# Specifies the list of Active Directory groups to use for authorization:
azure.activedirectory.activeDirectoryGroups=SQLAdmin
# Configure log level
logging.level.root=Debug
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").authenticated()
.and()
.oauth2Login()
.userInfoEndpoint()
.oidcUserService(oidcUserService);
}
}
@Autowired
@PreAuthorize("hasRole('SQLAdmin')")
@GetMapping("/admin")
@ResponseBody
public String helloWorld() {
return "Hello World!";
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.