从外部源向 Keycloak 身份验证添加额外的角色
Add additional role to Keycloak authentication from outer source
我想通过 Keycloak 对用户进行身份验证,但我需要向 Spring 安全性使用的身份验证对象添加其他角色。添加角色保存在 Postgres 数据库中。
我试图用自定义 AuthenticationProvider 覆盖 configureGlobal,但没有成功。
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
ApplicationAuthenticationProvider provider = new ApplicationAuthenticationProvider();
provider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(provider);
}
@组件
public class ApplicationAuthenticationProvider 扩展了 KeycloakAuthenticationProvider {
@Autowired
private UserService userService;
private GrantedAuthoritiesMapper grantedAuthoritiesMapper;
public void setGrantedAuthoritiesMapper(GrantedAuthoritiesMapper grantedAuthoritiesMapper) {
this.grantedAuthoritiesMapper = grantedAuthoritiesMapper;
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) authentication;
List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
String username = ((KeycloakAuthenticationToken) authentication)
.getAccount().getKeycloakSecurityContext().getToken().getPreferredUsername();
List<Role> roles = userService.findRoles(username);
for (Role role : roles) {
grantedAuthorities.add(new KeycloakRole(role.toString()));
}
return new KeycloakAuthenticationToken(token.getAccount(), token.isInteractive(), mapAuthorities(grantedAuthorities));
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
private Collection<? extends GrantedAuthority> mapAuthorities(
Collection<? extends GrantedAuthority> authorities) {
return grantedAuthoritiesMapper != null
? grantedAuthoritiesMapper.mapAuthorities(authorities)
: authorities;
}
}
尝试添加额外的过滤器,但我不确定配置是否正确。
@豆子
@Override
protected KeycloakAuthenticationProcessingFilter keycloakAuthenticationProcessingFilter() throws Exception {
RequestMatcher requestMatcher =
new OrRequestMatcher(
new AntPathRequestMatcher("/api/login"),
new QueryParamPresenceRequestMatcher(OAuth2Constants.ACCESS_TOKEN),
// We're providing our own authorization header matcher
new IgnoreKeycloakProcessingFilterRequestMatcher()
);
return new KeycloakAuthenticationProcessingFilter(authenticationManagerBean(), requestMatcher);
}
// Matches request with Authorization header which value doesn't start with "Basic " prefix
private class IgnoreKeycloakProcessingFilterRequestMatcher implements RequestMatcher {
IgnoreKeycloakProcessingFilterRequestMatcher() {
}
public boolean matches(HttpServletRequest request) {
String authorizationHeaderValue = request.getHeader("Authorization");
return authorizationHeaderValue != null && !authorizationHeaderValue.startsWith("Basic ");
}
}
现在我只为 login/password 使用 Keycloak。角色和权限现在保存在本地数据库中。
我想通过 Keycloak 对用户进行身份验证,但我需要向 Spring 安全性使用的身份验证对象添加其他角色。添加角色保存在 Postgres 数据库中。
我试图用自定义 AuthenticationProvider 覆盖 configureGlobal,但没有成功。
@Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { ApplicationAuthenticationProvider provider = new ApplicationAuthenticationProvider(); provider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper()); auth.authenticationProvider(provider); }
@组件 public class ApplicationAuthenticationProvider 扩展了 KeycloakAuthenticationProvider {
@Autowired private UserService userService; private GrantedAuthoritiesMapper grantedAuthoritiesMapper; public void setGrantedAuthoritiesMapper(GrantedAuthoritiesMapper grantedAuthoritiesMapper) { this.grantedAuthoritiesMapper = grantedAuthoritiesMapper; } @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) authentication; List<GrantedAuthority> grantedAuthorities = new ArrayList<>(); String username = ((KeycloakAuthenticationToken) authentication) .getAccount().getKeycloakSecurityContext().getToken().getPreferredUsername(); List<Role> roles = userService.findRoles(username); for (Role role : roles) { grantedAuthorities.add(new KeycloakRole(role.toString())); } return new KeycloakAuthenticationToken(token.getAccount(), token.isInteractive(), mapAuthorities(grantedAuthorities)); } @Override public boolean supports(Class<?> authentication) { return authentication.equals(UsernamePasswordAuthenticationToken.class); } private Collection<? extends GrantedAuthority> mapAuthorities( Collection<? extends GrantedAuthority> authorities) { return grantedAuthoritiesMapper != null ? grantedAuthoritiesMapper.mapAuthorities(authorities) : authorities; }
}
尝试添加额外的过滤器,但我不确定配置是否正确。
@豆子
@Override protected KeycloakAuthenticationProcessingFilter keycloakAuthenticationProcessingFilter() throws Exception { RequestMatcher requestMatcher = new OrRequestMatcher( new AntPathRequestMatcher("/api/login"), new QueryParamPresenceRequestMatcher(OAuth2Constants.ACCESS_TOKEN), // We're providing our own authorization header matcher new IgnoreKeycloakProcessingFilterRequestMatcher() ); return new KeycloakAuthenticationProcessingFilter(authenticationManagerBean(), requestMatcher); } // Matches request with Authorization header which value doesn't start with "Basic " prefix private class IgnoreKeycloakProcessingFilterRequestMatcher implements RequestMatcher { IgnoreKeycloakProcessingFilterRequestMatcher() { } public boolean matches(HttpServletRequest request) { String authorizationHeaderValue = request.getHeader("Authorization"); return authorizationHeaderValue != null && !authorizationHeaderValue.startsWith("Basic "); }
}
现在我只为 login/password 使用 Keycloak。角色和权限现在保存在本地数据库中。