Java 键斗篷虚拟配置
我有一个springboot项目,其中keydove作为身份验证提供者。是否可以为特定的弹簧配置文件创建“虚拟身份验证”?我想有一个配置文件'dummy auth',它将始终将keydovepprincipal设置为某个虚拟用户。也许要换一种过滤器?我有钥匙斗篷配置:Java 键斗篷虚拟配置,java,spring,spring-boot,keycloak,Java,Spring,Spring Boot,Keycloak,我有一个springboot项目,其中keydove作为身份验证提供者。是否可以为特定的弹簧配置文件创建“虚拟身份验证”?我想有一个配置文件'dummy auth',它将始终将keydovepprincipal设置为某个虚拟用户。也许要换一种过滤器?我有钥匙斗篷配置: @KeycloakConfiguration public class KeycloakSecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
@KeycloakConfiguration
public class KeycloakSecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(keycloakAuthenticationProvider());
}
@Bean
public KeycloakSpringBootConfigResolver keycloakSpringBootConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests()
.anyRequest()
.fullyAuthenticated();
}
}
我真的不知道如何实现这个虚拟身份验证。也许更好的选择是某种嵌套的keydove实例?一些建议 1.具有多个配置文件 我会为不同的目的提出不同的简介;钥匙斗篷,本地,钥匙斗篷本地 钥匙斗篷 当您想要与Identity Provider集成并将从KeyClope检索到的经过身份验证的对象设置为Spring上下文时,请使用此配置文件
@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
@Profile( "keycloak" )
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter
{
@Bean
public KeycloakSpringBootConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy( )
{
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Autowired
public void configureGlobal( AuthenticationManagerBuilder auth) throws Exception {
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@Override
protected void configure( HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests()
.antMatchers("/hello")
.authenticated()
.anyRequest()
.permitAll();
}
}
地方的
还创建一个本地配置文件,您不希望在其中附带标识提供程序,但仍希望将经过身份验证的用户注入到您的上下文中
@Configuration
@EnableWebSecurity
@ComponentScan( basePackageClasses = KeycloakSecurityComponents.class )
@Profile( "local" )
public class LocalSecurityConfig extends WebSecurityConfigurerAdapter
{
@Override
protected void configure( HttpSecurity http ) throws Exception
{
http.authorizeRequests( )
.antMatchers( "/hello" )
.authenticated( )
.anyRequest( )
.permitAll( )
.and( )
.formLogin( );
}
@Autowired
public void configureGlobal( AuthenticationManagerBuilder auth )
throws Exception
{
auth
.inMemoryAuthentication( )
.withUser( "user" )
.password( passwordEncoder().encode( "password") )
.roles( "USER" );
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
钥匙斗篷本地
或者更好的是,我们可以在特定概要文件中将真正的keydove认证对象设置为上下文。如果您在上下文中需要更复杂的身份验证对象,并且随附KeyDoppeAuthenticationToken,请使用此方法。否则,本地概要文件也可以,因为这需要更多的编码,但这也是一个工作示例:
创建一个过滤器,我们称之为LocalFilter。此筛选器将创建一个KeyDopperAuthenticationToken,并将其设置为spring上下文:
public class LocalFilter extends GenericFilterBean
{
@Override
public void doFilter( ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain )
throws IOException, ServletException
{
SecurityContextHolder.getContext( ).setAuthentication( generateKeycloakToken( "stackoverflow.com", "ROLE_USER", "" ) );
filterChain.doFilter(servletRequest, servletResponse);
}
public static KeycloakAuthenticationToken generateKeycloakToken( String org, String roles, String permissions )
{
AccessToken accessToken = new AccessToken( );
if ( org != null && !org.isEmpty( ) )
{
accessToken.setOtherClaims( "org", org );
}
if ( permissions != null && !permissions.isEmpty( ) )
{
accessToken.setOtherClaims( "permissions", permissions );
}
RefreshableKeycloakSecurityContext rksc =
new RefreshableKeycloakSecurityContext( null, null, UUID.randomUUID( ).toString( ), accessToken, null, null,
null );
Set<String> rolesSet = new HashSet<>( );
String[] roleArr = roles.split( "," );
for ( String role : roleArr )
{
rolesSet.add( role.trim( ) );
}
KeycloakPrincipal<RefreshableKeycloakSecurityContext> principal = new KeycloakPrincipal<>( "name", rksc );
Collection<GrantedAuthority> authorities = generateGrantedAuthority( roles );
return new KeycloakAuthenticationToken( new SimpleKeycloakAccount( principal, rolesSet, rksc ), false,
authorities );
}
public static Collection<GrantedAuthority> generateGrantedAuthority( String roles )
{
Collection<GrantedAuthority> authorities = new ArrayList<>( );
for ( String role : roles.split( "," ) )
{
authorities.add( new SimpleGrantedAuthority( role.trim( ) ) );
}
return authorities;
}
}
2.If资源服务器:没有交互身份提供程序的令牌
如果您使用客户机作为资源服务器进行密钥伪装,那么有一种方法可以验证身份验证,而无需与身份提供商交互。遵循以下步骤
- 生成一个JWT(您可以创建一个虚拟客户机来keydove并复制它,如果您需要一些样本或在任何地方生成它,记下您的算法和公钥)
- 如果您使用KeyClope生成jwt,请从领域设置->密钥->复制属于算法的公钥(默认值为RS256)复制公钥,并将其保存到应用程序中的某个位置,例如:src/main/test/resources
- 不要给出
而是使用颁发者uri
公钥和
jws算法配置您的服务。这样,您的服务将不会请求您的身份提供商验证承载者
- 对于spring security oauth2库,以下是一个示例配置:
- 现在将您的代币作为持票人头发送
@MockBean JwtDecoder JwtDecoder;
),而是简单地在安全上下文中插入模拟身份验证,或者手动使用SecurityContextHolder.getContext().setAuthentication(auth)
或使用类似的@和mockkeydapeauth
从。我提供了各种带有单元测试的示例应用程序,包括asAuthentication
impl。我的所有单元测试都不需要任何正在运行的授权服务器
如果您打算在不访问公司KeyClope实例的情况下启动应用程序,
也许你应该考虑在你的DEV机器上运行一个“独立”的KiP衣帽实例。在配置文件中更改多个属性值(指向KeyClope服务器A或B)常常是我痛苦经历的来源…此虚拟身份验证或此配置文件的目的是什么,您将使用什么?您想让应用程序的某个实例始终以虚拟用户运行吗?或者您希望您的一些端点与虚拟用户一起工作,而其他端点则按预期工作(因为您提到了自定义筛选器)?也许更多的细节会有帮助。也许用它进行一些集成测试?或者,当我没有正在运行的KeyClope实例时,我仍然想运行并测试我的应用程序;当您想在不使用keydove的情况下测试您的应用程序,或者只想绕过安全性(在集成测试中或在不使用keydove的情况下运行)时,在安全上下文中使用keydove令牌对象真的更合适吗?但当我必须向该用户分配某个对象时,情况会怎样呢?我需要从安全上下文中获取此用户。然后我有了REST端点(比如
/me
),我想在这里检索关于这个用户的所有信息。另一种情况可能是一些测试配置文件,在其中我使用内存中的db和模拟用户启动应用程序,这允许轻松测试我的应用程序。
@Configuration
@EnableWebSecurity
@ComponentScan( basePackageClasses = KeycloakSecurityComponents.class )
@Profile( "local-keycloak" )
public class LocalKeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter
{
@Bean
public KeycloakSpringBootConfigResolver keycloakConfigResolver( )
{
return new KeycloakSpringBootConfigResolver( );
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy( )
{
return new RegisterSessionAuthenticationStrategy( new SessionRegistryImpl( ) );
}
@Autowired
public void configureGlobal( AuthenticationManagerBuilder auth ) throws Exception
{
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider( );
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper( new SimpleAuthorityMapper( ) );
auth.authenticationProvider( keycloakAuthenticationProvider );
}
@Override
protected void configure( HttpSecurity http ) throws Exception
{
super.configure( http );
http.addFilterBefore(new LocalFilter(), UsernamePasswordAuthenticationFilter.class)
.authorizeRequests( )
.antMatchers( "/hello" )
.authenticated( )
.anyRequest( )
.permitAll( );
}
}
spring
security:
oauth2:
resourceserver:
jwt:
public-key-location: classpath:jwt_public_key.json
jws-algorithm: RS256 # this is default, you can skip setting it