What does \ mean in Spring Security Roles Hierarchy Expression? - spring

security:
jwt:
issuer: "https://localhost.com"
rolesHierarchyExpression:
ROLE_FATHER > ROLE_LORD \
ROLE_VASSAL > ROLE_HUMBLE_SERVANT
ROLE_KNIGHT > ROLE_HUMBLE_SERVANT
...
I was wondering in the application yml, what does \ mean? This is Spring Security Oauth 1.0.0.

Related

Spring boot application with kafka stream

Do anyone has a hello world example of reading message as stream using kafka stream and spring boot.
My kafka cluster is SASL_ SSL secured. So how do I connect my spring boot kafka stream application with. What to write in application.properties file.
I donot want to use spring cloud stream.
server.port=8084
topic.name=test-topic
server.servlet.context-path=/api/v1
spring.application.name=kafkatest
spring.kafka.bootstrap-servers=*************.com:9093
spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.IntegerSerializer
spring.kafka.producer.value-serializer=io.confluent.kafka.serializers.KafkaAvroSerializer
spring.kafka.jaas.enabled=true
spring.kafka.properties.security.protocol= SASL_SSL
spring.kafka.properties.security.krb5.config = file:/etc/krb5.conf
spring.kafka.properties.sasl.mechanism = GSSAPI
spring.kafka.properties.sasl.kerberos.service.name= kafka
spring.kafka.properties.sasl.jaas.config = com.sun.security.auth.module.Krb5LoginModule required useTicketCache=false serviceName="kafka" storeKey=true principal="***************" useKeyTab=true keyTab="/home/api/config/kafkaclient.keytab";
spring.kafka.ssl.trust-store-location= file:/home/api/config/truststore.p12 spring.kafka.ssl.trust-store-password=*********************
spring.kafka.ssl.trust-store-type= PKCS12
I did this way.
Add the sasl config in the properties.
> spring:
> kafka:
> client-id: ${spring.app.name}
> bootstrap-servers: <cluster_url>:9092
> properties:
> ssl.endpoint.identification.algorithm: https
> sasl.mechanism: PLAIN
> sasl.jaas.config: org.apache.kafka.common.security.plain.PlainLoginModule required
> username="xxxxx" password="xxxxxxx";
> security.protocol: SASL_SSL
And then created a bean which initializes KafkaStreamsConfiguration
#Bean
public KafkaStreamsConfiguration streamsConfig(KafkaProperties kafkaProperties) {
Map<String, Object> streamsProperties = kafkaProperties.buildStreamsProperties();
streamsProperties.put(BOOTSTRAP_SERVERS_CONFIG, server);
streamsProperties.put(APPLICATION_ID_CONFIG, applicationId);
streamsProperties.put(DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());
streamsProperties.put(DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());
return new KafkaStreamsConfiguration(streamsProperties);
}
Note that: I'm using KafkaProperties.buildStreamsProperties() to fetch the streams config from properties

Https setup for spring boot and swagger2

I am trying to integrate my Sprint Boot applications with Keycloak, starting with secure swagger page.
keytool helped me to generate a selfsigned keystore
keytool -genkey -alias abcdef -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
I use the above to setup ssl for the app
server:
port: "15700"
ssl:
enabled: true
key-store: classpath:keystore.p12
key-store-password: password
key-alias: abcdef
keyStoreType: PKCS12
Without keycloak, the https for swagger works as expected.
I started keycloak from their docker image as below, export http and https
services:
keycloak:
image: jboss/keycloak
environment:
DB_VENDOR: POSTGRES
DB_ADDR: my.ip.address
DB_PORT: 5432
DB_DATABASE: keycloak
DB_USER: username
DB_PASSWORD: password
KEYCLOAK_USER: admin
KEYCLOAK_PASSWORD: password
ports:
- 8443:8443
- 8080:8080
I ask user to login first when they want to access the swagger docs, so I configure keycloak as below:
keycloak:
auth-server-url: "https://192.168.1.15:8443/auth"
realm: "DemoRealm"
public-client: true
resource: demo-app
security-constraints[0]:
authRoles[0]: "user"
securityCollections[0]:
name: "Demo App"
patterns[0]: "/swagger-ui.html"
Now, not logged in user will be direct to keycloak login page, it works perfect. But after the successful login, when redirect back to the app's swagger page, I go the following error:
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
If I configure the keycloak auth uri to http
keycloak:
auth-server-url: "http://192.168.1.15:8080/auth"
realm: "DemoRealm"
public-client: true
resource: demo-app
security-constraints[0]:
authRoles[0]: "user"
securityCollections[0]:
name: "Demo App"
patterns[0]: "/swagger-ui.html"
everything works perfectly.
Is this a configuration issue for keycloak or for the spring boot app? Any required steps I missed?
You can try to set up your Rest Template bean:
Add dependency:
implementation 'org.apache.httpcomponents:httpclient:4.5'
Provide RestTemplate bean:
#Bean
private RestTemplate restTemplate() {
SSLContext sslContext = buildSslContext();
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext);
HttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(socketFactory)
.build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
return new RestTemplate(factory);
}
private SSLContext buildSslContext() {
try {
char[] keyStorePassword = sslProperties.getKeyStorePassword();
return new SSLContextBuilder()
.loadKeyMaterial(
KeyStore.getInstance(new File(sslProperties.getKeyStore()), keyStorePassword),
keyStorePassword
).build();
} catch (Exception ex) {
throw new IllegalStateException("Unable to instantiate SSL context", ex);
} finally {
sslProperties.setKeyStorePassword(null);
sslProperties.setTrustStorePassword(null);
}
}
Provide required SSL properties in your application.properties or application.yaml file:
server:
ssl:
enabled: true
key-store: /path/to/key.keystore
key-store-password: password
key-alias: alias
trust-store: /path/to/truststore
trust-store-password: password
Alternatively, you can use my spring boot starter

Keycloak Policy Enforcing

Application.properties:
server.port=8180
keycloak.realm = finaltest
keycloak.auth-server-url = http://localhost:8080/auth
keycloak.resource = ex
keycloak.public-client=false
keycloak.enabled=true
keycloak.credentials.secret=secret
keycloak.ssl-required = external
keycloak.cors=true
keycloak.use-resource-role-mappings=true
keycloak.security-constraints[0].auth-roles[0]=master
keycloak.security-constraints[0].security-collections[0].patterns[0]=/*
keycloak.policy-enforcer-config.enforcement-mode=ENFORCING
keycloak.policy-enforcer-config.lazy-load-paths=true
RESOURCES:
I have two resources namely
http://localhost:8180/flights.html
http://localhost:8180/hotels.html
I have protected these using the policies in keycloak admin console.How do I enforce these policies in the application?
keycloak.policy-enforcer-config.enforcement-mode=ENFORCING this line will enforce policies.But you must have spring boot version 2.0 and above.

Disable / remove spring boot datasource by profile

Using spring boot yaml config, I have a datasource that looks like this:
datasource:
url: jdbc:postgresql://somehost/somedb
username: username
password: password
hikari:
connection-timeout: 250
maximum-pool-size: 1
minimum-idle: 0
I can succesfully point to different DBs based on profile, but I'd like to setup a profile that does not use this datasource at all. When I use that profile, however, I get this:
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to auto-configure a DataSource: 'spring.datasource.url' is not specified and no embedded datasource could be auto-configured.
Reason: Failed to determine a suitable driver class
How do I use this datasource in some profiles, but not in others?
You can skip the bean for specific profiles using `#Profile("!dev") annotation
profile names can also be prefixed with a NOT operator e.g. “!dev” to exclude them from a profile
from docs here
If a given profile is prefixed with the NOT operator (!), the annotated component will be registered if the profile is not active — for example, given #Profile({"p1", "!p2"}), registration will occur if profile 'p1' is active or if profile 'p2' is not active.
Profiles can also be configured in XML – the tag has “profiles” attribute which takes comma separated values of the applicable profiles:here
<beans profile="dev">
<bean id="devDatasourceConfig"
 class="org.baeldung.profiles.DevDatasourceConfig" />
</beans>
Change to:
spring:
datasource:
url: jdbc:postgresql://somehost/somedb
username: username
password: password
hikari:
connection-timeout: 250
maximum-pool-size: 1
minimum-idle: 0
Springboot works with Autoconfiguration by default, but you can customize excluding some AutoConfiguration classes
Edit your configuration to skip AutoConfiguration:
#EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
Make your own datasource by profile
#Bean
#Profile("dev")
DataSource dataSourceDevProfile(org.springframework.core.env.Environment environment) throws Exception {
return DataSourceBuilder.create().url("").driverClassName("").password("").username("").build();
}
#Bean
#Profile("!dev")
DataSource dataSourceNoDev(org.springframework.core.env.Environment environment) throws Exception {
return DataSourceBuilder.create().url(environment.getProperty("spring.datasource.url")).driverClassName("").password(environment.getProperty("spring.datasource.password")).username(environment.getProperty("spring.datasource.username")).build();
}
Or Totally Programatically
#Bean
DataSource dataSource2(org.springframework.core.env.Environment environment) throws Exception {
if (environment.acceptsProfiles("dev")){
//return datasource dev
}else{
//return datasource prod
}

How do I enable logging for Spring Security?

I am setting up Spring Security to handle logging users in. I have logged in as a user, and am taken to an Access Denied error page upon successful login. I don't know what roles my user has actually been assigned, or the rule that causes access to be denied, because I can't figure out how to enable debugging for the Spring Security library.
My security xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans ... >
<!-- security -->
<security:debug/><!-- doesn't seem to be working -->
<security:http auto-config="true">
<security:intercept-url pattern="/Admin**" access="hasRole('PROGRAMMER') or hasRole('ADMIN')"/>
<security:form-login login-page="/Load.do"
default-target-url="/Admin.do?m=loadAdminMain"
authentication-failure-url="/Load.do?error=true"
username-parameter="j_username"
password-parameter="j_password"
login-processing-url="/j_spring_security_check"/>
<security:csrf/><!-- enable Cross Site Request Forgery protection -->
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:jdbc-user-service data-source-ref="loginDataSource"
users-by-username-query="SELECT username, password, active FROM userinformation WHERE username = ?"
authorities-by-username-query="
SELECT ui.username, r.rolename
FROM role r, userrole ur, userinformation ui
WHERE ui.username=?
AND ui.userinformationid = ur.userinformationid
AND ur.roleid = r.roleid "
/>
<security:password-encoder hash="md5"/>
</security:authentication-provider>
</security:authentication-manager>
</beans>
I've also tried adding log4j.logger.org.springframework.security=DEBUG to my log4j.properties
How can I get debug output for Spring Security?
Assuming you're using Spring Boot, another option is to put the following in your application.properties:
logging.level.org.springframework.security=DEBUG
This is the same for most other Spring modules as well.
If you're not using Spring Boot, try setting the property in your logging configuration, e.g. logback.
Here is the application.yml version as well:
logging:
level:
org:
springframework:
security: DEBUG
You can easily enable debugging support using an option for the #EnableWebSecurity annotation:
#EnableWebSecurity(debug = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
…
}
Basic debugging using Spring's DebugFilter can be configured like this:
#EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
public void configure(WebSecurity web) throws Exception {
web.debug(true);
}
}
You can easily enable debugging support using an option for the #EnableWebSecurity annotation:
#EnableWebSecurity(debug = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
…
}
If you need profile-specific control the in your application-{profile}.properties file
org.springframework.security.config.annotation.web.builders.WebSecurity.debugEnabled=false
Get Detailed Post: http://www.bytefold.com/enable-disable-profile-specific-spring-security-debug-flag/
We can always check the registered filters inside Spring Security with the below configuration
#EnableWebSecurity(debug=true) - We need to enable the debugging of the security details
Enable logging of the details by adding the below property in the application.properties logging.level.org.springframework.security.web.FilterChainProxy=DEBUG
Below mentioning some of the internal filters of Spring Security that gets executed in the authentication flow:
Security filter chain: [
CharacterEncodingFilter
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
CsrfFilter
LogoutFilter
X509AuthenticationFilter
UsernamePasswordAuthenticationFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
RememberMeAuthenticationFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
]
Using Spring Boot with default spring security filters (without customizing anything, and without even setting debug in the EnableWebSecurity annotation), setting TRACE as the following application.properties shows:
logging.level.org.springframework.security=TRACE
Is enough for it to show in detail what filters are being called and what they are doing.
TRACE w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
TRACE w.c.HttpSessionSecurityContextRepository : Created SecurityContextImpl [Null authentication]
DEBUG w.c.HttpSessionSecurityContextRepository : Created HttpSession as SecurityContext is non-default
...
DEBUG o.s.security.web.FilterChainProxy : Securing POST /api/product/productname01
TRACE o.s.security.web.FilterChainProxy : Invoking WebAsyncManagerIntegrationFilter (1/16)
...
TRACE o.s.security.web.FilterChainProxy : Invoking CsrfFilter (5/16)
DEBUG o.s.security.web.csrf.CsrfFilter : Invalid CSRF token found for http://localhost/api/product/productname01
DEBUG o.s.s.w.access.AccessDeniedHandlerImpl : Responding with 403 status code
Versions:
Spring Framework Bom version 5.3.16
Spring Boot 2.6.4
Spring 5.3.16
Spring Security 5.6.2
Spring security logging for webflux reactive apps is now available starting with version 5.4.0-M2 (as mentionned by #bzhu in comment How do I enable logging for Spring Security?)
Until this gets into a GA release, here is how to get this milestone release in gradle
repositories {
mavenCentral()
if (!version.endsWith('RELEASE')) {
maven { url "https://repo.spring.io/milestone" }
}
}
// Force earlier milestone release to get securing logging preview
// https://docs.spring.io/spring-security/site/docs/current/reference/html5/#getting-gradle-boot
// https://github.com/spring-projects/spring-security/pull/8504
// https://github.com/spring-projects/spring-security/releases/tag/5.4.0-M2
ext['spring-security.version']='5.4.0-M2'
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
You have two options:
1. Set the logging level of Spring Security to debug or trace:
application.yml:
logging:
level:
org:
springframework:
security: debug # or trace
application.properties:
logging.level.org.springframework.security=debug
2. Enable the Spring Security debug mode
#Configuration
#EnableWebSecurity
public class SecurityConfig {
#Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return web -> web.debug(true);
}
}
or like this:
#Configuration
#EnableWebSecurity(debug = true)
public class SecurityConfig {
}

Resources