我正在尝试做一件简单的事情。
想要向单个端点发出请求并发送不记名 token (来自客户端),我希望验证此 token ,并取决于在我的端点上接受/拒绝请求的 keycloak 分配的角色。
我学习了很多教程甚至书籍,但大多数我根本不懂。
按照这个设置我的 keycloak 信息(领域、角色、用户) https://medium.com/@bcarunmail/securing-rest-api-using-keycloak-and-spring-oauth2-6ddf3a1efcc2
所以,
我基本上用一个客户端设置了我的 key 斗篷,一个具有特定角色“用户”的用户并像这样配置它:
@Configuration
@KeycloakConfiguration
//@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
public class SecurityConf extends KeycloakWebSecurityConfigurerAdapter
{
/**
* Registers the KeycloakAuthenticationProvider with the authentication manager.
*/
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(keycloakAuthenticationProvider());
}
/**
* Defines the session authentication strategy.
*/
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Bean
public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Bean
public FilterRegistrationBean keycloakAuthenticationProcessingFilterRegistrationBean(
KeycloakAuthenticationProcessingFilter filter) {
FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}
@Bean
public FilterRegistrationBean keycloakPreAuthActionsFilterRegistrationBean(
KeycloakPreAuthActionsFilter filter) {
FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}
@Override
protected void configure(HttpSecurity http) throws Exception
{
super.configure(http);
http
.authorizeRequests()
.antMatchers("/user/*").hasRole("admin")
.antMatchers("/admin*").hasRole("user")
}
}
我不明白为什么在许多教程中我看到这个(作为最后一条规则):
.anyRequest().permitAll();
基本上当我设置我没有安全性时,我可以在没有承载 token 的情况下调用端点。
但是当我将此作为最后一条规则添加时
.anyRequest().denyAll();
我总是得到 403。
调试我发现了这个:
请求是处理身份验证
f.KeycloakAuthenticationProcessingFilter : Attempting Keycloak authentication
o.k.a.BearerTokenRequestAuthenticator : Found [1] values in authorization header, selecting the first value for Bearer.
o.k.a.BearerTokenRequestAuthenticator : Verifying access_token
o.k.a.BearerTokenRequestAuthenticator : successful authorized
a.s.a.SpringSecurityRequestAuthenticator : Completing bearer authentication. Bearer roles: []
o.k.adapters.RequestAuthenticator : User 'testuser' invoking 'http://localhost:9090/api/user/123' on client 'users'
o.k.adapters.RequestAuthenticator : Bearer AUTHENTICATED
f.KeycloakAuthenticationProcessingFilter : Auth outcome: AUTHENTICATED
o.s.s.authentication.ProviderManager : Authentication attempt using org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider
o.s.s.core.session.SessionRegistryImpl : Registering session 5B871A0E2AF55B70DC8E3B7436D79333, for principal testuser
f.KeycloakAuthenticationProcessingFilter : Authentication success using bearer token/basic authentication. Updating SecurityContextHolder to contain: org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken@355f68d6: Principal: testuser; Credentials: [PROTECTED]; Authenticated: true; Details: org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount@5d7a32a9; Not granted any authorities
[nio-9090-exec-3] o.s.security.web.FilterChainProxy : /api/user/123 at position 8 of 15 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
nio-9090-exec-3] o.s.s.w.s.DefaultSavedRequest : pathInfo: both null (property equals)
[nio-9090-exec-3] o.s.s.w.s.DefaultSavedRequest : queryString: both null (property equals)
好像我没有承载角色...
我的依赖:
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
<version>6.0.1</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-security-adapter</artifactId>
<version>6.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
我的问题?
我请求发送访问 token :
client_id -> my client from keycloak
username -> my user from keycloak
password -> my password from keycloak
grant_type -> password
client_secret -> from keycloak
我得到一个 token ,然后我用它来请求我的应用程序 endoint。 无论我使用什么端点(具有用户角色或管理员角色的端点),我的请求始终有效。
在我的特性中,我有这样的东西:
keycloak:
auth-server-url: http://localhost:8080/auth/
resource: users-api
credentials:
secret : my-secret
use-resource-role-mappings : true
realm: my-realm
realmKey: my-key
public-client: true
principal-attribute: preferred_username
bearer-only: true
知道在这种情况下如何实际启用角色吗?
我是否必须配置客户端才能使用 JWT?有什么想法吗?
我还在端点上添加了注释
@Secured("admin")
@PreAuthorize("hasAnyAuthority('admin')")
但他们似乎什么都不做......
-- 编辑--
修复 url 以匹配资源后,我仍然得到 403。
"realm_access": {
"roles": [
"offline_access",
"admin",
"uma_authorization"
]
},
"resource_access": {
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
}
},
resource_access 是否与我的问题有关?
最佳答案
在调试堆栈中:我看到您正在调用 /api/user/123
并且在您的安全配置中您正在保护 /user/*
这不一样,将您的安全更改为:
.antMatchers("/api/user/*").hasRole("user")
.antMatchers("/api/admin*").hasRole("admin")
P.S:您不需要注册 KeycloakAuthenticationProcessingFilter
和 KeycloakPreAuthActionsFilter
https://stackoverflow.com/questions/56214991/
相关文章:
java - Spring 验证与 Hibernate 验证
java - Spring Security 3 - 总是返回错误 302
java - 使用具有不同 AuthenticationProviders 的多个 WebSecur
java - spring mvc 表单 :select tag
java - Spring WS : How to get and save XSD validat
java - Spring Integration Kafka Consumer Listener
java - 在 Spring Hibernate java 项目中使用 "Envers"审计表
spring - 如何在运行时将新用户添加到 Spring Security