28 Nisan 2019 Pazar

SpringCloud Netflix Eureka Sunucu u@EnableEurekaServer Anotasyonu - Eureka Sunucusunu Başlatır

Giriş
Şu satırı dahil ederiz
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
Euraka'ya alternatif olarak Spring Cloud Consul kullanılabilir. Şeklen şöyle

Açıklaması şöyle.
If your infrastructure is not based on any popular Cloud environment but you still want to take advantage of the dynamic discovery rather than static IP configuration, you can set up your service registry. One of the more popular choices, especially in the JVM-based microservice world, is Eureka (initially developed by Netflix and now part of Spring Cloud). Eureka follows the client-server model, and you usually set up a server (or a cluster of servers for high availability) and use clients to register and locate services.
Açıklaması şöyle
- REST service which registers itself at the registry (Eureka Client) and
- Web application, which is consuming the REST service as a registry-aware client (Spring Cloud Netflix Feign Client).
Maven
Eureka Server tarafında şu satırı dahil ederiz
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
Örnek
Şöyle yaparız
@SpringBootApplication
@EnableEurekaServer
public class SuperdevEurekaServerApplication {
  public static void main(String[] args) {
    SpringApplication.run(SuperdevEurekaServerApplication.class, args);
  }
}
application.properties
Ayarlar eureka.client ve eureka.server başlıkları altında belirtilir

1. eureka server Ayarlar
registerWithEureka  Alanı
Eureka Sunucusunun Eurak Server'da listelenmesini isteyip istemediğimizi belirtiriz. 

Örnek 
Eureka Server'a kayıt olmak istemiyorsak şöyle yaparız
eureka.client.registerWithEureka = false
eureka.client.fetchRegistry = false
server.port = 8761

spring.application.name=superdev-eureka-server
Örnek
Şöyle yaparız
spring.application.name=eureka-server server.port=8761 eureka.client.register-with-eureka=false eureka.client.fetch-registry=false

2. eureka client Ayarlar
Örnek
Şöyle yaparız
spring.application.name=my-client eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
Örnek
Şöyle yaparız
server: port: 8761 # default port where discovery client is registered eureka: client: registerWithEureka: false fetchRegistry: false server: waitTimeInMsWhenSyncEmpty: 0
fetch-registry Alanı
Örnek 
Şöyle yaparız
server.port=8761

eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

logging.level.com.netflix.eureka=OFF
logging.level.com.netflix.discovery=OFF
Dashboard
Eureka Server Dashboard'u görmek için şöyle yaparız
http://localhost:8761/
Şeklen şöyle



SpringSecurity OAuth2 @EnableResourceServer Anotasyonu

Giriş
OAuth ile roller şöyle
There are four different roles within OAuth2 we need to consider:

- Resource Owner — an entity that is able to grant access to its protected resources
- Authorization Server — grants access tokens to Clients after successfully authenticating Resource Owners and obtaining their authorization
- Resource Server — a component that requires an access token to allow, or at least consider, access to its resources
- Client — an entity that is capable of obtaining access tokens from authorization servers
Bu roller için anotasyonlar şöyle.
@EnableAuthorizationServer (2)
@EnableResourceServer (3)
@EnableOAuth2Sso (4)
@EnableOAuth2Client (4)
Ne İçin Kullanırız
Açıklaması şöyle. Uygulamamıza erişmeye çalışan bir istemcinin (client) OAuth Access Token göndererek kendisini doğrulatmış olması gerekir. Yani 3 numaralı rolü yerine getirebiliriz.
The @EnableResourceServer annotation enables our application to behave as a Resource Server by configuring an OAuth2AuthenticationProcessingFilter and other equally important components.
ResourceServerConfigurerAdapter yazısına bakabilirsiniz.

Eğer Access Token Yoksa
Açıklaması şöyle. OAuth2 Access Token yoksa hata kodu döner.
@EnableResourceServer is a convenient annotation that enables request authentication through OAuth 2.0 tokens.
Eğer pom dosyamıza "spring-boot-starter-oauth2-resource-server" bağımlılığını eklersek bu anotasyonu kullanmaya gerek yok deniliyor ancak emin değilim.

SpringSecurity OAuth2 JwtTokenStore Sınıfı

Giriş
Bu sınıf AuthorizationServerConfigurerAdapter (authorization) veya WebSecurityConfigurerAdapter (authentication) tarafından kullanılabilir. Açıklaması şöyle.
JwtTokenStore encodes token-related data into the token itself. It does not make tokens persistent and requires JwtAccessTokenConverter as a translator between a JWT-encoded token and OAuth authentication information. ("Spring Essentials" by Shameer Kunjumohamed, Hamidreza Sattari).
JSON Web Tokens - JWT yazısına bakabilirsiniz.

constructor - JwtAccessTokenConverter
Authorization Server tarafından private key ile imzalanan token Resource Server tarafından public key kullanılarak doğrulanır.

Örnek - JwtAccessTokenConverter.setVerifierKey
Şöyle yaparız
@Value("${spring.application.name}")
public String applicationResourceID;

@Value(" ${key.config.oauth2.publicKey}")
private String publicKey;

@Value("jwt.aes.encrypt.keyValue")
String jwtAesEncryptionKey;


@Bean
public TokenStore tokenStore() {
  return new JwtTokenStore(jwtAccessTokenConverter());
}

@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
 MyJwtAccessTokenConverter converter = new MyJwtAccessTokenConverter(jwtAesEncryptionKey);
 converter.setVerifierKey(publicKey);
 return converter;
}

Örnek - JwtAccessTokenConverter.setSigningKey
Şöyle yaparız.
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

  private String privateKey;

  private int accessTokenValiditySeconds = 900; // 15 minutes;

  
  public AuthorizationServerConfig() {
    this.privateKey = "private";
  }

  @Bean
  public TokenStore tokenStore() {
    return new JwtTokenStore(accessTokenConverter());
  }

  @Bean
  public JwtAccessTokenConverter accessTokenConverter() {
    JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
    converter.setSigningKey(this.privateKey);
    return converter;
  }
  ...
}
Örnek - JwtAccessTokenConverter.setSigningKey
Şöyle yaparız.
@EnableResourceServer
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Bean
  public JwtAccessTokenConverter accessTokenConverter() {
    JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
    converter.setSigningKey("private");
    return converter;
  }

  @Bean
  public TokenStore tokenStore() {
    return new JwtTokenStore(this.accessTokenConverter());
  }
  ...
}

23 Nisan 2019 Salı

SpringSecurity WebSecurityConfigurerAdapter Sınıfı - Deprecate Edildi

Giriş
Şu satırı dahil ederiz.
import org.springframework.security.config.annotation.web.configuration
.WebSecurityConfigurerAdapter;
Multiple Entry Points - Farklı Ream'ler
Çoklu Realm yazısına taşıdım

Multiple Authentication Providers
Bir realm'e birden fazla AuthenticationProvider takılabilir. Bir örnek burada 

Örnek
Elimizde şöyle bir kod olsun.
@Autowired
private CustomAuthenticationProvider1 customProvider1;

@Autowired
private CustomAuthenticationProvider2 customProvider2;

@Autowired
private SAMLAuthenticationProvider samlProvider;
Şöyle yaparız
authenticationManagerBuilder.authenticationProvider(customProvider1);
authenticationManagerBuilder.authenticationProvider(customProvider2);
authenticationManagerBuilder.authenticationProvider(samlProvider);
Multiple Form Login
Eğer farklı kullanıcılar için farklı form login adresleri vermek istiyorsak yine bu sınıftan birden fazla yaratmak gerekebilir. Bir örnek burada.

Tanımlama
Bu sınıfı @Configuration anotasyonu ile birlikte kullanmak gerekir.
Örnek
Şöyle yaparız.
@Configuration
@EnableWebSecurity
public class SecurityAdapter extends WebSecurityConfigurerAdapter {
  ...
}
Bu tanımlama sonunda bir tane SecurityFilterChain arayüzünü gerçekleştiren nesne yaratılır. Bu nesne de FilterChainProxy sınıfının yaratılmasında kullanılır. 

Spring Hangi Filtreyi Kullanacağına Nasıl Karar Verir
Açıklaması şöyle
Authentication Flow
...
When an incoming request reaches our system, Spring Security starts by choosing the right security filter to process that request (Is the request a POST containing username and password elements? => UsernamePasswordAuthenticationFilter is chosen. Is the request having a header “Authorization : Basic base64encoded(username:password)”? => BasicAuthenticationFilter is chosen… and so the chaining goes on). When a filter had successfully retrieved Authentication information from the request, the AuthenticationManager is invoked to authenticate the request. via its implementation, the AuthenticationManager goes through each of the provided AuthenticationProvider(s) and try to authenticate the user based on the passed Authentication Object. when the Authentication is successful, and a matching user if found, an Authentication Object containing the user Authorities (which will be used to manage the user access to the system’s resources) is returned and set into the SecurityContext.
Şeklen şöyle. Burada önemli olan doğru filtreyi seçebilmek.


authenticationManagerBean metodu
Şöyle yaparız.
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
  return super.authenticationManagerBean();
}
configure metodu - AuthenticationManagerBuilder 
İmzası şöyle
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception;
AuthenticationManagerBuilder nesnesi ayarları yapılır. Yani kendi custom AuthenticationProvider nesnemizi takabiliriz. Custom AuthenticationProvider'lardan birisi

configure metodu - HttpSecurity 

İmzası şöyleHttpSecurity nesnesi ayarları yapılır.
@Override
protected void configure(HttpSecurity http) throws Exception;
Açıklaması şöyle
If we do not override the configure() method, a default filter chain is created as follows

protected void configure(HttpSecurity http) throws Exception {
  this.logger.debug("Using default configure(HttpSecurity). "
      + "If subclassed this will potentially override subclass configure(HttpSecurity).");
  http.authorizeRequests((requests) -> requests.anyRequest().authenticated());
  http.formLogin();
  http.httpBasic();
}
Neticede şu filtreler yaratılır
Each of these methods on the http object would lead to the addition of respective filters in the SecurityFilterChain. Inspect the methods, to know the individual filters being applied.

Here is a list of default filters that are applied:
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
CsrfFilter
LogoutFilter
UsernamePasswordAuthenticationFilter
DefaultLoginPageGeneratingFilter
DefaultLogoutPageGeneratingFilter
BasicAuthenticationFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
FilterSecurityInterceptor ile "authorization" yapılır

configure metodu - WebSecurity 
Açıklaması şöyle. Yani WebSecurity ile ignoring() yapılan adresler SpringSecurity filtrelerine uğramazlar.
General use of WebSecurity ignoring() method omits Spring Security and none of Spring Security’s features will be available. WebSecurity is based above HttpSecurity.
Aslında hem WebSecurity hem de HttpSecurity sınıflarının builder oldukları paket isimlerinden görülebilir.
org.springframework.security.config.annotation.web.builders.WebSecurity
org.springframework.security.config.annotation.web.builders.HttpSecurity
Örnek
Şöyle yaparız
@Override
public void configure(WebSecurity web) throws Exception {
  web.ignoring().antMatchers("/resources/**","/static/**");
}
userDetailsServiceBean metodu
Şöyle yaparız.
@Override
@Bean
public UserDetailsService userDetailsServiceBean() throws Exception {
  return super.userDetailsServiceBean();
}