我尝试根据声明中的角色对自己进行身份验证。基本上,我希望只有在声明中包含特定角色时才能连接到应用程序
学历:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.1.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>3.1.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
<version>3.1.4</version>
<scope>compile</scope>
</dependency>
字符集
这是我的安全课:
@Configuration
@EnableWebSecurity(debug = true)
@AllArgsConstructor
public class SecurityOAuth2Config {
private static final Logger LOGGER = LogManager.getLogger(SecurityOAuth2Config.class);
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.cors(AbstractHttpConfigurer::disable)
.headers(header -> header.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
.csrf(AbstractHttpConfigurer::disable)
.sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(req -> req
.requestMatchers(antMatcher("/actuator/health")).permitAll()
.requestMatchers(antMatcher("/actuator/info")).permitAll()
.requestMatchers(antMatcher("/h2-console/**")).permitAll()
// Invoked internally inside the kubernetes cluster
.requestMatchers(antMatcher("/internal/api/**")).permitAll()
.requestMatchers(antMatcher("/api/**"))
.hasAnyRole("User1", "Admin3","TestDataUploader")
.anyRequest().permitAll()
)
.oauth2ResourceServer((oauth2) -> oauth2.jwt(jwtConfigurer ->
jwtConfigurer.jwtAuthenticationConverter(jwtAuthenticationConverter())));
return http.getOrBuild();
}
@Bean
public JwtAuthenticationConverter jwtAuthenticationConverter() {
var grantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
grantedAuthoritiesConverter.setAuthoritiesClaimName("role");
grantedAuthoritiesConverter.setAuthorityPrefix("");
var jwtAuthenticationConverter = new JwtAuthenticationConverter();
jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(grantedAuthoritiesConverter);
return jwtAuthenticationConverter;
}
@Bean
public GrantedAuthoritiesMapper userAuthoritiesMapper() {
return (authorities) -> {
Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
LOGGER.info("AUTHORITIES " + authorities);
authorities.forEach(authority -> {
if (authority instanceof OidcUserAuthority oidcAuth) {
oidcAuth.getUserInfo().getClaimAsStringList("role").forEach(
role -> mappedAuthorities.add(new SimpleGrantedAuthority("" + role)));
}
});
mappedAuthorities.addAll(authorities);
return mappedAuthorities;
};
}
}
型
我一直都没得到授权
承载令牌示例
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1699881658,
"iss": "https://id.test.io/",
"upn": "Jon",
"role": [
"Admin",
"Approve"
]
}
型
控制器端点示例
@RestController
@RequestMapping("/api")
@AllArgsConstructor
public class ApplicationListController {
private ServiceApp serviceApp;
@GetMapping("/app")
public Collection<Response> getApplications() {
return serviceApp.loadResponse();
}
}
型
2条答案
按热度按时间9q78igpj1#
你应该删除你的
GrantedAuthoritiesMapper
bean,它复制了你已经在JwtAuthenticationConverter
上配置的东西。当使用
.hasAnyRole("User1", "Admin3","TestDataUploader")
时,您希望身份验证包含ROLE_User1
、ROLE_Admin3
或ROLE_TestDataUploader
权限之一,但您Map的"role": [ "Admin", "Approve" ]
声明没有前缀=>权限为Admin
和Approve
=>由于缺少ROLE_
前缀且预期角色为Admin3
,因此不匹配(不是您索赔中所含的Admin
)。三种选择:.hasAnyAuthority("User1", "Admin","TestDataUploader")
.hasAnyRole("User1", "Admin","TestDataUploader")
并将JwtAuthenticationConverter
更新为grantedAuthoritiesConverter.setAuthorityPrefix("ROLE_");
Admin3
更改为ROLE_Admin
(令牌中的声明将为"role": [ "ROLE_Admin3", "ROLE_Approve" ]
)尝试使用以下conf:
字符集
作为替代方案,您可以使用我的启动器沿着方法安全性,这可能会使您的生活更轻松:
gg58donl2#
给予访问权限,使用
@PreAuthorize("hasAnyAuthority('role')")
访问控制器字符集