17 Eylül 2021 Cuma

SpringSecurity Keycloak

Giriş
Açıklaması şöyle
Keycloak is an open-source identity and access management solution which makes it easy to secure modern applications and services with little to no code.
Keycloak Deployment
Açıklaması şöyle
There are many ways to deploy Keycloak.
1. Standalone Deployment with Keycloak Distribution Files
2. Standalone Deployment with Docker
3. High Availability Deployment in Kubernetes
Kurulumu yaptıktan sonra dizinlerin açıklaması şöyle
bin: This contains various scripts to either boot the server or performs some other management action on the server.
domain: This contains configuration files and working directory when running Keycloak in domain mode.
modules: These are all the Java libraries used by the server.
standalone: This contains configuration files and working directory when running Keycloak in standalone mode.
Çalıştırmak
Çalıştırmak için bin\standalone.bat kullanılır. 
Daha sonra http://localhost:8080 adresinden giriş yaparız. 

Örnek  - dev  olarak çalıştırmak
Şöyle yaparız
{KEYCLOAK_HOME}\bin\kc.sh start-dev

Admin Kullanıcısı
Önce bir admin kullanıcısı yaratmak gerekir. Admin kullanıcısı master realm altındadır.

Realm
Daha sonra yeni bir realm yaratırız. Açıklaması şöyle
A Realm manages a set of users, credentials, roles, and groups. A user belongs to and logs into a realm. Realms are isolated from one another and can only manage and authenticate the users that they control.
Client
Daha sonra yeni realm altında bir client yaratırız. Açıklaması şöyle
Clients are entities that can request Keycloak to authenticate a user. Most often, clients are applications and services that want to use Keycloak to secure themselves and provide a single sign-on solution. Clients can also be entities that just want to request identity information or an access token so that they can securely invoke other services on the network that are secured by Keycloak.
Role
Daha sonra realm altında role yaratırız. Açıklaması şöyle
Applications often assign access and permissions to specific roles rather than individual users as dealing with users can be too fine grained and hard to manage.
Daha sonra realm altında user yaratırız

kcadm komutu
Yukarıdaki adımlar komut satırından yapmak kcadm komutu ile mümkün. Şöyle yaparız
# login
./kcadm.sh config credentials 
  --server http://localhost:8080 
  --realm master 
  --user admin --password admin

# create realm
./kcadm.sh create realms 
  -s realm=spring-boot-keycloak 
  -s enabled=true 
  -o 
  -s defaultSignatureAlgorithm=RS512

# create the client that we are going to use
./kcadm.sh create clients 
  -r spring-boot-keycloak 
  -f {FILE_PATH}/client-id.json 
  -s clientId=spring-boot-keycloak-country-api-client 
  -s enabled=true

# create the client secret
# Get clientId
./kcadm.sh get clients -r spring-boot-keycloak --fields id,clientId

./kcadm.sh create clients/CLIENT_ID_FROM_PREVIOUS_STEP/client-secret 
  -r spring-boot-keycloak
Sonra rolleri yaratırız. Şöyle yaparız
# create roles
./kcadm.sh create roles -r spring-boot-keycloak -s name=manager
./kcadm.sh create roles -r spring-boot-keycloak -s name=user

# create users
./kcadm.sh create users -r spring-boot-keycloak 
  -s username=john.smith -s enabled=true

# Set password
./kcadm.sh update users/{USER_ID_FROM_PREVIOUS_COMMAND}/reset-password 
  -r spring-boot-keycloak -s type=password -s value=password -s temporary=false -n

./kcadm.sh create users -r spring-boot-keycloak -s username=jane.doe -s enabled=true

# Set password
./kcadm.sh update users/{USER_ID_FROM_PREVIOUS_COMMAND}/reset-password 
  -r spring-boot-keycloak -s type=password -s value=password -s temporary=false -n
Kullanıcılara rolleri atarız. Şöyle yaparız
./kcadm.sh add-roles --uusername john.smith --rolename manager -r spring-boot-keycloak
./kcadm.sh add-roles --uusername jane.doe --rolename user -r spring-boot-keycloak

Access Token
Örnek
http://keycloak.demo.com/auth/realms/Keycloak-Demo/protocol/openid-connect/token
adresine x-www-form-urlencoded olarak  POST istek göndeririz. Alanları doldurmak için şöyle yaparız
grant_type : password
client_id : ...
client_secret : ...
username : ...
password : ...

Maven
Şu satırı dahil ederiz
<dependency>
  <groupId>org.keycloak</groupId>
  <artifactId>keycloak-spring-boot-starter</artifactId>
  <version>10.0.1</version>
</dependency>
KeycloakWebSecurityConfigurerAdapter  Sınıfı
Açıklaması şöyle
Keycloak provides a KeycloakWebSecurityConfigurerAdapter as a convenient base class for creating a WebSecurityConfigurer instance. The implementation allows customization by overriding methods. While its use is not required, it greatly simplifies your security context configuration.

Örnek
Sınıfın iskeleti için şöyle yaparız
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
import org.keycloak.adapters.springsecurity.KeycloakSecurityComponents;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
class KeycloakSecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
  ...
}
configureGlobal metodu
Açıklaması şöyle
Registers the KeycloakAuthenticationProvider with the authentication manager.
Şöyle yaparız
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
  KeycloakAuthenticationProvider keycloakAuthenticationProvider =
keycloakAuthenticationProvider();
  keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
  auth.authenticationProvider(keycloakAuthenticationProvider);
}
sessionAuthenticationStrategy metodu
Açıklaması şöyle
Defines the session authentication strategy.
Şöyle yaparız
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
  return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
KeycloakConfigResolver Sınıfı
Açıklaması şöyle
By Default, the Spring Security Adapter looks for a keycloak.json configuration file. You can make sure it looks at the configuration provided by the Spring Boot Adapter by adding this bean
Şöyle yaparız
@Bean
public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
  return new KeycloakSpringBootConfigResolver();
}
configure metodu
Hangi adrese hangi rolün erişeceğini belirtiriz.

Örnek
Şöyle yaparız
@Value("${custom.keycloak.role}")
String keyCloakRole;

@Override
protected void configure(HttpSecurity http) throws Exception {
  super.configure(http);
  http.authorizeRequests()
    .anyRequest()
    .hasRole(keyCloakRole)
    .and()
      .exceptionHandling()
      .accessDeniedPage("/?denied")
    .and()
      .cors()
    .and()
      .csrf()
       .disable();
}
ayarlar işe şöyledir
custom.keycloak.role: test-user
keycloak:
    enable-basic-auth: true
    auth-server-url: http://localhost:8083/auth
    realm: master
    resource: test-clinet
    credentials:
        secret: 0e00874a-d6c3-426c-9704-43b88ecd448a
    ssl-required: external
    verify-token-audience: false
    use-resource-role-mappings: true
    principal-attribute: preferred_username
Örnek
Açıklaması şöyle
Rather than using @RolesAllowed annotation, the same configuration can be made in KeycloakSecurityConfig class as below.
Şöyle yaparız
@Override
protected void configure(HttpSecurity http) throws Exception {
  super.configure(http);
  http.authorizeRequests()
    .antMatchers("/test/anonymous").permitAll()
    .antMatchers("/test/user").hasAnyRole("user")
    .antMatchers("/test/admin").hasAnyRole("admin")
    .antMatchers("/test/all-user").hasAnyRole("user","admin")
    .anyRequest()
    .permitAll();
  http.csrf().disable();
}
Ayarlar
Örnek
Şöyle yaparız
server.port                         = 8000alo

keycloak.realm                      = Demo-Realm
keycloak.auth-server-url            = http://localhost:8080/auth
keycloak.ssl-required               = external
keycloak.resource                   = springboot-microservice
keycloak.credentials.secret         = XXXXXXXXXXXXXXXXXXXXXXXXX
keycloak.use-resource-role-mappings = true
keycloak.bearer-only                = true



Hiç yorum yok:

Yorum Gönder