1 Nisan 2019 Pazartesi

SpringSecurity AuthenticationProvider Arayüzü

Giriş
Şu satırı dahil ederiz
import org.springframework.security.authentication.AuthencticationProvider;
Açıklaması şöyle.
Spring Security provides a variety of options for performing authentication – all following a simple contract – an Authentication request is processed by an AuthenticationProvider and a fully authenticated object with full credentials is returned.
Açıklaması şöyle
It processes an Authentication request. In its “authenticate method, it returns a fully populated Authentication object including granted authorities if authentication is successful.

It has an extra method called “supports” that returns a boolean to allow the caller to query whether it supports a given Authentication type or not.
Bu arayüzün amacı kullanıcıyı doğrulamak.

Custom Authentication
CustomAuthenticationProvider Örneği yazısına bakınız.

Spring Tarafından Sağlanan Sınıflar
Bu arayüzü gerçekleştiren bazı sınıflar şöyle. 

DaoAuthenticationProvider : Kullanıcıyı kendisine atanan UserDetailsService ile yükler ve doğrular
ActiveDirectoryLdapAuthenticationProvider : Kullanıcıyı ActiveDirectory'den yükler ve doğrular
LdapAuthenticationProvider : Kullanıcıyı LDAP'ten yükler ve doğrular
- OpenIDAuthenticationProvider : Açıklama yaz

Neticede her sınıfın kullanıcı bilgisini bir kaynaktan yüklemesi gerekiyor

ProviderManager Nedir?
AuthenticationProvider arayüzünü gerçekleştiren sınıf ProviderManager

Kullanım
Bu arayüz AuthenticationManager nesnesine takılır.

AuthenticationProvider vs UserDetailsService Farkı Nedir?
Açıklaması şöyle. Birisi kullanıcıyı doğrular. Diğeri ise kullanıcı bilgilerini yükler.
AuthenticationProvider vs UserDetailsService
UserDetailsService is not an alternative to AuthenticationProvider but it is used for a different purpose i.e. to load user details. Typically, an AuthenticationProvider implementation can use UserDetailsService instance to retrieve user details during its authentication process. For example, DaoAuthenticationProvider, in case of JDBC-authentication, uses JdbcUserDetailsManager as an implementation of UserDetailsService. In case of in-memory authentication, DaoAuthenticationProvider uses InMemoryUserDetailsManager implementation.
UserDetailsService sadece kullanıcı ismiyle kullanıcıyı yükler. Açıklaması şöyle.
This User Details Service only has access to the username in order to retrieve the full user entity. This is enough for most scenarios.
authenticate metodu
İmzası şöyle.
@Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException
Adım 1: Özeti buradan çıkarttım. authenticate() metodu kullanıcı bilgilerine erişmek için Authentication nesnesini kullanır.

- Bu nesnenin getName() metodu ile kullanıcı adı alınır
- Bu nesnenin getCredentials() metodu ile kullanıcı şifresi alınır

Authentication nesnesi örneğin UsernamePasswordAuthenticationToken sınıfı olabilir. Açıklaması şöyle.
The input Authentication object contains the username and password credentials supplied by the user.

The authenticate method returns a fully populated Authentication object if the authentication is successful. If authentication fails, it throws an exception of type AuthenticationException:
Adım 2: Bu nesne bir servis kullanılarak doğrulanır. Eğer işlem başarısız olursa

 - Eğer kullanıcı bulunamazsa null dönülür
 - Eğer kullanıcı bulunur ancak doğrulanamazsa exception (örneğin BadCredentialsException) fırlatılır.  Aradaki farkın açıklaması şöyle
May return null if the AuthenticationProvider is unable to support authentication of the passed Authentication object. In such a case, the next AuthenticationProvider that supports the presented Authentication class will be tried. Throws: AuthenticationException - if authentication fails.
- Eğer kullanıcı doğrulanırsa Authentication arayüzünden kalıtan bir nesne döndürülür. Bu yeni nesneye GrantedAuthority yani roller atanmıştır. Rollere getAuthorities() metodu ile erişilebilir. Yeni nesne SecurityContextHolder nesnesinde mutlaka saklanmalıdır. Açıklaması şöyle.
When the user credentials are verified, we mark the user authenticated and register it in SecurityContext
Örnek
Şöyle yaparız
public class SSOAuthenticationProvider implements AuthenticationProvider {

  public Authentication authenticate(Authentication authentication) {

    // verified the authentication token
    authentication.setAuthenticated(true);

    // make the database call, get roles for the user
    authentication.setAuthorities(<authorities - discussed below>);
    SecurityContextHolder.getContext().setAuthentication(authentication);

    return authentication;
  }
}
Örnek
Şöyle yaparız
@Service(value = "customAuth")
public class CustomAuthenticationProvider implements AuthenticationProvider {

  @Autowired
  public Storages storage;

  @Override
  @Transactional
  public Authentication authenticate(Authentication authentication)
  throws AuthenticationException {
    String login = authentication.getName();
    String password = authentication.getCredentials().toString();
    User user = storage.uSM.findByEmailAndPassword(login, password);
    if (user == null) {
      return null;
    } else {
      // Here use the user object to only check if the user exists in the database
      // if not null use his login ( principal ) and password
      return new UsernamePasswordAuthenticationToken(login, password);
    }
  }

  @Override
  public boolean supports(Class<?> authentication) {
    return authentication.equals(UsernamePasswordAuthenticationToken.class);
  }
}

Hiç yorum yok:

Yorum Gönder